This patch updates JDE and the usual suspects to their required levels
for 2.2.7.
The patch doesn't contain the necessary binary files so it may be
easier for me to check it in myself.
Index: xemacs-packages/jde/Makefile
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/Makefile,v
retrieving revision 1.42
diff -u -r1.42 Makefile
--- xemacs-packages/jde/Makefile 2001/07/02 09:33:16 1.42
+++ xemacs-packages/jde/Makefile 2001/08/15 05:27:17
@@ -17,14 +17,14 @@
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
-VERSION = 1.27
-AUTHOR_VERSION = 2.2.7
+VERSION = 1.28
+AUTHOR_VERSION = 2.2.7.1
MAINTAINER = Paul Kinnucan <paulk(a)mathworks.com>
PACKAGE = jde
PKG_TYPE = regular
REQUIRES = jde cc-mode semantic debug speedbar \
edit-utils eterm mail-lib xemacs-base \
- eieio elib
+ eieio elib sh-script
CATEGORY = standard
ELCS = lisp/jde-bug.elc \
@@ -52,7 +52,8 @@
lisp/jde-wiz.elc \
lisp/jde.elc \
lisp/beanshell.elc \
- lisp/setnu.elc
+ lisp/setnu.elc \
+ lisp/tree-widget.elc
EXTRA_SOURCES =
@@ -128,14 +129,14 @@
DATA_31_FILES = $(wildcard doc/src/jde-ug/*.xml) \
$(wildcard doc/src/jde-ug/*.html)
DATA_31_DEST = jde/doc/src/jde-ug/
-DATA_31_FILES = $(wildcard doc/src/styles/html/*.xsl)
-DATA_31_DEST = jde/doc/src/styles/html
-DATA_32_FILES = $(wildcard doc/tli_rbl/au/*.au)
-DATA_32_DEST = jde/doc/tli_rbl/au
-DATA_33_FILES = $(wildcard doc/tli_rbl/img/*.gif)
-DATA_33_DEST = jde/doc/tli_rbl/img
-DATA_34_FILES = $(wildcard doc/tli_rbl/txt/*.txt)
-DATA_34_DEST = jde/doc/tli_rbl/txt
+DATA_32_FILES = $(wildcard doc/src/styles/html/*.xsl)
+DATA_32_DEST = jde/doc/src/styles/html
+DATA_33_FILES = $(wildcard doc/tli_rbl/au/*.au)
+DATA_33_DEST = jde/doc/tli_rbl/au
+DATA_34_FILES = $(wildcard doc/tli_rbl/img/*.gif)
+DATA_34_DEST = jde/doc/tli_rbl/img
+DATA_35_FILES = $(wildcard doc/tli_rbl/txt/*.txt)
+DATA_35_DEST = jde/doc/tli_rbl/txt
AUTOLOAD_PATH = lisp
Index: xemacs-packages/jde/doc/html/jde-ug/jde-ug-content.html
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/doc/html/jde-ug/jde-ug-content.html,v
retrieving revision 1.1
diff -u -r1.1 jde-ug-content.html
--- xemacs-packages/jde/doc/html/jde-ug/jde-ug-content.html 2001/02/15 06:45:44 1.1
+++ xemacs-packages/jde/doc/html/jde-ug/jde-ug-content.html 2001/08/15 05:27:20
@@ -1876,11 +1876,31 @@
interaction. To run an application, enter
</p><pre class="programlisting">
M-x jde-run
- </pre><p>or select Java->Run App on the
+ </pre><p>or select Java->Run App from the
Emacs menubar or type C-c C-v C-r.
</p>
<div id="ab2b5b4" class="section">
- <h2 class="title" style="clear: all"><a
name="ab2b5b4"><b><a
name="SpecifyingStartupDirectory"></a>Specifying a Startup
Directory</b></a></h2>
+ <h2 class="title" style="clear: all"><a
name="ab2b5b4"><b><a
name="SpecifyingMainClass"></a>Specifying the Application's Main
Class</b></a></h2>
+ <p>The term <i>main class</i> refers to the class
+ that contains the application's main method. The JDE's Run App
command
+ assumes by default that the class in the current buffer is the
+ application's main class. This can be inconvenient if you have
an
+ application that has multiple classes. You may want to be able to
+ run the application from any buffer containing one of the
application's
+ classes. To do this, set the variable
+ <tt>jde-run-application-class</tt> to
+ the <i>fully qualified name</i> of the application's
main class.
+ </p>
+ <p>You can temporarily override the setting of
+ <tt>jde-run-application-class</tt> by typing
<tt>C-u</tt>
+ before executing the <b>jde-run</b> command, for
example,
+ by typing <tt>C-u C-c C-r</tt>. This causes the JDE to
prompt you to
+ enter the <i>fully qualified name</i> of the
application's main
+ class.
+ </p>
+ </div>
+ <div id="ab2b5b5" class="section">
+ <h2 class="title" style="clear: all"><a
name="ab2b5b5"><b><a
name="SpecifyingStartupDirectory"></a>Specifying a Startup
Directory</b></a></h2>
<p>The JDE can start an application from any directory that you
specify. By default, the JDE starts an application from the
default directory of the current source buffer. The default
@@ -1927,8 +1947,8 @@
</ol>
</div>
</div>
- <div id="ab2b5b5" class="section">
- <h2 class="title" style="clear: all"><a
name="ab2b5b5"><b><a name="RunVMArgs"></a>
Setting VM Command-Line Arguments</b></a></h2>
+ <div id="ab2b5b6" class="section">
+ <h2 class="title" style="clear: all"><a
name="ab2b5b6"><b><a name="RunVMArgs"></a>
Setting VM Command-Line Arguments</b></a></h2>
<p>If you set the customization variable
<tt>jde-run-read-vm-args</tt> to a
non-<tt>nil</tt> value, the JDE compile command prompts
you
@@ -1939,8 +1959,8 @@
the up or down arrows on your keyboard.
</p>
</div>
- <div id="ab2b5b6" class="section">
- <h2 class="title" style="clear: all"><a
name="ab2b5b6"><b><a name="RunAppArgs"></a>
Setting Command-Line Application Arguments</b></a></h2>
+ <div id="ab2b5b7" class="section">
+ <h2 class="title" style="clear: all"><a
name="ab2b5b7"><b><a name="RunAppArgs"></a>
Setting Command-Line Application Arguments</b></a></h2>
<p>If you set the customization variable
<tt>jde-run-read-app-args</tt> to a
non-<tt>nil</tt> value, the JDE compile command prompts
you
@@ -1953,8 +1973,29 @@
keyboard.
</p>
</div>
- <div id="ab2b5b7" class="section">
- <h2 class="title" style="clear: all"><a
name="ab2b5b7"><b><a name="RunOptions"></a>Run
Customization Variables </b></a></h2>
+ <div id="ab2b5b8" class="section">
+ <h2 class="title" style="clear: all"><a
name="ab2b5b8"><b><a
name="NavigatingExceptionTraces"></a>Navigating Exception
Traces</b></a></h2>
+ <p>If an exception occurs while your program is running, the Java vm
+ outputs an exception trace. This trace appears in the run buffer for
the
+ application.
+ </p>
+ <p>
+
+ <div class="screenshot">
+ <div class="mediaobject"><img
src="images/excepttrace.gif"></div>
+ </div>
+
+ </p>
+ </div>
+ <p>To view the source line corresponding to a point in
+ the exception stack trace, right-click the corresponding stack
+ trace line in the run buffer. You can move up and down
+ the stack trace by typing the key combinations
+ <tt>C-c C-v C-[</tt> or
+ <tt>C-c C-v C-]</tt>.
+ </p>
+ <div id="ab2b5c10" class="section">
+ <h2 class="title" style="clear: all"><a
name="ab2b5c10"><b><a name="RunOptions"></a>Run
Customization Variables </b></a></h2>
<p>The JDE allows you to specify run-time options by setting run
variables.You can use the Emacs customization feature to set
run-time
variables interactively. To use the customization feature, select
@@ -1971,7 +2012,7 @@
</p>
<div class="table">
- <p><a name="ab2b5b7b3"></a><b>Table
1. </b></p>
+ <p><a name="ab2b5c10b3"></a><b>Table
1. </b></p>
<table border="1">
<colgroup>
<col>
@@ -2345,21 +2386,28 @@
<h2 class="title" style="clear: all"><a
name="ab2b8b4"><b><a
name="SettingClasspathVar"></a>Setting a Classpath
Variable</b></a></h2>
<p>As with other JDE customization variables, you must use
Emacs'
<b>customize-variable</b> command to
- set the JDE's classpath variables. When setting a classpath
variable,
+ set the JDE's classpath variables. You can use relative paths,
cygwin paths,
+ and paths with tilde notation and environment variables as values of
+ JDE classpath variables. See <a
href="#SpecifyingPaths">Specifying
+ Paths</a> for more information.
+
+ </p>
+ <p>
+ When setting a classpath variable,
you must enter each path as a separate entry in the customization
buffer. Do not enter the paths as semicolon or colon-separated lists
of paths. The following examples show the right and wrong way to
specify a classpath.
</p>
<div class="example">
- <p><a name="ab2b8b4b2"></a><b>Example
1. Wrong Way to Specify a Classpath</b></p><pre
class="programlisting">
+ <p><a name="ab2b8b4b3"></a><b>Example
1. Wrong Way to Specify a Classpath</b></p><pre
class="programlisting">
jde-global-classpath: [Hide]
[INS] [DEL] Path: c:/jde-dev/jmath/classes;c:/jde-dev/jmath/src
[INS]
[State]: this option has been set and saved.
</pre></div>
<div class="example">
- <p><a name="ab2b8b4b3"></a><b>Example
2. Right Way to Specify a Classpath</b></p><pre
class="programlisting">
+ <p><a name="ab2b8b4b4"></a><b>Example
2. Right Way to Specify a Classpath</b></p><pre
class="programlisting">
jde-global-classpath: [Hide]
[INS] [DEL] Path: c:/jde-dev/jmath/classes
[INS] [DEL] Path: c:/jde-dev/jmath/src
@@ -2368,68 +2416,67 @@
</pre></div>
</div>
<div id="ab2b8b5" class="section">
- <h2 class="title" style="clear: all"><a
name="ab2b8b5"><b><a
name="EnvVarsInClasspaths"></a>Environment Variables in
Classpaths</b></a></h2>
- <p>You can use environment variables in classpaths. For
example,</p>
- <p>
- <pre class="programlisting">
- $JDE_HOME/java/classes
- </pre>
+ <h2 class="title" style="clear: all"><a
name="ab2b8b5"><b><a
name="ClassLibraries"></a>Including Class
Libraries</b></a></h2>
+ <p>
+ If you store your class libraries as jar or zip files in
+ separate directory, you need specify only the path of the directory
+ in a JDE classpath variable. Whenever the JDE encounters a library
directory
+ in a classpath variable, it expands the classpath to include all
+ the jar and zip files in the library directory.
+
+ </p>
+ <p>
+ For example, suppose you organize your project directory as
+ follows:
+
+ </p>
+ <p>
+ <pre class="programlisting">
+ myproj
+ classes
+ lib
+ src
+ </pre>
</p>
- <p>is a valid entry in a classpath. The JDE substitutes the
- actual value of an environment variable wherever the variable
- occurs in the classpath.
+ <p>
+ where the <tt>src</tt> directory contains all of
+ your source files, the <tt>lib</tt> directory all
+ of your jar and zip files, and the
+ <tt>classes</tt> directory all of the classes
+ compiled from the <tt>src</tt> directory. Further,
+ suppose you store your project file
+ (see <a href="#UsingProjectFiles">Using Project
Files</a>)
+ at the root of your project directory. Then, you can specify
+ <tt>jde-global-classpath</tt> simply as follows.
+
</p>
- <div class="note" style="margin-left: 0.5in;
margin-right: 0.5in;">
- <h3 class="title"><a
name="ab2b8b5b4">Note</a></h3>
- <p>You must use the Unix notation for environment variables
- on Windows, e.g., <tt>$JDE_HOME</tt> or
- <tt>${JDE_HOME}</tt>. Emacs does not accept DOS
- notation, e.g., <tt>%JDE_HOME%</tt>.
+ <p>
+ <pre class="programlisting">
+ jde-global-classpath: [Hide]
+ [INS] [DEL] Path: ./classes
+ [INS] [DEL] Path: ./src
+ [INS] [DEL] Path: ./lib
+ [INS]
+ [State]: this option has been set and saved.
+ </pre>
</p>
- </div>
- </div>
- <div id="ab2b8b6" class="section">
- <h2 class="title" style="clear: all"><a
name="ab2b8b6"><b><a name="CygwinPaths"></a>Using
Cygwin Paths</b></a></h2>
- <p>You can use cygwin style paths in JDE classpath variables
- on Windows. The JDE converts such paths to DOS paths before
- using them, using a conversion function that you can specify.
- </p>
- <p>The jde-cgywin-path-converter variable allows you
- to choose the path conversion function used by the JDE.
- </p>
- <div class="itemizedlist">
- <ul>
- <li><a
name="ab2b8b6b3a"></a><p><tt>
-
jde-cygwin-path-converter-internal</tt></p>
- <p>This is the default path conversion function used by
- the JDE. It converts any paths of the form
<tt>//[a-z]/</tt>
- or <tt>//cygdrive/[a-z]/</tt> to the
corresponding DOS form. For
- example it converts
<tt>/c/jde/java/classes</tt> to
- <tt>c:/jde/java/classes</tt>.
-
- </p>
- </li>
- <li><a
name="ab2b8b6b3b1"></a><p><tt>jde-cygwin-path-converter-cygpath</tt></p>
- <p>This function invokes the cygwin
<tt>cygpath</tt> utility to
- perform the path conversion. The advantage is that the
cygwin path utility can
- recognize and convert Unix style paths that represent mount
points in the cygwin
- mount table. For example, suppose that you have mounted
- <tt>d:/javadev</tt> as
<tt>/javadev</tt> in
- the cygwin mount table. Then choosing
- <tt>jde-cygwin-path-converter-cygpath</tt>
- allows you to use paths beginning with
<tt>/javadev</tt> in JDE classpaths. The
- drawback is that the conversion is slow as it requires
running the cygwin utility
- for each Unix-style path to be converted.
- </p>
- </li>
- <li><a name="ab2b8b6b3b2"></a><p>A
custom conversion function that you supply.</p>
- </li>
- </ul>
- </div>
+ <p>
+ If you do not want the JDE to expand library directories, set the
variable
+ <tt>jde-expand-classpath-p</tt> off. The JDE expands
+ directories whose names match the regular expression specified by
+ <tt>jde-lib-directory-name</tt>. The default value of this
variable
+ is <tt>lib</tt>. So by default, the JDE expands names
+ that contain the string <tt>lib</tt>,
+ e.g., <tt>lib</tt>, <tt>mylib</tt>,
+ <tt>utility_lib</tt>, etc. However, you can customize
+ <tt>jde-lib-directory-name</tt> to reflect any library
naming
+ scheme you prefer.
+
+ </p>
</div>
</div>
<div id="ab2b9" class="chapter">
- <h2 class="title"><a name="ab2b9"><a
name="UsingProjectFiles"></a> Using Project
Files</a></h2>
+ <h2 class="title"><a name="ab2b9"><a
name="UsingProjectFiles"></a>Using Project Files</a></h2>
<p>A project file is a Lisp file that the JDE loads and evaluates
whenever you open a Java source file belonging to a specific
project. Project files allow you to save and restore project-specific
@@ -2444,17 +2491,37 @@
two assumptions. First, it assumes that all Java source files
relating to a particular project live in a single directory tree.
Second, it assumes that all project files have the same file name.
- The name assumed by default is prj.el. You can use the JDE
+ The name assumed by default is <tt>prj.el</tt>. You can
use the JDE
configuration variable <tt>jde-project-file-name</tt> to
specify
- another name. When you open a Java source file, the JDE looks for
- a project file in the directory containing the source file. If it
- cannot find a project file in the source file directory, it
- searches up the directory tree until it finds a project file or
- reaches the root of the directory tree. If the JDE finds a
- project file, it loads and evaluates the contents of the file as
- the last step in creating the buffer containing the Java source
- file.
+ another name.
+ </p>
+ <p>
+ When you open a Java source file, the JDE looks for
+ project files in the directory tree containing the source file.
+ If the JDE finds one or more project files, it loads the
+ project files in the following manner.
+
</p>
+ <p>
+ The JDE first sets all the JDE variables to their
+ Emacs startup values (i.e., the default value or the value
+ saved in your <tt>.emacs</tt> file). It then loads
+ all the project files in the directory tree containing the
+ current source buffer, starting with the topmost file.
+
+ </p>
+ <p>
+ What this means is that you can use project files to extend
+ and/or override the settings in your
+ <tt>.emacs</tt> file and in other project files.
+ For example, your <tt>.emacs</tt> file can specify
+ settings that are common to all your projects. You can put
+ settings common to a group of projects at the top of the
+ directory tree containing the projects, settings common to
+ each project at the top of the directory containing each
+ projects, and so on.
+
+ </p>
</div>
<div id="ab2b9b3" class="section">
<h2 class="title" style="clear: all"><a
name="ab2b9b3"><b><a
name="ProjectFileContents"></a> Project File
Contents</b></a></h2>
@@ -2468,12 +2535,12 @@
</p>
</div>
<div id="ab2b9b4" class="section">
- <h2 class="title" style="clear: all"><a
name="ab2b9b4"><b><a
name="CreatingProjectFiles"></a> Creating a Project
File</b></a></h2>
+ <h2 class="title" style="clear: all"><a
name="ab2b9b4"><b><a
name="CreatingProjectFiles"></a>Creating a Project
File</b></a></h2>
<p>The easiest way to create a project file is to use the
<tt>jde-save-project </tt> command
(JDE->Project->Project
File->Save
Project). This command saves the current
- values of all the JDE configuration variables in the project file
for
+ values of all customized JDE configuration variables in the project
file for
the selected Java buffer. (To be precise, the command inserts Lisp
code in the project file that restores the current settings of the
configuration variables; if such code already exists in the file,
it
@@ -2501,9 +2568,22 @@
</li>
<li>
<p>Select JDE->Project->Project
- File->Save Project
- to create a project file in the directory containing the
source
- file.
+ File->Save Project.
+
+ </p>
+ </li>
+ <li>
+ <p>
+ The JDE prompts you to enter the path to a directory in
which to store
+ the project file.
+
+ </p>
+ </li>
+ <li>
+ <p>
+ Enter the directory where you want to store the project
file or
+ press <b>Enter</b> to store the project file
in the current directory.
+
</p>
</li>
</ol>
@@ -2518,6 +2598,91 @@
</p>
</div>
+ <div id="ab2b9b5" class="section">
+ <h2 class="title" style="clear: all"><a
name="ab2b9b5"><b><a
name="CreatingPortableProjects"></a>Creating Portable
Projects</b></a></h2>
+ <p>
+ You can use relative paths and environment variables to
+ construct portable project files. For example, suppose your
+ project directory has the following structure:
+
+ </p>
+ <p>
+ <pre class="programlisting">
+ myprj
+ classes
+ pkg1
+ pkg2
+ src
+ pkg1
+ pkg2
+ prj.el
+ </pre>
+ </p>
+ <p>
+ Further suppose that your project uses beans from a
+ shared library specified by the environment variable
+ <tt>BEANS</tt>. With this setup,
+ you can specify <tt>jde-global-classpath</tt> as
+
+ </p>
+ <p>
+ <pre class="programlisting">
+ ./src
+ ./classes
+ $BEANS/lib/dials.jar
+ </pre>
+ </p>
+ <p>
+ and <tt>jde-compile-option-directory</tt> as
+
+ </p>
+ <p>
+ <pre class="programlisting">
+ ./classes
+ </pre>
+ </p>
+ <p>
+ This causes the JDE to store classes compiled from your src
+ directory in the classes directory. Note that you have not
+ used any absolute paths in creating your project file. This
+ means you can move your project anywhere without having to update
+ the project file.
+
+ </p>
+ </div>
+ <div id="ab2b9b6" class="section">
+ <h2 class="title" style="clear: all"><a
name="ab2b9b6"><b><a
name="DisablingContextSwitching"></a>Disabling Context
Switching</b></a></h2>
+ <p>When you select a buffer that belongs to another
+ project, the JDE loads the project file for that project
+ and may update the class list for the project. This
+ causes a slight delay before you can begin using the
+ new buffer. The delay can be irritating if you need
+ to switch frequently among open projects, for example,
+ when copying or diffing code from different projects.
+ Accordingly, the JDE provides ways for you to disable
+ context-switching either permanently or temporarily.
+
+ </p>
+ <p>To disable context-switching permanently, toggle
+ the customizat variable
+ <tt>jde-project-context-switching-enabled-p</tt>
+ off. Be sure to use customize to do this and save the
+ customization in your <tt>
+ .emacs</tt> or <tt>prj.el</tt>
+ file. Note that you can use the JDE's project file loading
+ command, <b>JDE->Project->Project
File->Load</b>,
+ to switch contexts manually.
+
+ </p>
+ <p>
+ To disable context-switching temporarily during a session,
+ select <b>
+ JDE->Project->Auto Switch</b> or enter
+ <tt>M-x jde-toggle-project-context-switching</tt>. To
reenable
+ context-switching, execute the same command again.
+
+ </p>
+ </div>
</div>
<div id="ab2c10" class="chapter">
<h2 class="title"><a name="ab2c10"><a
name="DisplayingDoc"></a> Displaying Java
Documentation</a></h2>
@@ -2873,8 +3038,9 @@
type C-h
v followed by the JDE group prefix
(<tt>jde-</tt>) or subgroup prefix (e.g.,
- <tt>jde-compile-option-</tt>, see <a
href="#JDECustomizationGroups"> JDE Customization Groups</a>). Emacs
- displays all variables belonging to the JDE group or
subgroup. You
+ <tt>jde-compile-option-</tt>,
+ see <a href="#JDECustomizationGroups">JDE
Customization Groups</a>).
+ Emacs displays all variables belonging to the JDE group
or subgroup. You
can then browse this list, using Emacs search,
completion, and
documentation display command, to find the applicable
variable.
@@ -2900,9 +3066,11 @@
</p>
</li>
<li>
- <p>Save the value for the variable in your
<tt>.emacs</tt> or <tt>.prj</tt> file.
+ <p>Save the value for the variable in your
<tt>.emacs</tt>
+ or <tt>.prj</tt> file.
+
</p>
- <p> If you want the setting to apply to all projects that
do not
+ <p>If you want the setting to apply to all projects that do
not
have a project file (see <a
href="#UsingProjectFiles">Using Project
Files</a>), you should save the variable in
your
<tt>.emacs</tt> file. To save the variable in
your
@@ -2917,7 +3085,10 @@
that project. To do this, open a source file from that
project, select
Set for Current Session from the State menu for the
variable, select the source buffer, and
select JDE->Project->Project
Files->Save
- (C-c C-v C-p) from the Emacs
menubar.
+ (C-c
+ C-v
+ C-p)
+ from the Emacs menubar.
</p>
<div class="note" style="margin-left: 0.5in;
margin-right: 0.5in;">
@@ -2934,13 +3105,97 @@
</div>
</div>
<div id="ab2c12b4" class="section">
- <h2 class="title" style="clear: all"><a
name="ab2c12b4"><b><a
name="JDECustomizationGroups"></a> JDE Customization
Groups</b></a></h2>
+ <h2 class="title" style="clear: all"><a
name="ab2c12b4"><b><a
name="SpecifyingPaths"></a>Specifying
Paths</b></a></h2>
+ <p>You can use paths containing environment variables and
+ or a tilde (~), cygwin paths, and relative paths as a
+ value of any JDE customization variable
+ that requires a path.
+ </p>
+ <div id="ab2c12b4b2" class="section">
+ <h3 class="title"><a
name="ab2c12b4b2"><b><a
name="EnvVarsInPaths"></a>Environment
Variables</b></a></h3>
+ <p>The JDE accepts paths that contain envirnoment variables,
for
+ example,
+ </p>
+ <p>
+ <pre class="programlisting">
+ $JDK_HOME/src
+ </pre>
+ </p>
+ <p>
+ The JDE replaces the environment variables with their actual
values
+ before passing the paths to commands (e.g., javac) that require
them.
+ You must use Unix notation (i.e., <tt>$VARNAME</tt>
or
+ <tt>${VARNAME}</tt>) to specify an environment
variable
+ in a path even on Windows.
+
+ </p>
+ </div>
+ <div id="ab2c12b4b3" class="section">
+ <h3 class="title"><a
name="ab2c12b4b3"><b><a
name="TildeNotation"></a>Tilde (~)
Notation</b></a></h3>
+ <p>The JDE accepts paths that begin with a tilde, for example,
+ <tt>~/myproj/classes</tt>. The JDE replaces the
tilde
+ with the path to your home directory.
+ </p>
+ </div>
+ <div id="ab2c12b4b4" class="section">
+ <h3 class="title"><a
name="ab2c12b4b4"><b><a
name="RelativePaths"></a>Relative
Paths</b></a></h3>
+ <p>A relative path is a path that begins with a period, for
+ example, <tt>./src</tt>. If
+ <tt>jde-resolve-relative-paths</tt> is
+ set to a non-nil value (the default), the JDE converts a relative
+ path to an absolute path by appending the relative path to the
+ path of the project file that set the path variable, or if no
such
+ file exists, to the path of the current Java source buffer.
+ </p>
+ </div>
+ <div id="ab2c12b4b5" class="section">
+ <h3 class="title"><a
name="ab2c12b4b5"><b><a
name="CygwinPaths"></a>Cygwin Paths</b></a></h3>
+ <p>You can use cygwin style paths in JDE classpath variables
+ on Windows. The JDE converts such paths to DOS paths before
+ using them, using a conversion function that you can specify.
+ </p>
+ <p>The jde-cgywin-path-converter variable allows you
+ to choose the path conversion function used by the JDE.
+ </p>
+ <div class="itemizedlist">
+ <ul>
+ <li><a
name="ab2c12b4b5b3a"></a><p><tt>
+
jde-cygwin-path-converter-internal</tt></p>
+ <p>This is the default path conversion function used
by
+ the JDE. It converts any paths of the form
<tt>//[a-z]/</tt>
+ or <tt>//cygdrive/[a-z]/</tt> to the
corresponding DOS form. For
+ example it converts
<tt>/c/jde/java/classes</tt> to
+ <tt>c:/jde/java/classes</tt>.
+
+ </p>
+ </li>
+ <li><a
name="ab2c12b4b5b3b1"></a><p><tt>jde-cygwin-path-converter-cygpath</tt></p>
+ <p>This function invokes the cygwin
<tt>cygpath</tt> utility to
+ perform the path conversion. The advantage is that
the cygwin path utility can
+ recognize and convert Unix style paths that
represent mount points in the cygwin
+ mount table. For example, suppose that you have
mounted
+ <tt>d:/javadev</tt> as
<tt>/javadev</tt> in
+ the cygwin mount table. Then choosing
+
<tt>jde-cygwin-path-converter-cygpath</tt>
+ allows you to use paths beginning with
<tt>/javadev</tt> in JDE classpaths. The
+ drawback is that the conversion is slow as it
requires running the cygwin utility
+ for each Unix-style path to be converted.
+ </p>
+ </li>
+ <li><a
name="ab2c12b4b5b3b2"></a><p>A custom conversion function that
you supply.</p>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ <div id="ab2c12b5" class="section">
+ <h2 class="title" style="clear: all"><a
name="ab2c12b5"><b><a
name="JDECustomizationGroups"></a> JDE Customization
Groups</b></a></h2>
<p>The JDE defines a top-level customization group, the JDE Group,
for JDE customization variables. The JDE Group itself contains
the following subgroups:
</p>
- <div id="ab2c12b4b2" class="section">
- <h3 class="title"><a
name="ab2c12b4b2"><b><a
name="CompileOptionGroup"></a> Compile Option
Group</b></a></h3>
+ <div id="ab2c12b5b2" class="section">
+ <h3 class="title"><a
name="ab2c12b5b2"><b><a
name="CompileOptionGroup"></a> Compile Option
Group</b></a></h3>
<p>Specifies compile options corresponding to the command-line
arguments (e.g., -d) accepted by the JDK compiler, javac. When
you
execute the JDE compile command, the JDE uses the settings of
this
@@ -2956,8 +3211,8 @@
from the Emacs menubar.
</p>
</div>
- <div id="ab2c12b4b3" class="section">
- <h3 class="title"><a
name="ab2c12b4b3"><b><a
name="CompileOptionGroup"></a>Run Option
Group</b></a></h3>
+ <div id="ab2c12b5b3" class="section">
+ <h3 class="title"><a
name="ab2c12b5b3"><b><a
name="CompileOptionGroup"></a>Run Option
Group</b></a></h3>
<p>Specifies run-time options corresponding to the command-line
arguments (for example, -classpath) accepted by the JDK virtual
machine, java. When you execute the JDE Run command,
the
@@ -2973,8 +3228,8 @@
from the Emacs menubar.
</p>
</div>
- <div id="ab2c12b4b4" class="section">
- <h3 class="title"><a
name="ab2c12b4b4"><b><a
name="DebugOptionGroup"></a> Debug Option
Group</b></a></h3>
+ <div id="ab2c12b5b4" class="section">
+ <h3 class="title"><a
name="ab2c12b5b4"><b><a
name="DebugOptionGroup"></a> Debug Option
Group</b></a></h3>
<p>Specifies run-time options corresponding to the command-line
arguments (for example, -classpath) accepted by the JDK
debugger,
jdb. jdb accepts the same command-line arguments as java.
However,
@@ -2990,12 +3245,12 @@
from the Emacs menubar.
</p>
</div>
- <div id="ab2c12b4b5" class="section">
- <h3 class="title"><a
name="ab2c12b4b5"><b> <a
name="AutocodeGroup"></a>Autocode
Group</b></a></h3>
+ <div id="ab2c12b5b5" class="section">
+ <h3 class="title"><a
name="ab2c12b5b5"><b> <a
name="AutocodeGroup"></a>Autocode
Group</b></a></h3>
<p>Specifies templates used to generate code automatically.
</p>
</div>
- <div id="ab2c12b4b6" class="section">
- <h3 class="title"><a
name="ab2c12b4b6"><b><a name="GeneralGroup"></a>
General Options Group</b></a></h3>
+ <div id="ab2c12b5b6" class="section">
+ <h3 class="title"><a
name="ab2c12b5b6"><b><a name="GeneralGroup"></a>
General Options Group</b></a></h3>
<p>Specify all other JDE options. You can display the
customization buffer for the General Option Group by selecting
JDE->Project->Options->General
Index: xemacs-packages/jde/doc/html/jde-ug/jde-ug-toc.html
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/doc/html/jde-ug/jde-ug-toc.html,v
retrieving revision 1.1
diff -u -r1.1 jde-ug-toc.html
--- xemacs-packages/jde/doc/html/jde-ug/jde-ug-toc.html 2001/02/16 04:45:42 1.1
+++ xemacs-packages/jde/doc/html/jde-ug/jde-ug-toc.html 2001/08/15 05:27:20
@@ -44,7 +44,7 @@
<td><a href="jde-ug-content.html#"
target="content">Specifying Classpaths</a></td>
</tr>
<tr>
- <td><a href="jde-ug-content.html#"
target="content"> Using Project Files</a></td>
+ <td><a href="jde-ug-content.html#"
target="content">Using Project Files</a></td>
</tr>
<tr>
<td><a href="jde-ug-content.html#"
target="content"> Displaying Java Documentation</a></td>
Index: xemacs-packages/jde/doc/html/jde-ug/images/KeyBindings.gif
===================================================================
RCS file: KeyBindings.gif
diff -N KeyBindings.gif
Binary files /dev/null and KeyBindings.gif differ
Index: xemacs-packages/jde/doc/html/jde-ug/images/jdemenu.gif
===================================================================
RCS file: jdemenu.gif
diff -N jdemenu.gif
Binary files /dev/null and jdemenu.gif differ
Index: xemacs-packages/jde/doc/src/jde-ug/jde-ug-content.xml
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/doc/src/jde-ug/jde-ug-content.xml,v
retrieving revision 1.1
diff -u -r1.1 jde-ug-content.xml
--- xemacs-packages/jde/doc/src/jde-ug/jde-ug-content.xml 2001/02/13 04:49:59 1.1
+++ xemacs-packages/jde/doc/src/jde-ug/jde-ug-content.xml 2001/08/15 05:27:24
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE book PUBLIC "-//Arbortext//DTD DocBk XML V2.0//EN"
- "file:///c:/xae-dev/xae/doctypes/docbook/docbookx.dtd" []>
+
"file:///c:/Applications/cygwin/home/xae-dev/xae/doctypes/docbook/docbookx.dtd"
[]>
-<?xml-stylesheet
href="file:///c:/jde-dev/jde/doc/src/styles/html/jdebook.xsl"
type="text/xsl" ?>
+<?xml-stylesheet
href="file:///c:/Applications/cygwin/home/jde-dev/jde/doc/src/styles/html/jdebook.xsl"
type="text/xsl" ?>
<!--
@@ -2120,13 +2120,34 @@
</programlisting>
<para>or select <menuchoice><guimenu>Java</guimenu>
- <guimenuitem>Run App</guimenuitem></menuchoice> on the
+ <guimenuitem>Run App</guimenuitem></menuchoice> from the
Emacs menubar or type <keycombo>
<keycap>C</keycap><keycap>c</keycap></keycombo> <keycombo>
<keycap>C</keycap><keycap>v</keycap></keycombo> <keycombo>
<keycap>C</keycap><keycap>r</keycap></keycombo>.
</para>
+ <section>
+ <title><anchor id="SpecifyingMainClass"/>Specifying the
Application's Main Class</title>
+
+ <para>The term <emphasis>main class</emphasis> refers to the
class
+ that contains the application's main method. The JDE's Run App command
+ assumes by default that the class in the current buffer is the
+ application's main class. This can be inconvenient if you have an
+ application that has multiple classes. You may want to be able to
+ run the application from any buffer containing one of the application's
+ classes. To do this, set the variable
+ <varname>jde-run-application-class</varname> to
+ the <emphasis>fully qualified name</emphasis> of the application's main
class.</para>
+
+ <para>You can temporarily override the setting of
+ <varname>jde-run-application-class</varname> by typing
<varname>C-u</varname>
+ before executing the <command moreinfo="none">jde-run</command>
command, for example,
+ by typing <varname>C-u C-c C-r</varname>. This causes the JDE to prompt you
to
+ enter the <emphasis>fully qualified name</emphasis> of the application's
main
+ class.</para>
+ </section>
+
<section>
@@ -2226,6 +2247,37 @@
</section>
<section>
+ <title><anchor id="NavigatingExceptionTraces"/>Navigating
Exception Traces</title>
+
+ <para>If an exception occurs while your program is running, the Java vm
+ outputs an exception trace. This trace appears in the run buffer for the
+ application.</para>
+
+ <para>
+ <screenshot>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/excepttrace.gif"/>
+ </imageobject>
+ <textobject>
+ Screenshot showing an exception trace in the
+ JDE's run buffer.
+ </textobject>
+ </mediaobject>
+ </screenshot>
+ </para>
+ </section>
+
+ <para>To view the source line corresponding to a point in
+ the exception stack trace, right-click the corresponding stack
+ trace line in the run buffer. You can move up and down
+ the stack trace by typing the key combinations
+ <varname>C-c C-v C-[</varname> or
+ <varname>C-c C-v C-]</varname>.</para>
+
+
+
+ <section>
<title><anchor id="RunOptions"/>Run Customization Variables
</title>
@@ -2613,11 +2665,20 @@
<varname>jde-global-classpath</varname> is the only variable you
need to set.</para>
+
+
<section>
<title><anchor id="SettingClasspathVar"/>Setting a Classpath
Variable</title>
<para>As with other JDE customization variables, you must use Emacs'
<command moreinfo="none">customize-variable</command> command to
- set the JDE's classpath variables. When setting a classpath variable,
+ set the JDE's classpath variables. You can use relative paths, cygwin paths,
+ and paths with tilde notation and environment variables as values of
+ JDE classpath variables. See <ulink url="#SpecifyingPaths">Specifying
+ Paths</ulink> for more information.
+ </para>
+
+ <para>
+ When setting a classpath variable,
you must enter each path as a separate entry in the customization
buffer. Do not enter the paths as semicolon or colon-separated lists
of paths. The following examples show the right and wrong way to
@@ -2644,77 +2705,76 @@
</programlisting>
</example>
</section>
-
- <section>
- <title><anchor id="EnvVarsInClasspaths"/>Environment
Variables in Classpaths</title>
- <para>You can use environment variables in classpaths. For
example,</para>
-
- <para>
- <programlisting>
- $JDE_HOME/java/classes
- </programlisting>
+ <section>
+ <title><anchor id="ClassLibraries"/>Including Class
Libraries</title>
+ <para>
+ If you store your class libraries as jar or zip files in
+ separate directory, you need specify only the path of the directory
+ in a JDE classpath variable. Whenever the JDE encounters a library directory
+ in a classpath variable, it expands the classpath to include all
+ the jar and zip files in the library directory.
</para>
- <para>is a valid entry in a classpath. The JDE substitutes the
- actual value of an environment variable wherever the variable
- occurs in the classpath.</para>
-
- <note>
- <para>You must use the Unix notation for environment variables
- on Windows, e.g., <varname>$JDE_HOME</varname> or
- <varname>${JDE_HOME}</varname>. Emacs does not accept DOS
- notation, e.g., <varname>%JDE_HOME%</varname>.</para>
- </note>
+ <para>
+ For example, suppose you organize your project directory as
+ follows:
+ </para>
+
+ <para>
+ <programlisting format="linespecific">
+ myproj
+ classes
+ lib
+ src
+ </programlisting>
+ </para>
- </section>
+ <para>
+ where the <filename>src</filename> directory contains all of
+ your source files, the <filename>lib</filename> directory all
+ of your jar and zip files, and the
+ <filename>classes</filename> directory all of the classes
+ compiled from the <filename>src</filename> directory. Further,
+ suppose you store your project file
+ (see <ulink url="#UsingProjectFiles">Using Project Files</ulink>)
+ at the root of your project directory. Then, you can specify
+ <varname>jde-global-classpath</varname> simply as follows.
+ </para>
- <section>
- <title><anchor id="CygwinPaths"/>Using Cygwin
Paths</title>
- <para>You can use cygwin style paths in JDE classpath variables
- on Windows. The JDE converts such paths to DOS paths before
- using them, using a conversion function that you can specify.</para>
-
- <para>The jde-cgywin-path-converter variable allows you
- to choose the path conversion function used by the JDE.</para>
+ <para>
+ <programlisting format="linespecific">
+ jde-global-classpath: [Hide]
+ [INS] [DEL] Path: ./classes
+ [INS] [DEL] Path: ./src
+ [INS] [DEL] Path: ./lib
+ [INS]
+ [State]: this option has been set and saved.
+ </programlisting>
+ </para>
- <itemizedlist>
- <listitem>
- <para><function moreinfo="none">
- jde-cygwin-path-converter-internal</function></para>
- <para>This is the default path conversion function used by
- the JDE. It converts any paths of the form <varname>//[a-z]/</varname>
- or <varname>//cygdrive/[a-z]/</varname> to the corresponding DOS form.
For
- example it converts <varname>/c/jde/java/classes</varname> to
- <varname>c:/jde/java/classes</varname>.
- </para>
- </listitem>
- <listitem>
- <para><function
moreinfo="none">jde-cygwin-path-converter-cygpath</function></para>
- <para>This function invokes the cygwin <function>cygpath</function>
utility to
- perform the path conversion. The advantage is that the cygwin path utility can
- recognize and convert Unix style paths that represent mount points in the cygwin
- mount table. For example, suppose that you have mounted
- <varname>d:/javadev</varname> as <varname>/javadev</varname>
in
- the cygwin mount table. Then choosing
- <function
moreinfo="none">jde-cygwin-path-converter-cygpath</function>
- allows you to use paths beginning with <varname>/javadev</varname> in
JDE classpaths. The
- drawback is that the conversion is slow as it requires running the cygwin utility
- for each Unix-style path to be converted.</para>
- </listitem>
- <listitem>
- <para>A custom conversion function that you supply.</para>
- </listitem>
- </itemizedlist>
+ <para>
+ If you do not want the JDE to expand library directories, set the variable
+ <varname>jde-expand-classpath-p</varname> off. The JDE expands
+ directories whose names match the regular expression specified by
+ <varname>jde-lib-directory-name</varname>. The default value of this
variable
+ is <filename>lib</filename>. So by default, the JDE expands names
+ that contain the string <filename>lib</filename>,
+ e.g., <filename>lib</filename>, <filename>mylib</filename>,
+ <filename>utility_lib</filename>, etc. However, you can customize
+ <varname>jde-lib-directory-name</varname> to reflect any library naming
+ scheme you prefer.
+ </para>
</section>
+
</chapter>
<chapter>
- <title><anchor id="UsingProjectFiles"/> Using Project
Files</title>
+ <title><anchor id="UsingProjectFiles"/>Using Project
Files</title>
<para>A project file is a Lisp file that the JDE loads and evaluates
whenever you open a Java source file belonging to a specific
@@ -2733,18 +2793,39 @@
two assumptions. First, it assumes that all Java source files
relating to a particular project live in a single directory tree.
Second, it assumes that all project files have the same file name.
- The name assumed by default is prj.el. You can use the JDE
+ The name assumed by default is <filename>prj.el</filename>. You can use the
JDE
configuration variable <varname>jde-project-file-name</varname> to specify
- another name. When you open a Java source file, the JDE looks for
- a project file in the directory containing the source file. If it
- cannot find a project file in the source file directory, it
- searches up the directory tree until it finds a project file or
- reaches the root of the directory tree. If the JDE finds a
- project file, it loads and evaluates the contents of the file as
- the last step in creating the buffer containing the Java source
- file. </para>
- </section>
+ another name.</para>
+
+ <para>
+ When you open a Java source file, the JDE looks for
+ project files in the directory tree containing the source file.
+ If the JDE finds one or more project files, it loads the
+ project files in the following manner.
+ </para>
+
+ <para>
+ The JDE first sets all the JDE variables to their
+ Emacs startup values (i.e., the default value or the value
+ saved in your <filename>.emacs</filename> file). It then loads
+ all the project files in the directory tree containing the
+ current source buffer, starting with the topmost file.
+ </para>
+ <para>
+ What this means is that you can use project files to extend
+ and/or override the settings in your
+ <filename>.emacs</filename> file and in other project files.
+ For example, your <filename>.emacs</filename> file can specify
+ settings that are common to all your projects. You can put
+ settings common to a group of projects at the top of the
+ directory tree containing the projects, settings common to
+ each project at the top of the directory containing each
+ projects, and so on.
+ </para>
+
+ </section>
+
<section>
@@ -2763,7 +2844,7 @@
<section>
- <title><anchor id="CreatingProjectFiles"/> Creating a Project
File</title>
+ <title><anchor id="CreatingProjectFiles"/>Creating a Project
File</title>
<para>The easiest way to create a project file is to use the
<varname>jde-save-project </varname> command (<menuchoice>
@@ -2771,7 +2852,7 @@
<guisubmenu>Project</guisubmenu><guisubmenu>Project
File</guisubmenu><guimenuitem>Save
Project</guimenuitem></menuchoice>). This command saves the current
- values of all the JDE configuration variables in the project file for
+ values of all customized JDE configuration variables in the project file for
the selected Java buffer. (To be precise, the command inserts Lisp
code in the project file that restores the current settings of the
configuration variables; if such code already exists in the file, it
@@ -2798,10 +2879,21 @@
<para>Select <menuchoice>
<guimenu>JDE</guimenu>
<guisubmenu>Project</guisubmenu><guisubmenu>Project
- File</guisubmenu><guimenuitem>Save
Project</guimenuitem></menuchoice>
- to create a project file in the directory containing the source
- file.</para>
+ File</guisubmenu><guimenuitem>Save
Project</guimenuitem></menuchoice>.
+ </para>
</step>
+ <step performance="required">
+ <para>
+ The JDE prompts you to enter the path to a directory in which to store
+ the project file.
+ </para>
+ </step>
+ <step performance="required">
+ <para>
+ Enter the directory where you want to store the project file or
+ press <keycap>Enter</keycap> to store the project file in the current
directory.
+ </para>
+ </step>
</procedure>
<para>Once you have created the project file, you can insert
@@ -2814,8 +2906,91 @@
</para>
</section>
- </chapter>
+ <section>
+ <title><anchor id="CreatingPortableProjects"/>Creating
Portable Projects</title>
+ <para>
+ You can use relative paths and environment variables to
+ construct portable project files. For example, suppose your
+ project directory has the following structure:
+ </para>
+ <para>
+ <programlisting>
+ myprj
+ classes
+ pkg1
+ pkg2
+ src
+ pkg1
+ pkg2
+ prj.el
+ </programlisting>
+ </para>
+ <para>
+ Further suppose that your project uses beans from a
+ shared library specified by the environment variable
+ <varname>BEANS</varname>. With this setup,
+ you can specify <varname>jde-global-classpath</varname> as
+ </para>
+ <para>
+ <programlisting>
+ ./src
+ ./classes
+ $BEANS/lib/dials.jar
+ </programlisting>
+ </para>
+ <para>
+ and <varname>jde-compile-option-directory</varname> as
+ </para>
+ <para>
+ <programlisting>
+ ./classes
+ </programlisting>
+ </para>
+ <para>
+ This causes the JDE to store classes compiled from your src
+ directory in the classes directory. Note that you have not
+ used any absolute paths in creating your project file. This
+ means you can move your project anywhere without having to update
+ the project file.
+ </para>
+
+ </section>
+
+ <section>
+ <title><anchor id="DisablingContextSwitching"/>Disabling
Context Switching</title>
+ <para>When you select a buffer that belongs to another
+ project, the JDE loads the project file for that project
+ and may update the class list for the project. This
+ causes a slight delay before you can begin using the
+ new buffer. The delay can be irritating if you need
+ to switch frequently among open projects, for example,
+ when copying or diffing code from different projects.
+ Accordingly, the JDE provides ways for you to disable
+ context-switching either permanently or temporarily.
+ </para>
+
+ <para>To disable context-switching permanently, toggle
+ the customizat variable
+ <varname>jde-project-context-switching-enabled-p</varname>
+ off. Be sure to use customize to do this and save the
+ customization in your <filename moreinfo="none">
+ .emacs</filename> or <filename
moreinfo="none">prj.el</filename>
+ file. Note that you can use the JDE's project file loading
+ command, <command>JDE->Project->Project File->Load</command>,
+ to switch contexts manually.
+ </para>
+
+ <para>
+ To disable context-switching temporarily during a session,
+ select <command>
+ JDE->Project->Auto Switch</command> or enter
+ <varname>M-x jde-toggle-project-context-switching</varname>. To reenable
+ context-switching, execute the same command again.
+ </para>
+ </section>
+ </chapter>
+
<chapter>
@@ -3285,9 +3460,9 @@
type
<keycombo><keycap>C</keycap><keycap>h</keycap></keycombo>
<keysym>v</keysym> followed by the JDE group prefix
(<varname>jde-</varname>) or subgroup prefix (e.g.,
- <varname>jde-compile-option-</varname>, see <ulink
- url="#JDECustomizationGroups"> JDE Customization
Groups</ulink>). Emacs
- displays all variables belonging to the JDE group or subgroup. You
+ <varname>jde-compile-option-</varname>,
+ see <ulink url="#JDECustomizationGroups">JDE Customization
Groups</ulink>).
+ Emacs displays all variables belonging to the JDE group or subgroup. You
can then browse this list, using Emacs search, completion, and
documentation display command, to find the applicable variable.
</para>
@@ -3315,8 +3490,10 @@
</step>
<step>
- <para>Save the value for the variable in your
<filename>.emacs</filename> or <filename>.prj</filename> file.
</para>
- <para> If you want the setting to apply to all projects that do not
+ <para>Save the value for the variable in your
<filename>.emacs</filename>
+ or <filename>.prj</filename> file.
+ </para>
+ <para>If you want the setting to apply to all projects that do not
have a project file (see <ulink url="#UsingProjectFiles">Using
Project
Files</ulink>), you should save the variable in your
<filename>.emacs</filename> file. To save the variable in your
@@ -3331,8 +3508,13 @@
<menuchoice><guimenuitem>Set for Current Session</guimenuitem>
</menuchoice> from the
<menuchoice><guimenu>State</guimenu>
</menuchoice> menu for the variable, select the source buffer, and
- select
<menuchoice><guimenu>JDE</guimenu><guisubmenu>Project</guisubmenu><guisubmenu>Project
Files</guisubmenu><guimenuitem>Save</guimenuitem></menuchoice>
-
(<keycombo><keycap>C</keycap><keycap>c</keycap></keycombo> <keycombo><keycap>C</keycap><keycap>v</keycap></keycombo> <keycombo><keycap>C</keycap><keycap>p</keycap></keycombo>)
from the Emacs menubar.
+ select <menuchoice><guimenu>JDE</guimenu>
+ <guisubmenu>Project</guisubmenu><guisubmenu>Project
Files</guisubmenu>
+ <guimenuitem>Save</guimenuitem></menuchoice>
+
(<keycombo><keycap>C</keycap><keycap>c</keycap></keycombo>
+
<keycombo><keycap>C</keycap><keycap>v</keycap></keycombo>
+
<keycombo><keycap>C</keycap><keycap>p</keycap></keycombo>)
+ from the Emacs menubar.
</para>
<note>
<para> If a project file does exist for the
@@ -3344,7 +3526,96 @@
</step>
</procedure>
- </section>
+ </section>
+
+ <section>
+ <title><anchor id="SpecifyingPaths"/>Specifying
Paths</title>
+ <para>You can use paths containing environment variables and
+ or a tilde (~), cygwin paths, and relative paths as a
+ value of any JDE customization variable
+ that requires a path.</para>
+
+ <section>
+ <title><anchor id="EnvVarsInPaths"/>Environment
Variables</title>
+ <para>The JDE accepts paths that contain envirnoment variables, for
+ example, </para>
+
+ <para>
+ <programlisting format="linespecific">
+ $JDK_HOME/src
+ </programlisting>
+ </para>
+
+ <para>
+ The JDE replaces the environment variables with their actual values
+ before passing the paths to commands (e.g., javac) that require them.
+ You must use Unix notation (i.e., <varname>$VARNAME</varname> or
+ <varname>${VARNAME}</varname>) to specify an environment variable
+ in a path even on Windows.
+ </para>
+
+ </section>
+
+ <section>
+ <title><anchor id="TildeNotation"/>Tilde (~)
Notation</title>
+ <para>The JDE accepts paths that begin with a tilde, for example,
+ <filename>~/myproj/classes</filename>. The JDE replaces the tilde
+ with the path to your home directory.</para>
+ </section>
+
+ <section>
+ <title><anchor id="RelativePaths"/>Relative Paths</title>
+ <para>A relative path is a path that begins with a period, for
+ example, <filename>./src</filename>. If
+ <varname>jde-resolve-relative-paths</varname> is
+ set to a non-nil value (the default), the JDE converts a relative
+ path to an absolute path by appending the relative path to the
+ path of the project file that set the path variable, or if no such
+ file exists, to the path of the current Java source buffer.</para>
+ </section>
+
+ <section>
+ <title><anchor id="CygwinPaths"/>Cygwin Paths</title>
+ <para>You can use cygwin style paths in JDE classpath variables
+ on Windows. The JDE converts such paths to DOS paths before
+ using them, using a conversion function that you can specify.</para>
+
+ <para>The jde-cgywin-path-converter variable allows you
+ to choose the path conversion function used by the JDE.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><function moreinfo="none">
+ jde-cygwin-path-converter-internal</function></para>
+ <para>This is the default path conversion function used by
+ the JDE. It converts any paths of the form
<varname>//[a-z]/</varname>
+ or <varname>//cygdrive/[a-z]/</varname> to the corresponding DOS form.
For
+ example it converts <varname>/c/jde/java/classes</varname> to
+ <varname>c:/jde/java/classes</varname>.
+ </para>
+ </listitem>
+ <listitem>
+ <para><function
moreinfo="none">jde-cygwin-path-converter-cygpath</function></para>
+ <para>This function invokes the cygwin
<function>cygpath</function> utility to
+ perform the path conversion. The advantage is that the cygwin path utility can
+ recognize and convert Unix style paths that represent mount points in the cygwin
+ mount table. For example, suppose that you have mounted
+ <varname>d:/javadev</varname> as
<varname>/javadev</varname> in
+ the cygwin mount table. Then choosing
+ <function
moreinfo="none">jde-cygwin-path-converter-cygpath</function>
+ allows you to use paths beginning with <varname>/javadev</varname> in
JDE classpaths. The
+ drawback is that the conversion is slow as it requires running the cygwin
utility
+ for each Unix-style path to be converted.</para>
+ </listitem>
+ <listitem>
+ <para>A custom conversion function that you supply.</para>
+ </listitem>
+ </itemizedlist>
+
+ </section>
+
+
+ </section>
<section>
Index: xemacs-packages/jde/doc/src/styles/html/jdebook.xsl
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/doc/src/styles/html/jdebook.xsl,v
retrieving revision 1.1
diff -u -r1.1 jdebook.xsl
--- xemacs-packages/jde/doc/src/styles/html/jdebook.xsl 2001/02/16 05:53:44 1.1
+++ xemacs-packages/jde/doc/src/styles/html/jdebook.xsl 2001/08/15 05:27:25
@@ -5,7 +5,7 @@
exclude-result-prefixes="doc"
version='1.0'>
-<xsl:import
href="file:///c:/xae-dev/xae/doctypes/docbook/styles/docbook/html/docbook.xsl"
/>
+<xsl:import
href="file:///c:/Applications/cygwin/home/xae-dev/xae/doctypes/docbook/styles/docbook/html/docbook.xsl"
/>
<xsl:variable name="chapter.autolabel">0</xsl:variable>
<xsl:variable name="generate.division.toc">0</xsl:variable>
Index: xemacs-packages/jde/doc/tli_rbl/txt/jde-ug-toc.txt
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/doc/tli_rbl/txt/jde-ug-toc.txt,v
retrieving revision 1.2
diff -u -r1.2 jde-ug-toc.txt
--- xemacs-packages/jde/doc/tli_rbl/txt/jde-ug-toc.txt 2001/02/17 07:46:53 1.2
+++ xemacs-packages/jde/doc/tli_rbl/txt/jde-ug-toc.txt 2001/08/15 05:27:26
@@ -26,9 +26,11 @@
1 ; Build Options ; 0 ; ../html/jde-ug/jde-ug-content.html#BuildOptions
2 ; Sample Makefile ; 3 ; ../html/jde-ug/jde-ug-content.html#SampleMakefile
0 ; Running Java Applications ; 0 ; ../html/jde-ug/jde-ug-content.html#RunningJavaApps
+1 ; Specifying the Application's Main Class ; 3 ;
../html/jde-ug/jde-ug-content.html#SpecifyingMainClass
1 ; Specifying a Startup Directory ; 3 ;
../html/jde-ug/jde-ug-content.html#SpecifyingStartupDirectory
1 ; Setting VM Command-Line Arguments ; 3 ;
../html/jde-ug/jde-ug-content.html#RunVMArgs
1 ; Setting Command-Line Application Arguments ; 3 ;
../html/jde-ug/jde-ug-content.html#RunAppArgs
+1 ; Navigating Exception Traces ; 3 ;
../html/jde-ug/jde-ug-content.html#NavigatingExceptionTraces
1 ; Run Customization Variables ; 3 ; ../html/jde-ug/jde-ug-content.html#RunOptions
0 ; Working with Applets ; 0 ; ../html/jde-ug/jde-ug-content.html#WorkingWithApplets
1 ; Running Applets ; 3 ; ../html/jde-ug/jde-ug-content.html#RunningApplets
@@ -37,12 +39,13 @@
0 ; Debugging Applications ; 0 ; ../html/jde-ug/jde-ug-content.html#DebuggingApps
0 ; Specifying Classpaths ; 0 ; ../html/jde-ug/jde-ug-content.html#SpecifyingClasspaths
1 ; Setting a Classpath Variable ; 3 ;
../html/jde-ug/jde-ug-content.html#SettingClasspathVar
-1 ; Environment Variables in Classpaths ; 3 ;
../html/jde-ug/jde-ug-content.html#EnvVarsInClasspaths
-1 ; Using Cygwin Paths ; 3 ; ../html/jde-ug/jde-ug-content.html#CygwinPaths
+1 ; Including Class Libraries ; 3 ; ../html/jde-ug/jde-ug-content.html#ClassLibraries
0 ; Using Project Files ; 0 ; ../html/jde-ug/jde-ug-content.html#UsingProjectFiles
1 ; How the JDE Finds Project Files ; 3 ;
../html/jde-ug/jde-ug-content.html#FindingProjectFiles
1 ; Project File Contents ; 3 ; ../html/jde-ug/jde-ug-content.html#ProjectFileContents
1 ; Creating a Project File ; 3 ;
../html/jde-ug/jde-ug-content.html#CreatingProjectFiles
+1 ; Creating Portable Projects ; 3 ;
../html/jde-ug/jde-ug-content.html#CreatingPortableProjects
+1 ; Disabling Context Switching ; 3 ;
../html/jde-ug/jde-ug-content.html#DisablingContextSwitching
0 ; Displaying Java Documentation ; 0 ;
../html/jde-ug/jde-ug-content.html#DisplayingDoc
1 ; Browsing JDK Documentation ; 3 ; ../html/jde-ug/jde-ug-content.html#BrowsingJDKDoc
1 ; Context-Sensitive Class Help ; 3 ; ../html/jde-ug/jde-ug-content.html#ClassHelp
@@ -64,6 +67,11 @@
0 ; Customizing the JDE ; 0 ; ../html/jde-ug/jde-ug-content.html#CustomizingJDE
1 ; Customization Variables ; 3 ;
../html/jde-ug/jde-ug-content.html#CustomizationVariables
1 ; Setting a Variable ; 3 ; ../html/jde-ug/jde-ug-content.html#SettingVariable
+1 ; Specifying Paths ; 0 ; ../html/jde-ug/jde-ug-content.html#SpecifyingPaths
+2 ; Environment Variables ; 3 ; ../html/jde-ug/jde-ug-content.html#EnvVarsInPaths
+2 ; Tilde (~) Notation ; 3 ; ../html/jde-ug/jde-ug-content.html#TildeNotation
+2 ; Relative Paths ; 3 ; ../html/jde-ug/jde-ug-content.html#RelativePaths
+2 ; Cygwin Paths ; 3 ; ../html/jde-ug/jde-ug-content.html#CygwinPaths
1 ; JDE Customization Groups ; 0 ;
../html/jde-ug/jde-ug-content.html#JDECustomizationGroups
2 ; Compile Option Group ; 3 ; ../html/jde-ug/jde-ug-content.html#CompileOptionGroup
2 ; Run Option Group ; 3 ; ../html/jde-ug/jde-ug-content.html#CompileOptionGroup
Index: xemacs-packages/jde/java/lib/jde.jar
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/lib/jde.jar,v
retrieving revision 1.2
diff -u -r1.2 jde.jar
Binary files /usr/tmp/cvs005368 and jde.jar differ
Index: xemacs-packages/jde/java/src/jde/debugger/CommandStream.java
===================================================================
RCS file: CommandStream.java
diff -N CommandStream.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ CommandStream.java Tue Aug 14 22:27:46 2001
@@ -0,0 +1,111 @@
+package jde.debugger;
+import java.io.StreamTokenizer;
+import java.io.BufferedReader;
+import java.util.List;
+import java.util.ArrayList;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.InputStreamReader;
+
+
+/**
+ * CommandStream.java
+ *
+ *
+ * Created: Tue Feb 13 15:40:34 2001
+ *
+ * @author <a href="mailto: "</a>
+ * @version
+ */
+
+public class CommandStream extends StreamTokenizer {
+
+ public CommandStream (BufferedReader in){
+
+ super(in);
+ setSyntax();
+ }
+
+ public List nextCommand() {
+
+ List commandLine = new ArrayList();
+
+ try {
+
+ int token = nextToken();
+
+ while (token != TT_EOL) {
+
+ switch (token) {
+
+ case TT_EOF :
+ throw new IOException("EOF occurred reading command stream.");
+
+ case TT_WORD :
+ case '"' :
+ case '\'':
+ commandLine.add(sval);
+ break;
+
+ default:
+ commandLine.add(String.valueOf((char)token));
+ break;
+ } // end of switch ()
+
+ token = nextToken();
+ }
+
+ if (commandLine.size() < 3) {
+ if (commandLine.size() > 0)
+ JDE.getJDE().signalCommandError(Jdebug.debuggerID, new Integer(-1), "Malformed
command");
+ commandLine = nextCommand();
+ }
+ }
+ catch (IOException ex) {
+ commandLine = null;
+ } // end of catch
+
+ return commandLine;
+ }
+
+ /**
+ * Sets the syntax of the command stream. We want the input to be broken
+ * into lines, with whitespaces separating tokens
+ */
+ private void setSyntax() {
+ resetSyntax();
+ eolIsSignificant(true);
+ whitespaceChars('\u0000', '\u0020');
+ wordChars('\u0021', '\u00ff');
+ quoteChar('"');
+ }
+
+ public static void main (String[] args) {
+
+ PrintWriter out = new PrintWriter(System.out);
+ BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
+ CommandStream commandStream = new CommandStream(in);
+
+ out.print("> ");
+ out.flush();
+ List command = commandStream.nextCommand();
+ while (command != null && ! ((String)
command.get(2)).startsWith("qu")) {
+
+ int n = command.size();
+ for (int i = 0; i<n; i++) {
+ out.println(command.get(i));
+ } // end of for ()
+
+ out.print("> ");
+ out.flush();
+ command = commandStream.nextCommand();
+ } // end of while ()
+
+
+
+
+ } // end of main ()
+
+
+
+}// CommandStream
Index: xemacs-packages/jde/java/src/jde/debugger/Debug.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/Debug.java,v
retrieving revision 1.1
diff -u -r1.1 Debug.java
--- xemacs-packages/jde/java/src/jde/debugger/Debug.java 2000/08/13 13:36:08 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/Debug.java 2001/08/15 05:27:46
@@ -1,70 +1,70 @@
-
-package jde.debugger;
-
-/**
- * Debug.java
- * <p>
- * keeps state and has variables regarding the variable states
- * <p>
- * Explanation of debug levels:
- * Debug.NONE: None
- * Debug.APP_IO: Debug App I/O
- * Debug.JDE_PIPE: Debug JDE-JDEbug pipe
- * Debug.EVENTS: Debug Event receiving/sending
- * Debug.EXCEPTION:Print stack trace on exception
- * <p>
- * Created: Thu Jul 8 13:03:25 1999
- *
- * @author Amit Kumar
- * @since 0.1
- */
-
-public class Debug implements Protocol {
-
- // the different debug states
- public final static int NONE = 0;
- public final static int APP_IO = 1;
- public final static int JDE_PIPE = 2;
- public final static int EVENTS = 4;
- public final static int EXCEPTION = 8;
-
- public static int debug
- = APP_IO
- | JDE_PIPE
- | EVENTS
- // | EXCEPTION
- ;
-
- // some useful functions
- public static void printIf(Exception ex) {
- if (set(EXCEPTION)) {
- System.out.println(BR+"("+JDE_BUG+DEBUG+" \"");
- ex.printStackTrace();
- System.out.println("\")"+BR);
- System.out.flush();
- }
- }
-
- public static void printIf(int val, Object obj) {
- if (set(val)) {
- System.out.println(BR+"("+JDE_BUG+DEBUG+" \"");
- System.out.println(obj);
- System.out.println("\")"+BR);
- System.out.flush();
- }
- }
-
- public static void printIf(int val, double obj) {
- if (set(val)) {
- System.out.println(BR+"("+JDE_BUG+DEBUG+" \"");
- System.out.println(obj);
- System.out.println("\")"+BR);
- System.out.flush();
- }
- }
-
- public static boolean set(int val) {
- return ((debug & val) != 0);
- }
-
-} // Debug
+
+package jde.debugger;
+
+/**
+ * Debug.java
+ * <p>
+ * keeps state and has variables regarding the variable states
+ * <p>
+ * Explanation of debug levels:
+ * Debug.NONE: None
+ * Debug.APP_IO: Debug App I/O
+ * Debug.JDE_PIPE: Debug JDE-JDEbug pipe
+ * Debug.EVENTS: Debug Event receiving/sending
+ * Debug.EXCEPTION:Print stack trace on exception
+ * <p>
+ * Created: Thu Jul 8 13:03:25 1999
+ *
+ * @author Amit Kumar
+ * @since 0.1
+ */
+
+public class Debug implements Protocol {
+
+ // the different debug states
+ public final static int NONE = 0;
+ public final static int APP_IO = 1;
+ public final static int JDE_PIPE = 2;
+ public final static int EVENTS = 4;
+ public final static int EXCEPTION = 8;
+
+ public static int debug
+ = APP_IO
+ | JDE_PIPE
+ | EVENTS
+ // | EXCEPTION
+ ;
+
+ // some useful functions
+ public static void printIf(Exception ex) {
+ if (set(EXCEPTION)) {
+ System.out.println(BR+"("+JDE_BUG+DEBUG+" \"");
+ ex.printStackTrace();
+ System.out.println("\")"+BR);
+ System.out.flush();
+ }
+ }
+
+ public static void printIf(int val, Object obj) {
+ if (set(val)) {
+ System.out.println(BR+"("+JDE_BUG+DEBUG+" \"");
+ System.out.println(obj);
+ System.out.println("\")"+BR);
+ System.out.flush();
+ }
+ }
+
+ public static void printIf(int val, double obj) {
+ if (set(val)) {
+ System.out.println(BR+"("+JDE_BUG+DEBUG+" \"");
+ System.out.println(obj);
+ System.out.println("\")"+BR);
+ System.out.flush();
+ }
+ }
+
+ public static boolean set(int val) {
+ return ((debug & val) != 0);
+ }
+
+} // Debug
Index: xemacs-packages/jde/java/src/jde/debugger/DebuggeeProcess.java
===================================================================
RCS file: DebuggeeProcess.java
diff -N DebuggeeProcess.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ DebuggeeProcess.java Tue Aug 14 22:27:46 2001
@@ -0,0 +1,400 @@
+package jde.debugger;
+
+import com.sun.jdi.ReferenceType;
+import com.sun.jdi.VirtualMachine;
+import com.sun.jdi.event.EventQueue;
+import com.sun.jdi.request.ClassPrepareRequest;
+import com.sun.jdi.request.EventRequest;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import jde.debugger.ObjectStore;
+import jde.debugger.spec.BreakpointSpec;
+import jde.debugger.spec.EventRequestSpec;
+import jde.debugger.spec.EventRequestSpecList;
+import jde.debugger.spec.ExceptionSpec;
+import jde.debugger.spec.WatchpointSpec;
+import java.io.BufferedWriter;
+import java.io.OutputStreamWriter;
+import com.sun.jdi.ThreadReference;
+import com.sun.jdi.ThreadGroupReference;
+
+
+/**
+ * Class of debuggee processes.
+ *
+ * @author Amit Kumar
+ * @since 0.1
+ * @author Paul Kinnucan
+ * @since 1.5
+ */
+public class DebuggeeProcess implements Protocol {
+
+
+ /********************************************************************
+ * CONSTRUCTORS *
+ ********************************************************************/
+
+ /**
+ * Creates an instance of a process object.
+ *
+ * @param jdebug {@link Jdebug} class
+ * @param procID Identifier used to specify this app int commands.
+ * @param vm Virtual machine in which this process is running.
+ */
+ public DebuggeeProcess(Integer procID, VirtualMachine vm) {
+
+ this.procID = procID;
+
+ this.vm = vm;
+
+ store = new ObjectStore(this);
+
+ eventHandler = new EventHandler(this);
+
+ eventRequestSpecs = new EventRequestSpecList(this);
+
+ // we need to raise all class prepare events to
+ // make sure we resolve the corresponding specs.
+ ClassPrepareRequest cprequest =
+ vm.eventRequestManager().createClassPrepareRequest();
+
+ // this (hack?) is used to identify if the user itself specified
+ // a class prepare request, or the event was raised because of
+ // this request.
+ cprequest.putProperty("default", "default");
+ cprequest.setSuspendPolicy(EventRequest.SUSPEND_ALL);
+ cprequest.enable();
+
+ debuggeeSIO = new DebuggeeSIO(this);
+
+ }
+
+ /********************************************************************
+ * METHODS *
+ ********************************************************************/
+
+ /*
+ * Gets the virtual machine that is running this application.
+ * @return Process running this vm.
+ */
+ public final VirtualMachine getVM() { return vm; }
+
+ /*
+ * Gets the ID used by commands to specify this application.
+ *
+ * @return application ID
+ */
+ public final Integer getId() { return procID; }
+
+ /*
+ * Generates an ID used by commands to reference objects.
+ *
+ * @return new object ID
+ */
+ public final Long generateObjectID() {
+ // synchronize on any static object
+ synchronized (Jdebug.debuggerID) {
+ return new Long(objIdCounter++);
+ }
+ }
+
+ public final ObjectStore getStore() { return store; }
+
+ public final EventQueue getEventQueue() { return vm.eventQueue(); }
+
+
+ public final void shutdown() {
+ // we need to be a little considerate to the output. given
+ // there are all kinds of threads running, we make sure we
+ // wait for all the output to complete.
+
+ shuttingDown = true;
+
+ // isolate the process first
+ Process process = null;
+ if (vm != null)
+ process = vm.process();
+ try {
+ if (vm != null) {
+ vm.dispose();
+ vm = null;
+ eventHandler.shutdown();
+ }
+ debuggeeSIO.shutdown();
+ } catch (Exception ex) {
+ // do nothing
+ } finally {
+ if (process != null) {
+ process.destroy();
+ // XXX sun's jdb implementation works a lot to make sure
+ // the stderr and stdout are dumped before killing
+ // things. i'm not sure how important it is, or even how
+ // well it works (given i can't test it)
+ // sooo, if the reader finds bugs with the output handling
+ // on finish, lemme know.
+ }
+ procRegistry.removeProcess(procID);
+ }
+ }
+
+
+
+ /*
+ * FUNCTIONS TO MANAGE Standard IO STREAMS
+ */
+
+
+
+
+ /*
+ *
+ * USEFUL FUNCTIONS
+ *
+ */
+
+
+
+ /**
+ * Return a list of ReferenceType objects for all
+ * currently loaded classes and interfaces whose name
+ * matches the given pattern. The pattern syntax is
+ * open to some future revision, but currently consists
+ * of a fully-qualified class name in which the first
+ * component may optionally be a "*" character, designating
+ * an arbitrary prefix.
+ */
+ public List findClassesMatchingPattern(String pattern)
+ throws JDEException {
+ if (vm == null) return null;
+ List result = new ArrayList(); //### Is default size OK?
+ if (pattern.startsWith("*.")) {
+ // Wildcard matches any leading package name.
+ pattern = pattern.substring(1);
+ List classes = vm.allClasses();
+ Iterator iter = classes.iterator();
+ while (iter.hasNext()) {
+ ReferenceType type = ((ReferenceType)iter.next());
+ if (type.name().endsWith(pattern)) {
+ result.add(type);
+ }
+ }
+ return result;
+ } else {
+ // It's a class name.
+ return vm.classesByName(pattern);
+ }
+ }
+
+ /**
+ * Returns the thread corresponding to this name
+ */
+ public ThreadReference getThread(String name) {
+
+ List list = vm.allThreads();
+ Iterator it = list.iterator();
+
+ ThreadReference thread;
+ while (it.hasNext()) {
+ thread = (ThreadReference)it.next();
+ if (thread.name().equals(name)) return thread;
+ }
+
+ return null;
+ }
+
+
+ /**
+ * Returns a representation of all the threads and threadgroups
+ * in the VM. For example:
+ * <pre>
+ * ThreadGroup-1
+ * +- ThreadGroup-2
+ * | +- ThreadGroup-3
+ * | | \- Thread-1
+ * | +- ThreadGroup-4
+ * | | +- Thread-2
+ * | | \- Thread-3
+ * | \- Thread-4
+ * \- Thread-5
+ * ThreadGroup-5
+ * +- Thread-6
+ *
+ *
+ * (list
+ * (list "ThreadGroup" <tgID> "ThreadGroup-1"
+ * (list
+ * (list "Thread" <tID> "Thread-5" ...))
+ * (list
+ * (list "ThreadGroup" <tgID>
"ThreadGroup-2"
+ * (list
+ * (list "Thread" <tID> "Thread-4"))
+ * (list
+ * (list "ThreadGroup" <tgID>
"ThreadGroup-3"
+ * (list)
+ * (list
+ * (list "Thread" <tID> "Thread-1"
...)))
+ * (list "ThreadGroup" <tgID>
"ThreadGroup-4"
+ * (list)
+ * (list
+ * (list "Thread" <tID> "Thread-2"
...)
+ * (list "Thread" <tID> "Thread-3"
...)))))))
+ * (list "ThreadGroup" <tgID> "ThreadGroup-5"
+ * (list)
+ * (list
+ * (list "Thread" <tID> "Thread-6" ...))))
+ * </pre>
+ * <b>Syntax:</b>
+ * <pre>
+ * (list [{@link Rep#getThreadGroupRep top-level thread group}]*)
+ * </pre>
+ *
+ * @param vm The virtual machine itself
+ * @param store The object store where you should keep references to
+ * the thread ids. For details, see {@link ObjectStore}
+ */
+ public LispForm getAllThreadsInformation() {
+ List l = vm.topLevelThreadGroups();
+
+ String info = "(list ";
+ Iterator it = l.iterator();
+
+ while (it.hasNext()) {
+ info += BR +Rep.getThreadGroupRep((ThreadGroupReference)it.next(), store);
+ }
+
+ info += ")";
+ return new LispForm(info);
+ }
+
+
+ /* spec related functions */
+
+
+ /**
+ * This method is executed whenever a new reference type is prepared.
+ * If any outstanding specs match, they get resolved in the process
+ *
+ * @see EventRequestSpecList#resolve(ReferenceType)
+ */
+ public void resolve(ReferenceType ref) {
+ eventRequestSpecs.resolve(ref);
+ }
+
+ /**
+ * Inform jde on a successful spec resolution
+ */
+ public void informJDEInstallSuccessful(EventRequestSpec spec) {
+ jde.signal(procID, SPEC_RESOLVED, spec.getID());
+ }
+
+ /**
+ * Removes a Spec from the specList, and informs jde.
+ * If there is an error while resolving a spec, indicating that it
+ * cannot be resolved (ie even at a later time when more classes are
+ * prepared), this function is called to remove it from the list, and
+ * inform the jde about this error
+ */
+ public void removeSpecAndInformJDE(EventRequestSpec spec, String problem) {
+ if (spec instanceof BreakpointSpec) {
+ jde.signal(procID, INVALID+BREAK, new LispForm(spec.getID()
+ +" \""+problem+"\""));
+ } else if (spec instanceof WatchpointSpec) {
+ jde.signal(procID, INVALID+WATCH, new LispForm(spec.getID()
+ +" \""+problem+"\""));
+ } else if (spec instanceof ExceptionSpec) {
+ jde.signal(procID, INVALID+TRACE_EXCEPTIONS,
+ new LispForm(spec.getID()+" \""+problem+"\""));
+ }
+ eventRequestSpecs.delete(spec);
+ }
+
+ public EventRequestSpecList getEventRequestSpecs() {
+ return eventRequestSpecs;
+ }
+
+ public DebuggeeSIO getSIO() {
+ return debuggeeSIO;
+ }
+
+
+ /********************************************************************
+ * FIELDS *
+ ********************************************************************/
+
+ /** The ID that uniquely identifies this process in jdebug. */
+ final Integer procID;
+
+ /**
+ * The {@link EventHandler} manages the events received from the
+ * debugee vm
+ */
+ EventHandler eventHandler;
+
+ /** The virtual machine that is running this application. */
+ VirtualMachine vm;
+
+ /**
+ * {@link jde.debugger.spec.EventRequestSpecList} is responsible for
+ * keeping track of the events that the user is interested in. To do
+ * this, it maintains a list of "eventRequestSpec"s.
+ *
+ * @see jde.debugger.spec.EventRequestSpecList
+ * @see jde.debugger.spec.EventRequestSpec
+ */
+ EventRequestSpecList eventRequestSpecs;
+
+
+ /**
+ * A store of all the objects jde knows about.
+ * @see ObjectStore
+ */
+ ObjectStore store;
+
+ /**
+ * Some classes require a unique ID with which to refer to objects
+ * they are tracking: for instance eventRequestSpecs, which need a spec
+ * ID with which to identify the specs, and identifiableSpecRequests
+ * (in ProcessCommands)
+ * <p>
+ * This variable keeps a monotonically increasing count, and can be
+ * used to generate a new id, using {@link #generateObjectID}
+ */
+ private long objIdCounter = 0;
+
+ /**
+ * keeps track of the state of the application: exceptions/error messages
+ * will not be raised if we're shutting down.
+ */
+ private boolean shuttingDown = false;
+ public boolean isShuttingDown() { return shuttingDown; }
+
+ DebuggeeSIO debuggeeSIO;
+
+ ProcessRegistry procRegistry = ProcessRegistry.getRegistry();
+ JDE jde = JDE.getJDE();
+
+} // Process
+
+
+/*
+ * $Log: DebuggeeProcess.java,v $
+ * Revision 1.1 2001/03/24 05:33:17 paulk
+ * Initial version.
+ *
+ *
+ */
+
+
+// End of DebuggeeProcess.java
Index: xemacs-packages/jde/java/src/jde/debugger/DebuggeeSIO.java
===================================================================
RCS file: DebuggeeSIO.java
diff -N DebuggeeSIO.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ DebuggeeSIO.java Tue Aug 14 22:27:46 2001
@@ -0,0 +1,364 @@
+package jde.debugger;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.BufferedReader;
+import java.net.Socket;
+import java.io.BufferedWriter;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.ServerSocket;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.InterruptedIOException;
+
+/**
+ * DebuggeeSIO.java
+ *
+ *
+ * Created: Sun Feb 18 01:24:09 2001
+ *
+ * @author <a href="mailto: "</a>
+ * @version
+ */
+
+public class DebuggeeSIO implements Protocol {
+
+ public DebuggeeSIO (DebuggeeProcess proc){
+ this.proc = proc;
+ procID = proc.getId();
+ }
+
+ /**
+ * Launches a thread to connect the Emacs standard I/O buffer
+ * for the current process to the standard I/O of the process.
+ *
+ * <p>
+ * This method creates a socket for the standard I/O connection.
+ * The thread waits for Emacs to connect to the standard I/O socket.
+ *
+ * @return Address of standard I/O socket.
+ * @exception JDEException if an error occurs
+ */
+ public int initConnect(final Integer cmdId) throws JDEException {
+
+ jde.signal(procID, MESSAGE, "initSIOConnect: starting standard I/O
handshake.");
+
+ ServerSocket ss = null;
+ try {
+ ss = new ServerSocket(0);
+ } catch (IOException ex) {
+ throw new JDEException("Unable to create a server socket");
+ }
+
+ final ServerSocket sstmp = ss;
+ final int port = ss.getLocalPort();
+
+ standardIOConnectThread = new Thread("Standard I/O Thread for App
#"+procID) {
+ public void run() {
+ try {
+ sstmp.setSoTimeout(15000);
+
+ // Note!!! Added to solve initial hang up problem
+ jde.signalCommandResult(procID, cmdId, new Integer(port));
+
+ jde.signal(procID, MESSAGE, "Debugger waiting for Emacs to connect to app SIO
port " +
+ port + ".");
+
+ sioSocket = sstmp.accept();
+ sstmp.close();
+ initTransport();
+ } catch (IOException ex) {
+ jde.signal(procID, ERROR, "Gave up waiting for Emacs to connect to SIO port:
" + port);
+ // proc.shutdown();
+ } catch (SecurityException ex1) {
+ jde.signal(procID, ERROR, "Security exception occurred while connecting to app
SIO port " +
+ port);
+ }
+ }
+ };
+
+ jde.signal(procID, MESSAGE, "initSIOConnect: starting SIO connect
thread.");
+ standardIOConnectThread.start();
+ return port;
+
+ }
+
+ /**
+ * Describe <code>initTransport</code> method here.
+ *
+ */
+ public void initTransport() {
+
+ jde.signal(procID, MESSAGE, "Debugger connected to standard I/O
socket.");
+
+
+ final Process process = proc.getVM().process();
+ standardInputProcessor = new StandardInputProcessor(process.getOutputStream());
+ standardInputProcessor.start();
+
+ standardOutputWriter = new StandardOutputWriter(sioSocket);
+ standardOutputWriter.println("*** Process Standard I/O ***");
+
+ standardOutputProcessor = new StandardOutputProcessor(process.getInputStream());
+ standardOutputProcessor.start();
+
+ standardErrorProcessor = new StandardErrorProcessor(process.getErrorStream());
+ standardErrorProcessor.start();
+
+ }
+
+ public void shutdown() {
+
+ try {
+ sioSocket.close();
+ } catch (IOException e) {
+
+ } // end of try-catch
+
+ }
+
+ /**
+ * Reads standard input from Emacs and forwards it to the application.
+ *
+ * @author Paul Kinnucan <paulk(a)mathworks.com>
+ * @version 1.0
+ * @since 1.0
+ * @see Thread
+ */
+ private class StandardInputProcessor extends Thread {
+
+ public StandardInputProcessor(final OutputStream toVmStream) {
+ super("Input Processor for App #"+procID);
+
+ toVM = new PrintStream(toVmStream, true);
+
+ try {
+ fromEmacs =
+ new BufferedReader(new InputStreamReader(sioSocket.getInputStream()));
+ }
+ catch (IOException ex1) {
+ jde.signal(procID, ERROR, "Could not get standard input stream from
Emacs.");
+ }
+
+ // setPriority(Thread.MAX_PRIORITY-1);
+
+ }
+
+ public void run() {
+
+ if (fromEmacs == null) return;
+
+ try {
+ String line;
+ while ((line = fromEmacs.readLine()) != null) {
+ toVM.println(line);
+ toVM.flush();
+ }
+
+ if (!proc.isShuttingDown()) {
+ try {
+ // sioSocket.close();
+ jde.signal(procID, MESSAGE, "Process closed its standard input.");
+ } catch (Exception ex) {
+ jde.signal(procID, MESSAGE, "Couldn't close socket to standard
input.");
+ }
+ }
+
+ } catch (IOException ex) {
+ if (!proc.isShuttingDown()) {
+ try {
+ // sioSocket.close();
+ jde.signal(procID, ERROR, "Input error; application I/O closed");
+ } catch (Exception e) {
+ jde.signal(procID, ERROR, "Input error; couldn't close application
I/O");
+ }
+ }
+ }
+ }
+
+ PrintStream toVM;
+ BufferedReader fromEmacs;
+
+ }
+
+
+ /**
+ * Writes a line to the socket connected to the
+ * standard I/O buffer maintained by Emacs for this
+ * application.
+ *
+ * <p>This class is used by the StandardOutputProcessor
+ * and StandardErrorProcessor to forward the application's
+ * standard ouput and error output to Emacs.
+ *
+ * @author "" <paulk(a)mathworks.com>
+ * @version 1.0
+ * @since 1.0
+ */
+ private class StandardOutputWriter {
+
+ public StandardOutputWriter(Socket sioSocket) {
+ if (sioSocket == null) {
+ jde.signal(procID, ERROR, "Could not transport app output. " +
+ "Transport socket does not exist.");
+ return;
+ }
+
+ OutputStream toEmacsStream;
+
+ try {
+ toEmacsStream = sioSocket.getOutputStream();
+ if (toEmacsStream == null) {
+ jde.signal(procID, ERROR, "Could not transport app output. Transport socket
closed.");
+ return;
+ }
+ }
+ catch (IOException ex1) {
+ jde.signal(procID, ERROR, "Could not transport app output. Transport socket
closed.");
+ return;
+ }
+
+ toEmacs = new BufferedWriter(new OutputStreamWriter(toEmacsStream));
+ }
+
+ public void write(char[] cbuf, int len) {
+ if (toEmacs != null) {
+ try {
+ toEmacs.write(cbuf, 0, len);
+ toEmacs.flush();
+ }
+ catch (IOException ex1) {
+ jde.signal(procID, ERROR, "I/O error: cannot write process output to
Emacs.");
+ }
+ }
+ }
+
+ public void println(String line) {
+ try {
+ toEmacs.write(line);
+ toEmacs.newLine();
+ } catch (IOException e) {
+ jde.signal(procID, ERROR, "I/O error: cannot write process output to
Emacs.");
+ } // end of try-catch
+
+ }
+
+ BufferedWriter toEmacs;
+ }
+
+
+ /**
+ * Forwards the application's standard output to Emacs.
+ *
+ * @author Paul Kinnucan <paulk(a)mathworks.com>
+ * @version 1.0
+ * @since 1.0
+ * @see Thread
+ */
+ private class StandardOutputProcessor extends Thread {
+
+ public StandardOutputProcessor(InputStream fromVMStream) {
+ fromVM = new BufferedReader(new InputStreamReader(fromVMStream));
+ setPriority(Thread.MAX_PRIORITY-1);
+ }
+
+ public void run() {
+
+ String line;
+
+ try {
+ char[] cbuf = new char[256];
+ int len;
+ while ((len = fromVM.read(cbuf, 0, 256)) != -1) {
+ synchronized (standardOutputWriter) {
+ if (standardOutputWriter != null) {
+ standardOutputWriter.write(cbuf, len);
+ } // end of if ()
+ }
+ }
+ }
+ catch (IOException ex) {
+ }
+
+ if (!proc.isShuttingDown()) {
+ try {
+ // sioSocket.close();
+ jde.signal(procID, MESSAGE, "Closed transport for application's standard
output.");
+ } catch (Exception ex) {
+ jde.signal(procID, ERROR, "Could not close application standard output
transport.");
+ }
+ }
+ }
+
+ BufferedReader fromVM;
+
+ }
+
+
+ /**
+ * Forwards the application's error output to Emacs.
+ *
+ * @author Paulk Kinnucan <paulk(a)mathworks.com>
+ * @version 1.0
+ * @since 1.0
+ * @see Thread
+ */
+ private class StandardErrorProcessor extends Thread {
+
+ public StandardErrorProcessor(InputStream fromVMStream) {
+ super("Standard Error Processor for App #" + procID);
+ fromVM = new BufferedReader(new InputStreamReader(fromVMStream));
+ setPriority(Thread.MAX_PRIORITY-1);
+ }
+
+ public void run() {
+
+ String line;
+
+ try {
+ char[] cbuf = new char[256];
+ int len;
+ while ((len = fromVM.read(cbuf, 0, 256)) != -1) {
+ synchronized (standardOutputWriter) {
+ if (standardOutputWriter != null) {
+ standardOutputWriter.write(cbuf, len);
+ } // end of if ()
+ }
+ }
+ }
+ catch (IOException ex) {
+ }
+
+ if (!proc.isShuttingDown()) {
+ try {
+ // sioSocket.close();
+ jde.signal(procID, MESSAGE, "Closed transport for application's standard
error output.");
+ } catch (Exception ex) {
+ jde.signal(procID, ERROR, "Could not close application standard error output
transport.");
+ }
+ }
+ }
+
+ BufferedReader fromVM;
+
+ }
+
+ DebuggeeProcess proc;
+
+ Integer procID;
+
+ JDE jde = JDE.getJDE();
+
+ /** Socket connection to do i/o */
+ Socket sioSocket = null;
+
+
+ Thread standardIOConnectThread;
+ StandardInputProcessor standardInputProcessor;
+ StandardOutputProcessor standardOutputProcessor;
+ StandardErrorProcessor standardErrorProcessor;
+ StandardOutputWriter standardOutputWriter;
+
+
+
+}// DebuggeeSIO
Index: xemacs-packages/jde/java/src/jde/debugger/Etc.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/Etc.java,v
retrieving revision 1.1
diff -u -r1.1 Etc.java
--- xemacs-packages/jde/java/src/jde/debugger/Etc.java 2000/08/13 13:36:08 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/Etc.java 2001/08/15 05:27:46
@@ -1,468 +1,468 @@
-
-package jde.debugger;
-
-import jde.debugger.expr.*;
-
-import com.sun.jdi.*;
-import com.sun.jdi.request.*;
-
-import java.util.*;
-
-/**
- * Etc.java
- * <p>
- * random useful utilities
- * <p>
- * Created: Thu Jul 8 13:01:24 1999
- *
- * @author Amit Kumar
- * @since 0.1
- */
-
-public class Etc {
-
- /**
- * dump a particular object, in whatever way seems appropriate
- * @param obj The object to dump
- */
- public static void dump(Object obj) {
- if (obj instanceof Collection) {
- Iterator it = ((Collection)obj).iterator();
- while (it.hasNext()) {
- System.out.println(it.next());
- }
- } else if (obj instanceof Object[]) {
- Object[] k = (Object[])obj;
- for (int i=0; i<k.length; i++)
- dump(k[i]);
- } else {
- System.out.println(obj);
- }
- }
-
-
- /**
- * Safely convert to a Long, raising an appropriate
- * JDENumberFormatException if required
- *
- * @param obj The object to convert. The .toString() is used.
- * @param type The type of long: used in the exception string if required
- * @return the Long, or raises exception.
- */
- public static Long safeGetLong(Object obj, String type)
- throws JDEException {
- try {
- return new Long(obj.toString());
- } catch (NumberFormatException ex) {
- throw new JDENumberFormatException(type);
- }
- }
-
-
- /**
- * Safely convert to an int, raising an appropriate
- * JDENumberFormatException if required
- *
- * @param obj The object to convert. The .toString() is used.
- * @param type The type of int: used in the exception string if required
- * @return the Integer, or raises exception.
- */
- public static int safeGetint(Object obj, String type)
- throws JDEException {
- try {
- return Integer.parseInt(obj.toString());
- } catch (NumberFormatException ex) {
- throw new JDENumberFormatException(type);
- }
- }
-
-
- /**
- * Evaluate an expression, given a context
- * <p>
- * @param expr The expression to evaluate
- * @param frame The stackframe that defines the context
- * @return a {@link Rep#getValueRep(Value, ObjectStore) value}
- */
- public static Value evaluate(String expr, final StackFrame frame)
- throws JDEException {
- // System.out.println(expr);
- try {
- ExpressionParser.GetFrame frameGetter = null;
- frameGetter = new ExpressionParser.GetFrame() {
- public StackFrame get()
- throws IncompatibleThreadStateException {
- return frame;
- }
- };
- return ExpressionParser.evaluate(expr, frame.virtualMachine(),
- frameGetter);
- } catch (NativeMethodException ex) {
- throw new JDEException("Can't access local variables in native
methods");
- } catch (ParseException ex) {
- throw new JDEException(ex.toString());
- } catch (InvocationException ex) {
- throw new JDEException("Exception in expression:
"+ex.exception().referenceType().name());
- } catch (InvalidTypeException ite) {
- throw new JDEException("Expression contains invalid type");
- } catch (IncompatibleThreadStateException itse) {
- throw new JDEException("This expression cannot be evaluated at an arbitrary
location");
- } catch (ClassNotLoadedException tnle) {
- throw new JDEException("A required class for the evaluation hasn't been
loaded");
- }
- }
-
-
- /**
- * Parses the list of arguments for thread information.
- * <pre>
- * on_thread_id threadID
- * on_thread_name "threadName"
- * </pre>
- * Note that the exception is <b>not</b> raised if the tags are
- * not present: only if what follows the tag is incorrect.
- * <p>
- * Commands having this argument will raise events only if the event
- * thread matches the specification. More details in EventHandler.
- * <p>
- * Shortcuts: <u>-tid</u> and <u>-tname</u>
- * <p>
- * @return a Long corresponding to the threadID, or the string
- * "threadName"
- * @exception JDEException If the information cannot be resolved
- */
- public static Object getThreadFromArgs(List args)
- throws JDEException {
-
- String threadArg = null;
- int threadIndex = -1;
- for (int i = 0; i < args.size(); i++) {
- String arg = args.get(i).toString().toLowerCase();
- if (arg.equals("on_thread_id") || arg.equals("on_thread_name")
- || arg.equals("-tid") || arg.equals("-tname")) {
- threadIndex = i;
- threadArg = args.remove(threadIndex).toString();
- break;
- }
- }
- // at this point, either threadArg = null, or on_thread_id/name. in
- // that case, threadIndex should now have the index of the argument
- if (threadArg == null) {
- return null;
- } else {
- if (threadArg.equals("on_thread_id")
- || threadArg.equals("-tid")) {
- if (threadIndex == args.size()) {
- // ie missing argument
- throw new JDEException("Missing argument to 'on_thread_id'");
- } else {
- try {
- return new Long(args.remove(threadIndex).toString());
- } catch (NumberFormatException ex) {
- throw new JDENumberFormatException("'on_thread_id' argument");
- }
- }
- } else if (threadArg.equals("on_thread_name")
- || threadArg.equals("-tname")) {
- if (threadIndex == args.size()) {
- throw new JDEException("Missing argument to 'on_thread_name'");
- } else {
- return args.remove(threadIndex).toString();
- }
- } else {
- throw new JDEException("Should not happen! Contact maintainer");
- }
- }
- }
-
-
- /**
- * Parses the list of arguments for expression information.
- * <pre>
- * if "expression"
- * </pre>
- * Note that the exception is <b>not</b> raised if the tag isn't
- * present: only if what follows the tag is incorrect.
- * <p>
- * When used, the expression is evaluated at the time of the event,
- * and the event passed to jde if the expression evaluates to "true".
- * <p>
- * Shortcut: <u>-e</u>
- * <p>
- * @return string corresponding to the expression
- * @exception JDEException If the information cannot be resolved
- */
- public static String getExprFromArgs(List args)
- throws JDEException {
-
- String exprArg = null;
- int exprIndex = -1;
- for (int i = 0; i < args.size(); i++) {
- String arg = args.get(i).toString().toLowerCase();
- if (arg.equals("if") || arg.equals("-e")) {
- exprIndex = i;
- exprArg = args.remove(exprIndex).toString();
- break;
- }
- }
- // at this point, either exprArg = null, or "if". in
- // that case, exprIndex should now have the index of the argument
- if (exprArg == null) {
- return null;
- } else {
- if (exprArg.equals("if") || exprArg.equals("-e")) {
- if (exprIndex == args.size()) {
- // ie missing argument
- throw new JDEException("Missing argument to 'if'");
- } else {
- return args.remove(exprIndex).toString();
- }
- } else {
- throw new JDEException("Should not happen! Contact maintainer");
- }
- }
- }
-
-
- /**
- * Parses the list of arguments for class filter information.
- * <pre>
- * class_filters "classPatternList"
- * </pre>
- * Note that the exception is <b>not</b> raised if the tag isn't
- * present: only if what follows the tag is incorrect.
- * <p>
- * the classPatternList should be a list of class patterns, using
- * space or comma as delimiter.
- * <p>
- * Shortcut: <u>-cf</u>
- * <p>
- * This constraint is used to add class filters to events. To quote
- * JDI documentation:
- * <p>
- * Restricts the events generated by this request to those whose
- * location is in a class whose name matches a restricted regular
- * expression. Regular expressions are limited to exact matches
- * and patterns that begin with '*' or end with '*'; for example,
- * "*.Foo" or "java.*".
- * <p>
- * @return a List of all the class filters.
- * @exception JDEException If the information cannot be resolved
- */
- public static List getClassFiltersFromArgs(List args)
- throws JDEException {
-
- String filterArg = null;
- int filterIndex = -1;
- for (int i = 0; i < args.size(); i++) {
- String arg = args.get(i).toString().toLowerCase();
- if (arg.equals("class_filters") || arg.equals("-cf")) {
- filterIndex = i;
- filterArg = args.remove(filterIndex).toString();
- break;
- }
- }
- // at this point, either filterArg = null, or "if". in
- // that case, filterIndex should now have the index of the argument
- if (filterArg == null) {
- return null;
- } else {
- if (filterArg.equals("class_filters")
- || filterArg.equals("-cf")) {
- if (filterIndex == args.size()) {
- // ie missing argument
- throw new JDEException("Missing argument to 'class_filters'");
- } else {
- List filters = new ArrayList();
- StringTokenizer tokens = new StringTokenizer(args.remove(filterIndex).toString(),
" \t\n\r\f,");
- while (tokens.hasMoreTokens()) {
- filters.add(tokens.nextToken());
- }
- return filters;
- }
- } else {
- throw new JDEException("Should not happen! Contact maintainer");
- }
- }
- }
-
-
- /**
- * Parses the list of arguments for class exclusion filter information.
- * <pre>
- * class_exclusion_filters "classPatternList"
- * </pre>
- * Note that the exception is <b>not</b> raised if the tag isn't
- * present: only if what follows the tag is incorrect.
- * <p>
- * the classPatternList should be a list of class patterns, using
- * space or comma as delimiter.
- * <p>
- * Shortcut: <u>-cef</u>
- * <p>
- * This is used to add class exclusion filters to events. To quote
- * JDI documentation:
- * <p>
- * Restricts the events generated by this request to those whose
- * location is in a class whose name does <b>not</b> match this
- * restricted
- * regular expression. Regular expressions are limited to exact matches
- * and patterns that begin with '*' or end with '*'; for example,
- * "*.Foo" or "java.*".
- * <p>
- * @return a List of all the class exclusion filters.
- * @exception JDEException If the information cannot be resolved
- */
- public static List getClassExFiltersFromArgs(List args)
- throws JDEException {
-
- String filterArg = null;
- int filterIndex = -1;
- for (int i = 0; i < args.size(); i++) {
- String arg = args.get(i).toString().toLowerCase();
- if (arg.equals("class_exclusion_filters")
- || arg.equals("-cef")) {
- filterIndex = i;
- filterArg = args.remove(filterIndex).toString();
- break;
- }
- }
- // at this point, either filterArg = null, or "if". in
- // that case, filterIndex should now have the index of the argument
- if (filterArg == null) {
- return null;
- } else {
- if (filterArg.equals("class_exclusion_filters")
- || filterArg.equals("-cef")) {
- if (filterIndex == args.size()) {
- // ie missing argument
- throw new JDEException("Missing argument to
'class_exclusion_filters'");
- } else {
- List filters = new ArrayList();
- StringTokenizer tokens = new StringTokenizer(args.remove(filterIndex).toString(),
" \t\n\r\f,");
- while (tokens.hasMoreTokens()) {
- filters.add(tokens.nextToken());
- }
- return filters;
- }
- } else {
- throw new JDEException("Should not happen! Contact maintainer");
- }
- }
- }
-
-
- /**
- * Parses the list of arguments for suspend policy information.
- * <pre>
- * using_suspend_policy policy
- * </pre>
- * Note that the exception is <b>not</b> raised if the tags are
- * not present: only if what follows the tag is incorrect.
- * <p>
- * <i>policy</i> is one of "all", "thread", or
"none". "all" means the
- * entire
- * VM is suspended when the event occurs, "thread" indicates only the
- * thread on which the event occurs is suspended (only for events
- * associated with threads), while "none" means nothing is suspended
- * when the event occurs.
- * <p>
- * Shortcut: <u>-sp</u>
- * <p>
- * @return a valid int indicating the suspend policy
- * @exception JDEException If the information cannot be resolved
- */
- public static int getSuspendPolicyFromArgs(List args)
- throws JDEException {
-
- String suspendPolicyArg = null;
- int suspendPolicyIndex = -1;
- for (int i = 0; i < args.size(); i++) {
- String arg = args.get(i).toString().toLowerCase();
- if (arg.equals("using_suspend_policy") || arg.equals("-sp")) {
- suspendPolicyIndex = i;
- suspendPolicyArg =args.remove(suspendPolicyIndex).toString();
- break;
- }
- }
- // at this point, either suspendPolicyArg = null, or "if". in
- // that case, suspendPolicyIndex should now have the index of the
- // argument
- if (suspendPolicyArg == null) {
- return EventRequest.SUSPEND_ALL;
- } else {
- if (suspendPolicyArg.equals("using_suspend_policy")
- || suspendPolicyArg.equals("-sp")) {
- if (suspendPolicyIndex == args.size()) {
- // ie missing argument
- throw new JDEException("Missing argument to
'using_suspend_policy'");
- } else {
- String policy = args.remove(suspendPolicyIndex).toString().toLowerCase();
- if (policy.equals("all")) {
- return EventRequest.SUSPEND_ALL;
- } else if (policy.equals("thread")) {
- return EventRequest.SUSPEND_EVENT_THREAD;
- } else if (policy.equals("none")) {
- return EventRequest.SUSPEND_NONE;
- } else {
- throw new JDEException("Invalid suspend policy
'"+policy+"'");
- }
-
- }
- } else {
- throw new JDEException("Should not happen! Contact maintainer");
- }
- }
- }
-
-
- /**
- * Parses the list of arguments for object ID information.
- * <pre>
- * if_object_id objectID
- * </pre>
- * Note that the exception is <b>not</b> raised if the tag isn't
- * present: only if what follows the tag is incorrect.
- * <p>
- * Shortcut: <u>-oid</u>
- * <p>
- * @return a Long corresponding to the object ID.
- * @exception JDEException If the information cannot be resolved
- */
- public static Long getObjectIDFromArgs(List args)
- throws JDEException {
-
- String idArg = null;
- int idIndex = -1;
- for (int i = 0; i < args.size(); i++) {
- String arg = args.get(i).toString().toLowerCase();
- if (arg.equals("if_object_id") || arg.equals("-oid")) {
- idIndex = i;
- idArg = args.remove(idIndex).toString();
- break;
- }
- }
- // at this point, either idArg = null, or "if". in
- // that case, idIndex should now have the index of the argument
- if (idArg == null) {
- return null;
- } else {
- if (idArg.equals("if_object_id")
- || idArg.equals("-oid")) {
- if (idIndex == args.size()) {
- // ie missing argument
- throw new JDEException("Missing argument to 'if_object_id'");
- } else {
- try {
- return new Long(args.remove(idIndex).toString());
- } catch (NumberFormatException ex) {
- throw new JDENumberFormatException("'if_object_id' argument");
- }
- }
- } else {
- throw new JDEException("Should not happen! Contact maintainer");
- }
- }
- }
-
-} // Etc
+
+package jde.debugger;
+
+import jde.debugger.expr.*;
+
+import com.sun.jdi.*;
+import com.sun.jdi.request.*;
+
+import java.util.*;
+
+/**
+ * Etc.java
+ * <p>
+ * random useful utilities
+ * <p>
+ * Created: Thu Jul 8 13:01:24 1999
+ *
+ * @author Amit Kumar
+ * @since 0.1
+ */
+
+public class Etc {
+
+ /**
+ * dump a particular object, in whatever way seems appropriate
+ * @param obj The object to dump
+ */
+ public static void dump(Object obj) {
+ if (obj instanceof Collection) {
+ Iterator it = ((Collection)obj).iterator();
+ while (it.hasNext()) {
+ System.out.println(it.next());
+ }
+ } else if (obj instanceof Object[]) {
+ Object[] k = (Object[])obj;
+ for (int i=0; i<k.length; i++)
+ dump(k[i]);
+ } else {
+ System.out.println(obj);
+ }
+ }
+
+
+ /**
+ * Safely convert to a Long, raising an appropriate
+ * JDENumberFormatException if required
+ *
+ * @param obj The object to convert. The .toString() is used.
+ * @param type The type of long: used in the exception string if required
+ * @return the Long, or raises exception.
+ */
+ public static Long safeGetLong(Object obj, String type)
+ throws JDEException {
+ try {
+ return new Long(obj.toString());
+ } catch (NumberFormatException ex) {
+ throw new JDENumberFormatException(type);
+ }
+ }
+
+
+ /**
+ * Safely convert to an int, raising an appropriate
+ * JDENumberFormatException if required
+ *
+ * @param obj The object to convert. The .toString() is used.
+ * @param type The type of int: used in the exception string if required
+ * @return the Integer, or raises exception.
+ */
+ public static int safeGetint(Object obj, String type)
+ throws JDEException {
+ try {
+ return Integer.parseInt(obj.toString());
+ } catch (NumberFormatException ex) {
+ throw new JDENumberFormatException(type);
+ }
+ }
+
+
+ /**
+ * Evaluate an expression, given a context
+ * <p>
+ * @param expr The expression to evaluate
+ * @param frame The stackframe that defines the context
+ * @return a {@link Rep#getValueRep(Value, ObjectStore) value}
+ */
+ public static Value evaluate(String expr, final StackFrame frame)
+ throws JDEException {
+ // System.out.println(expr);
+ try {
+ ExpressionParser.GetFrame frameGetter = null;
+ frameGetter = new ExpressionParser.GetFrame() {
+ public StackFrame get()
+ throws IncompatibleThreadStateException {
+ return frame;
+ }
+ };
+ return ExpressionParser.evaluate(expr, frame.virtualMachine(),
+ frameGetter);
+ } catch (NativeMethodException ex) {
+ throw new JDEException("Can't access local variables in native
methods");
+ } catch (ParseException ex) {
+ throw new JDEException(ex.toString());
+ } catch (InvocationException ex) {
+ throw new JDEException("Exception in expression:
"+ex.exception().referenceType().name());
+ } catch (InvalidTypeException ite) {
+ throw new JDEException("Expression contains invalid type");
+ } catch (IncompatibleThreadStateException itse) {
+ throw new JDEException("This expression cannot be evaluated at an arbitrary
location");
+ } catch (ClassNotLoadedException tnle) {
+ throw new JDEException("A required class for the evaluation hasn't been
loaded");
+ }
+ }
+
+
+ /**
+ * Parses the list of arguments for thread information.
+ * <pre>
+ * on_thread_id threadID
+ * on_thread_name "threadName"
+ * </pre>
+ * Note that the exception is <b>not</b> raised if the tags are
+ * not present: only if what follows the tag is incorrect.
+ * <p>
+ * Commands having this argument will raise events only if the event
+ * thread matches the specification. More details in EventHandler.
+ * <p>
+ * Shortcuts: <u>-tid</u> and <u>-tname</u>
+ * <p>
+ * @return a Long corresponding to the threadID, or the string
+ * "threadName"
+ * @exception JDEException If the information cannot be resolved
+ */
+ public static Object getThreadFromArgs(List args)
+ throws JDEException {
+
+ String threadArg = null;
+ int threadIndex = -1;
+ for (int i = 0; i < args.size(); i++) {
+ String arg = args.get(i).toString().toLowerCase();
+ if (arg.equals("on_thread_id") || arg.equals("on_thread_name")
+ || arg.equals("-tid") || arg.equals("-tname")) {
+ threadIndex = i;
+ threadArg = args.remove(threadIndex).toString();
+ break;
+ }
+ }
+ // at this point, either threadArg = null, or on_thread_id/name. in
+ // that case, threadIndex should now have the index of the argument
+ if (threadArg == null) {
+ return null;
+ } else {
+ if (threadArg.equals("on_thread_id")
+ || threadArg.equals("-tid")) {
+ if (threadIndex == args.size()) {
+ // ie missing argument
+ throw new JDEException("Missing argument to 'on_thread_id'");
+ } else {
+ try {
+ return new Long(args.remove(threadIndex).toString());
+ } catch (NumberFormatException ex) {
+ throw new JDENumberFormatException("'on_thread_id' argument");
+ }
+ }
+ } else if (threadArg.equals("on_thread_name")
+ || threadArg.equals("-tname")) {
+ if (threadIndex == args.size()) {
+ throw new JDEException("Missing argument to 'on_thread_name'");
+ } else {
+ return args.remove(threadIndex).toString();
+ }
+ } else {
+ throw new JDEException("Should not happen! Contact maintainer");
+ }
+ }
+ }
+
+
+ /**
+ * Parses the list of arguments for expression information.
+ * <pre>
+ * if "expression"
+ * </pre>
+ * Note that the exception is <b>not</b> raised if the tag isn't
+ * present: only if what follows the tag is incorrect.
+ * <p>
+ * When used, the expression is evaluated at the time of the event,
+ * and the event passed to jde if the expression evaluates to "true".
+ * <p>
+ * Shortcut: <u>-e</u>
+ * <p>
+ * @return string corresponding to the expression
+ * @exception JDEException If the information cannot be resolved
+ */
+ public static String getExprFromArgs(List args)
+ throws JDEException {
+
+ String exprArg = null;
+ int exprIndex = -1;
+ for (int i = 0; i < args.size(); i++) {
+ String arg = args.get(i).toString().toLowerCase();
+ if (arg.equals("if") || arg.equals("-e")) {
+ exprIndex = i;
+ exprArg = args.remove(exprIndex).toString();
+ break;
+ }
+ }
+ // at this point, either exprArg = null, or "if". in
+ // that case, exprIndex should now have the index of the argument
+ if (exprArg == null) {
+ return null;
+ } else {
+ if (exprArg.equals("if") || exprArg.equals("-e")) {
+ if (exprIndex == args.size()) {
+ // ie missing argument
+ throw new JDEException("Missing argument to 'if'");
+ } else {
+ return args.remove(exprIndex).toString();
+ }
+ } else {
+ throw new JDEException("Should not happen! Contact maintainer");
+ }
+ }
+ }
+
+
+ /**
+ * Parses the list of arguments for class filter information.
+ * <pre>
+ * class_filters "classPatternList"
+ * </pre>
+ * Note that the exception is <b>not</b> raised if the tag isn't
+ * present: only if what follows the tag is incorrect.
+ * <p>
+ * the classPatternList should be a list of class patterns, using
+ * space or comma as delimiter.
+ * <p>
+ * Shortcut: <u>-cf</u>
+ * <p>
+ * This constraint is used to add class filters to events. To quote
+ * JDI documentation:
+ * <p>
+ * Restricts the events generated by this request to those whose
+ * location is in a class whose name matches a restricted regular
+ * expression. Regular expressions are limited to exact matches
+ * and patterns that begin with '*' or end with '*'; for example,
+ * "*.Foo" or "java.*".
+ * <p>
+ * @return a List of all the class filters.
+ * @exception JDEException If the information cannot be resolved
+ */
+ public static List getClassFiltersFromArgs(List args)
+ throws JDEException {
+
+ String filterArg = null;
+ int filterIndex = -1;
+ for (int i = 0; i < args.size(); i++) {
+ String arg = args.get(i).toString().toLowerCase();
+ if (arg.equals("class_filters") || arg.equals("-cf")) {
+ filterIndex = i;
+ filterArg = args.remove(filterIndex).toString();
+ break;
+ }
+ }
+ // at this point, either filterArg = null, or "if". in
+ // that case, filterIndex should now have the index of the argument
+ if (filterArg == null) {
+ return null;
+ } else {
+ if (filterArg.equals("class_filters")
+ || filterArg.equals("-cf")) {
+ if (filterIndex == args.size()) {
+ // ie missing argument
+ throw new JDEException("Missing argument to 'class_filters'");
+ } else {
+ List filters = new ArrayList();
+ StringTokenizer tokens = new StringTokenizer(args.remove(filterIndex).toString(),
" \t\n\r\f,");
+ while (tokens.hasMoreTokens()) {
+ filters.add(tokens.nextToken());
+ }
+ return filters;
+ }
+ } else {
+ throw new JDEException("Should not happen! Contact maintainer");
+ }
+ }
+ }
+
+
+ /**
+ * Parses the list of arguments for class exclusion filter information.
+ * <pre>
+ * class_exclusion_filters "classPatternList"
+ * </pre>
+ * Note that the exception is <b>not</b> raised if the tag isn't
+ * present: only if what follows the tag is incorrect.
+ * <p>
+ * the classPatternList should be a list of class patterns, using
+ * space or comma as delimiter.
+ * <p>
+ * Shortcut: <u>-cef</u>
+ * <p>
+ * This is used to add class exclusion filters to events. To quote
+ * JDI documentation:
+ * <p>
+ * Restricts the events generated by this request to those whose
+ * location is in a class whose name does <b>not</b> match this
+ * restricted
+ * regular expression. Regular expressions are limited to exact matches
+ * and patterns that begin with '*' or end with '*'; for example,
+ * "*.Foo" or "java.*".
+ * <p>
+ * @return a List of all the class exclusion filters.
+ * @exception JDEException If the information cannot be resolved
+ */
+ public static List getClassExFiltersFromArgs(List args)
+ throws JDEException {
+
+ String filterArg = null;
+ int filterIndex = -1;
+ for (int i = 0; i < args.size(); i++) {
+ String arg = args.get(i).toString().toLowerCase();
+ if (arg.equals("class_exclusion_filters")
+ || arg.equals("-cef")) {
+ filterIndex = i;
+ filterArg = args.remove(filterIndex).toString();
+ break;
+ }
+ }
+ // at this point, either filterArg = null, or "if". in
+ // that case, filterIndex should now have the index of the argument
+ if (filterArg == null) {
+ return null;
+ } else {
+ if (filterArg.equals("class_exclusion_filters")
+ || filterArg.equals("-cef")) {
+ if (filterIndex == args.size()) {
+ // ie missing argument
+ throw new JDEException("Missing argument to
'class_exclusion_filters'");
+ } else {
+ List filters = new ArrayList();
+ StringTokenizer tokens = new StringTokenizer(args.remove(filterIndex).toString(),
" \t\n\r\f,");
+ while (tokens.hasMoreTokens()) {
+ filters.add(tokens.nextToken());
+ }
+ return filters;
+ }
+ } else {
+ throw new JDEException("Should not happen! Contact maintainer");
+ }
+ }
+ }
+
+
+ /**
+ * Parses the list of arguments for suspend policy information.
+ * <pre>
+ * using_suspend_policy policy
+ * </pre>
+ * Note that the exception is <b>not</b> raised if the tags are
+ * not present: only if what follows the tag is incorrect.
+ * <p>
+ * <i>policy</i> is one of "all", "thread", or
"none". "all" means the
+ * entire
+ * VM is suspended when the event occurs, "thread" indicates only the
+ * thread on which the event occurs is suspended (only for events
+ * associated with threads), while "none" means nothing is suspended
+ * when the event occurs.
+ * <p>
+ * Shortcut: <u>-sp</u>
+ * <p>
+ * @return a valid int indicating the suspend policy
+ * @exception JDEException If the information cannot be resolved
+ */
+ public static int getSuspendPolicyFromArgs(List args)
+ throws JDEException {
+
+ String suspendPolicyArg = null;
+ int suspendPolicyIndex = -1;
+ for (int i = 0; i < args.size(); i++) {
+ String arg = args.get(i).toString().toLowerCase();
+ if (arg.equals("using_suspend_policy") || arg.equals("-sp")) {
+ suspendPolicyIndex = i;
+ suspendPolicyArg =args.remove(suspendPolicyIndex).toString();
+ break;
+ }
+ }
+ // at this point, either suspendPolicyArg = null, or "if". in
+ // that case, suspendPolicyIndex should now have the index of the
+ // argument
+ if (suspendPolicyArg == null) {
+ return EventRequest.SUSPEND_ALL;
+ } else {
+ if (suspendPolicyArg.equals("using_suspend_policy")
+ || suspendPolicyArg.equals("-sp")) {
+ if (suspendPolicyIndex == args.size()) {
+ // ie missing argument
+ throw new JDEException("Missing argument to
'using_suspend_policy'");
+ } else {
+ String policy = args.remove(suspendPolicyIndex).toString().toLowerCase();
+ if (policy.equals("all")) {
+ return EventRequest.SUSPEND_ALL;
+ } else if (policy.equals("thread")) {
+ return EventRequest.SUSPEND_EVENT_THREAD;
+ } else if (policy.equals("none")) {
+ return EventRequest.SUSPEND_NONE;
+ } else {
+ throw new JDEException("Invalid suspend policy
'"+policy+"'");
+ }
+
+ }
+ } else {
+ throw new JDEException("Should not happen! Contact maintainer");
+ }
+ }
+ }
+
+
+ /**
+ * Parses the list of arguments for object ID information.
+ * <pre>
+ * if_object_id objectID
+ * </pre>
+ * Note that the exception is <b>not</b> raised if the tag isn't
+ * present: only if what follows the tag is incorrect.
+ * <p>
+ * Shortcut: <u>-oid</u>
+ * <p>
+ * @return a Long corresponding to the object ID.
+ * @exception JDEException If the information cannot be resolved
+ */
+ public static Long getObjectIDFromArgs(List args)
+ throws JDEException {
+
+ String idArg = null;
+ int idIndex = -1;
+ for (int i = 0; i < args.size(); i++) {
+ String arg = args.get(i).toString().toLowerCase();
+ if (arg.equals("if_object_id") || arg.equals("-oid")) {
+ idIndex = i;
+ idArg = args.remove(idIndex).toString();
+ break;
+ }
+ }
+ // at this point, either idArg = null, or "if". in
+ // that case, idIndex should now have the index of the argument
+ if (idArg == null) {
+ return null;
+ } else {
+ if (idArg.equals("if_object_id")
+ || idArg.equals("-oid")) {
+ if (idIndex == args.size()) {
+ // ie missing argument
+ throw new JDEException("Missing argument to 'if_object_id'");
+ } else {
+ try {
+ return new Long(args.remove(idIndex).toString());
+ } catch (NumberFormatException ex) {
+ throw new JDENumberFormatException("'if_object_id' argument");
+ }
+ }
+ } else {
+ throw new JDEException("Should not happen! Contact maintainer");
+ }
+ }
+ }
+
+} // Etc
Index: xemacs-packages/jde/java/src/jde/debugger/EventHandler.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/EventHandler.java,v
retrieving revision 1.3
diff -u -r1.3 EventHandler.java
--- xemacs-packages/jde/java/src/jde/debugger/EventHandler.java 2001/02/12 06:34:15 1.3
+++ xemacs-packages/jde/java/src/jde/debugger/EventHandler.java 2001/08/15 05:27:46
@@ -9,6 +9,7 @@
import com.sun.jdi.event.*;
import com.sun.jdi.request.*;
import com.sun.jdi.connect.*;
+import jde.debugger.LispForm;
/**
* EventHandler.java
@@ -29,12 +30,14 @@
/** Are we connected to the VM? */
boolean connected = true;
- /** The application for which we're the event handler */
- final Application app;
+ /** The process for which we're the event handler */
+ final DebuggeeProcess proc;
- /** The ID of the application */
- final Integer my_id;
+ /** The ID of the process */
+ final Integer procID;
+ final JDE jde = JDE.getJDE();
+
/**
* My own thread. Used when we want to suspend ourselves or some such
* weird stuff :-)
@@ -50,11 +53,11 @@
*/
boolean resumeApp;
- public EventHandler(Application app) {
+ public EventHandler(DebuggeeProcess proc) {
/* the q gets all the events from the vm */
- this.app = app;
- this.my_id = app.getId();
- this.thread = new Thread(this, "Event Handler for App #"+my_id);
+ this.proc = proc;
+ this.procID = proc.getId();
+ this.thread = new Thread(this, "Event Handler for App #"+procID);
this.thread.start();
}
@@ -129,7 +132,7 @@
* </ul>
*/
public void run() {
- EventQueue queue = app.getEventQueue();
+ EventQueue queue = proc.getEventQueue();
/* only need to run while we're connected */
while (connected) {
try {
@@ -195,7 +198,7 @@
eventSetString += " nil";
} else {
eventSetString += BR +
- Rep.getThreadRep(eventThread, app.getStore());
+ Rep.getThreadRep(eventThread, proc.getStore());
}
Iterator iter = events.iterator();
@@ -204,7 +207,7 @@
}
// finally, we send the events to The Man. (or woman...)
- app.signal(EVENTSET, new LispForm(eventSetString));
+ jde.signal(procID, EVENTSET, new LispForm(eventSetString));
} catch (InterruptedException ex) {
// Debug.printIf(ex);
@@ -281,7 +284,7 @@
private void handleDisconnectedException() {
// disconnected while handling some other event. flush queue
// and deal with disconnectEvent and deathEvents
- EventQueue queue = app.getEventQueue();
+ EventQueue queue = proc.getEventQueue();
while (connected) {
try {
EventSet eventSet = queue.remove();
@@ -387,7 +390,7 @@
}
} else if (thread instanceof String) {
ThreadReference tRef =
- ThreadCommands.getThread(app.getVM(), thread.toString());
+ proc.getThread(thread.toString());
ThreadReference t = getEventThread(event);
if (t.equals(tRef)) {
@@ -607,10 +610,10 @@
String fieldValueString =
Rep.getFieldValueRep(event.field(), event.valueCurrent(),
- app.getStore()).toString();
+ proc.getStore()).toString();
String objectString = Rep.getObjectRep(event.object(),
- app.getStore()).toString();
+ proc.getStore()).toString();
resumeApp &= false;
return new LispForm("(list '"+EVENT_WATCHPOINT_HIT
@@ -666,7 +669,7 @@
+EVENT_EXCEPTION
+" "+specID
+ BR +Rep.getObjectRep(event.exception(),
- app.getStore())
+ proc.getStore())
+ BR +threadString+")");
}
@@ -720,7 +723,7 @@
return new LispForm("(list '"
+ EVENT_THREAD_START
+ BR +Rep.getThreadRep(event.thread(),
- app.getStore())
+ proc.getStore())
+")");
}
@@ -738,7 +741,7 @@
return new LispForm("(list '"
+ EVENT_THREAD_DEATH
+ BR +Rep.getThreadRep(event.thread(),
- app.getStore())
+ proc.getStore())
+")");
}
@@ -759,7 +762,7 @@
* </pre>
*/
private LispForm classPrepareEvent(ClassPrepareEvent event) {
- app.resolve(event.referenceType());
+ proc.resolve(event.referenceType());
// now find out if this event was also requested by the user.
// it will be, if the "default" property does NOT exists in the
// corresponding request.
@@ -802,7 +805,7 @@
private LispForm vmDisconnectEvent(Event event) {
connected = false;
resumeApp &= true;
- app.shutdown();
+ proc.shutdown();
return new LispForm("(list '"+EVENT_VM_DISCONNECT+")");
}
Index: xemacs-packages/jde/java/src/jde/debugger/JDE.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/JDE.java,v
retrieving revision 1.1
diff -u -r1.1 JDE.java
--- xemacs-packages/jde/java/src/jde/debugger/JDE.java 2000/08/13 13:36:08 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/JDE.java 2001/08/15 05:27:46
@@ -1,676 +1,179 @@
-/*
- * $Revision: 1.1 $
- *
- * Copyright (C) 1999 Free Software Foundation, Inc.
- *
- * Author: Amit Kumar <amit(a)usc.edu>
- * Maintainer: Paul Kinnucan <paulk(a)mathworks.com>
- *
- * Sun Microsystems, Inc. sponsored initial development of this code.
- *
- * This code is distributed with the Java Development Environment for
- * Emacs (JDE). The latest version of the JDE is available at
- *
http://sunsite.auc.dk/jde/.
- *
- * This code is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * This code is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this code; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-package jde.debugger;
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-
-/**
- * JDE.java
- * <p>
- * This class is the main link between jdebug and jde. It has methods that
- * allow communication between jde and jdebug, as well as a store
- * of all the applications currently active. Commands that have valid app_ids
- * interpret get passed on to the corresponding applications.
- * If not, corresponding errors are sent on the
- * pipe.
- * <p>
- * Look {@link Protocol here} for the command/response formats, and
- * {@link EventHandler here} for information about handling of events,
- * including event set formats
- * <p>
- * Note that for each command sent by jde, there *has* to be a reply. (either
- * a result or an error) For example, in
- * case we're launching a thread, we should return true, even if the thread
- * might bomb later on.
- * <p>
- *
- * <b> Handshake </b>
- *
- * Since JDI supports different kinds of connections, (for
- * example, it being possible to "launch" a debugger once an
- * uncaught exception is raised), we should probably have some
- * sort of a handshake mechanism preceding a debugging session,
- * for each new vm.
- * <p>
- * For example, if the debugee vm is already running, during the
- * handshake we might specify its address. On the other hand, if
- * we want the debugger to *launch* a vm, we can do that during
- * the handshake.
- * <p>
- * For our purposes, we will only support "launch" in the
- * beginning.
- * <p>
- * The purpose of the handshake is to establish the
- * debugee_vm_id <-> debugee VM binding. It is guaranteed that no
- * events will be raised from jdebug for a debugee VM for which
- * the handshake is not yet complete.
- * <p>
- *
- * Created: Wed Jul 7 20:49:16 1999
- *
- * @author Amit Kumar
- * @since 0.1
- */
-
-public class JDE extends Thread implements Protocol {
-
- BufferedReader in;
- PrintWriter out;
-
- /**
- * All the active applications are kept in a map of
- * <code>app_id -> app</code>.
- * The app_id uniquely idenifies the application: it's the duty
- * of the app to nicely remove itself from the map once it's finished
- */
- Map applications;
-
- /**
- * Each command has a command id associated with it, that is used by
- * jde, to match with the corresponding result/error. jdebug maintains
- * the pending command ids in this collection (as does {@link
- * Application}, see
- * {@link Application#pendingCommands}),
- * and removes
- * them once the command processing is over.<br>
- * Hence, the command id can actually be reused.
- * <p>
- * Note that in case the command is actually meant for one of the apps
- * (ie as ascertained by matching the app_id), the id isn't stored in
- * our Collection, but the applications. This means that, in fact, it
- * is the tuple (app_id, cmd_id) that need be unique (assuming that a
- * "general" command has a app_id of -1
- */
- private Collection pendingCommands;
-
- /**
- * The ID of jdebug. This is used by jde when issuing commands that
- * are not specific to any particular vm, for instance, 'quit', or
- * the command used to launch new application/vms.<br>
- * It is the Integer -1.
- */
- public static final Integer my_id = new Integer(-1);
-
-
- public JDE() throws IOException {
-
- //out = new PrintWriter(new BufferedWriter(new
OutputStreamWriter(socket.getOutputStream())));
- //in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
- out = new PrintWriter(System.out);
- in = new BufferedReader(new InputStreamReader(System.in));
-
- applications = Collections.synchronizedMap(new HashMap());
- pendingCommands = Collections.synchronizedSet(new HashSet());
- }
-
- /**
- * Sets the syntax of the input stream. We want the input to be broken
- * into lines, with whitespaces separating tokens
- */
- private void setSyntax(StreamTokenizer st) {
- /*
- st.resetSyntax();
- st.eolIsSignificant(true);
- st.quoteChar('"');
- st.whitespaceChars('\u0000', '\u0020');
- st.wordChars('.', '.'); // for class names and all
- st.wordChars('-', '-'); // for negative numbers...
- st.wordChars('0', '9');
- st.wordChars('A', 'Z');
- st.wordChars('a', 'z');
- st.wordChars('\u00A0', '\u00FF');
- */
- st.resetSyntax();
- st.eolIsSignificant(true);
- st.whitespaceChars('\u0000', '\u0020');
- st.wordChars('\u0021', '\u00ff');
- st.quoteChar('"');
- }
-
- /**
- * JDE is a thread: it reads a line at a time and executes the command
- * therein
- */
- public void run() {
-
- // read till we get an error
- try {
- StreamTokenizer st = new StreamTokenizer(in);
- setSyntax(st);
-
- int ttype;
-
- // read a line at a time
- ttype = st.nextToken();
- while (ttype != StreamTokenizer.TT_EOF) {
-
- try {
-
- List commandLine = new ArrayList();
- while(ttype != StreamTokenizer.TT_EOL) {
-
- if (ttype == StreamTokenizer.TT_EOF) {
- throw new IOException("I/O EOF occured");
- } else if (ttype == StreamTokenizer.TT_WORD) {
- //Debug.printIf(Debug.JDE_PIPE, "word "+st.sval);
- commandLine.add(st.sval);
- } else if ((ttype == '"') || (ttype == '\'')) {
- //Debug.printIf(Debug.JDE_PIPE, "phrase "+st.sval);
- commandLine.add(st.sval);
- } else {
- // should be a char. see if we need to get ttype
- // and convert it into a string instead of using
- // tostring
- //Debug.printIf(Debug.JDE_PIPE, "char "+st);
- commandLine.add(String.valueOf((char)ttype));
- }
-
- ttype = st.nextToken();
-
- } // finished reading a line, or eof raised.
-
- // if (Debug.set(Debug.JDE_PIPE)) Etc.dump(commandLine);
-
- // we have the complete command. since we're really a
- // private interface, we assume that the line is really
- // well formed. if not, we don't raise an exception,
- // just
- // warn the jde side that we didn't understand the last
- // command. just to be consistent, we will *not* send
- // back
- // the app_id and cmd_id back (they will both be -1)
- // when
- // we complain about malformed commands, even if
- // one/both
- // *were* available to us (ie were parsed correctly)
-
- if (commandLine.size() < 3) {
- ttype = st.nextToken();
- // don't get irritated by simple newlines
- if (commandLine.size() > 1)
- signalCommandError(my_id, new Integer(-1), "Malformed command");
- continue;
- }
-
- final Integer app_id =
- Integer.valueOf(commandLine.get(0).toString());
- final Integer cmd_id =
- Integer.valueOf(commandLine.get(1).toString());
- final String command =
- commandLine.get(2).toString().toLowerCase();
- final List arguments =
- commandLine.subList(3, commandLine.size());
-
- // by now all of the above variables are properly set
-
- Thread thread = new
- Thread("Executing ("+app_id+","+cmd_id+")") {
- public void run() {
- // a general command has app_id = -1
- if (app_id.equals(my_id)) {
- handleGeneralCommand
- (cmd_id, command, arguments);
- }
- // otherwise we find which app is targetted
- else {
- handleAppCommand
- (app_id, cmd_id, command, arguments);
- }
- }
- };
- thread.start();
-
- } catch (IOException ex) {
- // if there is an ioexception, the connection was
- // broken. fall through the loop, raising another
- // exception as the outer loop tries to read a token
- // Debug.printIf(ex);
- } catch (Exception ex) {
- // any other exception means the command wasn't good.
- // Debug.printIf(ex);
- // since we cannot be sure of app_id and cmd_id being
- // good, we send back a general error.
- signalCommandError(my_id, new Integer(-1), "Malformed command:
"+ex.toString());
- }
-
- // read another token
- ttype = st.nextToken();
-
- } // finished reading all input
-
- } catch (IOException ex) {
- // Debug.printIf(ex);
- } finally {
- // close down gracefully, shutting down all VMs
- // jdeexceptions might be raised: ignore them.
- try {
- shutdown();
- } catch (Exception ex) {
- // do nothing
- }
- }
- }
-
- /**
- * Commands that are not meant for any particular app/vm are funneled
- * to this method.
- *
- * @param cmd_id The ID of the command sent. The app_id was -1
- * @param command The command itself
- * @param arguments And the arguments of the command
- */
- private void handleGeneralCommand(Integer cmd_id, String command,
- List arguments) {
- synchronized (pendingCommands) {
- // see if there already is a command with this cmd_id. this
- // should never happen.
- if (pendingCommands.contains(cmd_id)) {
- signalCommandError(my_id, new Integer(-1), "Duplicate cmd_id
'"+cmd_id+"'");
- return;
- }
-
- // if not, add to pending commands.
- pendingCommands.add(cmd_id);
- }
-
- // any parse errors will raise an exception
- try {
- // a new app is to be launched
- if (command.equals(LAUNCH)) {
- doLaunch(cmd_id, arguments);
- }
- // attach to existing app
- else if (command.equals(ATTACH_SOCKET)) {
- doAttach(command, cmd_id, arguments);
- }
- // attach to existing app
- else if (command.equals(ATTACH_SHMEM)) {
- doAttach(command, cmd_id, arguments);
- }
- // listen to existing app
- else if (command.equals(LISTEN_SOCKET)) {
- doListen(command, cmd_id, arguments);
- }
- // listen to existing app
- else if (command.equals(LISTEN_SHMEM)) {
- doListen(command, cmd_id, arguments);
- }
- // quitting jdebug
- else if (command.equals(QUIT) || command.equals(EXIT)) {
- doQuit(cmd_id, arguments);
- }
- // if it's not supported
- else {
- signalCommandError(my_id, cmd_id, "'"+command+"' is not
supported");
- }
- } catch (JDEException ex) {
- Debug.printIf(ex);
- // a jde exception was raised. the kind of error is already
- // in there.
- signalCommandError(my_id, cmd_id, ex.getMessage());
- return;
- } catch (Exception ex) {
- Debug.printIf(ex);
- signalCommandError(my_id, cmd_id, "Unspecified error: "+ex.toString());
- return;
- } finally {
- synchronized (pendingCommands) {
- // once the command is done, remove it from the pending
- // commands list. if an exception is raised, it should be
- // removed from the pending list there.
- pendingCommands.remove(cmd_id);
- }
- }
- }
-
- /**
- * Commands received from JDE that don't have app_id == -1 get
- * funneled to handleAppCommand. We have to check if the app_id is
- * valid and if it corresponds to a valid app. If not, we send a
- * general error message back to JDE, with my_id=1 and cmd_id=-1
- * since app_id is not valid anyway
- *
- * @param app_id The ID of the application for which the command is
- * intended
- * @param cmd_id ID of the command
- * @param command The command
- * @param arguments And a list of the arguments of the command
- */
- private void handleAppCommand(Integer app_id, Integer cmd_id,
- String command, List arguments) {
- Application app;
-
- synchronized(applications) {
- // this app id should be valid. register using a connector
- // earlier
- if (!applications.containsKey(app_id)) {
- signalCommandError(my_id, cmd_id, "Application ID '"+app_id+"'
does not exist");
- return;
- }
- }
- synchronized(applications) {
- // also, it should be a valid application
- if ((app = (Application)applications.get(app_id)) == null) {
- signalCommandError(my_id, cmd_id, "Application ID '"+app_id+"'
does not correspond to a valid application");
- }
- }
- // at this point, we call the handleCommand function of the
- // app to take care of actions.
- app.handleCommand(cmd_id, command, arguments);
- }
-
- /*
- * a note on convention: any replies sent back will either by in
- * the handleXCommand functions, or in the doX functions. arbitrary
- * replies (ie from any function) to jde should be avoided
- */
-
-
-
- /**
- * This method is actually called by doLaunch, doAttach, and doListen
- * and does all the ugly work. The 3 above are separated for
- * documentation purposes
- * <p>
- * <font size=-4>The real reason is that I realised too late that they
- * share
- * the same code :-(</font>
- */
- private void initApplication(String category, Integer cmd_id, List args)
- throws JDEException {
-
- if (args.size() < 1)
- throw new JDEException("Missing application ID");
-
- // the app id with which it will be known.
- // note that we remove the arguments as we consume them from the
- // list.
- Integer app_id =
- new Integer(Etc.safeGetint(args.remove(0), "application ID"));
-
- // the app id cannot be same as my id
- if (app_id.equals(my_id)) {
- throw new JDEException("Invalid Application ID");
- }
- // an app using this id is already present!
- // XXX make sure you dispose the id once done with the app
- synchronized (applications) {
- if (applications.containsKey(app_id)) {
- throw new JDEException("Application ID is duplicate");
- }
- }
- // new app. initialize stuff
- // note that new App might raise a jdeexception.
- Application app = new Application(this, app_id);
- int port = app.initialize(category, args);
- synchronized (applications) {
- if (applications.containsKey(app_id)) {
- app.shutdown();
- throw new JDEException("A new application with the same ID exists: things will go
miserably wrong!");
- }
- applications.put(app_id, app);
- }
- signalCommandResult(my_id, cmd_id, new Integer(port));
- }
-
-
- /**
- * 'launch' command. Launches a new application.
- * <p>
- *
- * <b>Syntax:</b>
- * <pre>
- * launch app_id [-use_executable javax] classname [args]
- * </pre>
- *
- * <b>Comments:</b>
- * <ul>
- * <li> this command establishes the existence of a unique
- * "stream" of data between jde and jdebug, indexed by
- * app_id, and referring to a particular vm.
- * <li> other commands might be ... attach app_id [args]
- * ... where args specify the "location" of the running
- * VM. In that case, jdebug might try to connect to the
- * "location", and return an error if unable to do so.
- * </ul>
- */
- private void doLaunch(Integer cmd_id, List args)
- throws JDEException {
- initApplication(LAUNCH, cmd_id, args);
- }
-
- /**
- * 'attach_socket' and 'attach_shmem' commands. Attaches to an
already
- * running application through a socket/shared memory.
- * <p>
- *
- * <b>Syntax:</b>
- * <pre>
- * attach_socket app_id -port p_value [-host h_value]
- * attach_shmem app_id name
- * </pre>
- *
- * <b>Comments:</b>
- * <ul>
- * <li> Like launch, except here we're attaching to a debugee vm that
- * has, of course, been launched with the "right" parameters. See the
- * Connection and Invocation details document of JPDA about this.
- * </ul>
- */
- private void doAttach(String type, Integer cmd_id, List args)
- throws JDEException {
- initApplication(type, cmd_id, args);
- }
-
-
- /**
- * 'listen_socket' and 'listen_shmem' commands. Listenes for an
- * incoming debuggee connection
- * <p>
- *
- * <b>Syntax:</b>
- * <pre>
- * listen_socket app_id port
- * listen_shmem app_id name
- * </pre>
- */
- private void doListen(String type, Integer cmd_id, List args)
- throws JDEException {
- initApplication(type, cmd_id, args);
- }
-
-
- /**
- * 'quit' command.
- * <p>
- *
- * <b>Syntax:</b>
- * <pre>
- * quit
- * </pre>
- */
- private void doQuit(Integer cmd_id, List arguments)
- throws JDEException {
- try {
- shutdown();
- } catch (Exception ex) {
- // do nothing
- }
- signalCommandResult(my_id, cmd_id);
- System.exit(0);
- }
-
- /**
- * called by {@link Application#shutdown}
- * to remove it's own entry from
- * the applications collection here
- */
- public void removeApplication(Integer app_id) {
- synchronized (applications) {
- applications.remove(app_id);
- }
- }
-
- /**
- * Shuts down all the applications prior to exiting
- */
- private void shutdown()
- throws JDEException {
- // run the "shutdown" function for all the apps currently being
- // debugged.
- synchronized (applications) {
- Iterator iterator = applications.values().iterator();
- while (iterator.hasNext()) {
- ((Application)iterator.next()).shutdown();
- iterator.remove();
- }
- }
- }
-
-
-
-
- /*
- *
- * FUNCTIONS FOR SENDING INFORMATION OVER TO THE JDE SIDE
- *
- */
-
-
-
-
- /**
- * Returns a string representation of the object. Here is the logic:
- * <ul>
- * <li> If the object is null, return an empty string
- * <li> If the object is string, quote it within quotation marks.
- * <li> If the object is a list, recursively call stringRep, appending
- * a space.
- * <li> If it's any other kind of object, return the .toString()
- * </ul>
- */
- public String stringRep(Object obj) {
- if (obj == null) {
- return "";
- } else if (obj instanceof String) {
- return "\""+obj.toString()+"\"";
- } else if (obj instanceof List) {
- StringBuffer returnString = new StringBuffer("");
- Iterator it = ((List)obj).iterator();
- while (it.hasNext()) {
- returnString.append(stringRep(it.next())+" ");
- }
- return "\n"+returnString.toString().trim();
- } else {
- return obj.toString();
- }
- }
-
-
- /**
- * Send an arbitrary lisp function across.
- *
- * @param app_id The application ID
- * @param type The function name. JDE_BUG gets added to
- * its beginning
- * @param obj An arbitrary object. If a string, it's just printed out,
- * if a list, each of its elements is printed out, with a space after
- * each.
- */
- synchronized public void signal(Integer app_id, String type,
- Object obj) {
- String strRep = stringRep(obj);
- if (strRep.equals("")) {
- out.println("\n("+JDE_BUG+type+" "+app_id+")\n");
- } else {
- String temp="("+JDE_BUG+type+"\n"+app_id+"
"+stringRep(obj)+")";
- if (temp.length() <= 80)
- out.println("\n("+JDE_BUG+type+" "+app_id+" "+
- stringRep(obj)+")\n");
- else
- out.println("\n"+temp+"\n");
- }
- out.flush();
- }
-
- /**
- * Signal a reply: a result or an error
- */
- synchronized private void signalReply(Integer app_id, Integer cmd_id,
- Object obj, String type) {
- String strRep = stringRep(obj);
- if (strRep.equals("")) {
- out.println("\n("+type+" "+cmd_id+")\n");
- } else {
- String temp = "("+type+"\n"+cmd_id+"
"+strRep+")";
- if (temp.length() <= 80)
- out.println("\n("+type+" "+cmd_id+"
"+strRep+")\n");
- else
- out.println("\n"+temp+"\n");
- }
- out.flush();
- }
-
-
- /**
- * send the result of a command. indicates a positive completion of
- * the command. this could of course be provisional: eg. in case of
- * provisional breakpoints
- */
- public void signalCommandResult(Integer app_id, Integer cmd_id) {
- signalCommandResult(app_id, cmd_id, null);
- }
-
- /**
- *
- * the result of a command. if it's a string, just send it across, else
- * it should be a list. each element is sent across, just doing a
- * toString() -> ie, if you want to send (... 23 "some string" 45), you
- * need to put in the quotes (ie "") yourself: else what will be sent
- * will be (... 23 some string 45), obviously wrong.
- */
- synchronized public void signalCommandResult(Integer app_id,
- Integer cmd_id, Object obj) {
- signalReply(app_id, cmd_id, obj, COMMAND_RESULT);
- }
-
-
- /**
- * reply to a command with an error.
- * @param obj Is usually a string explaining what went wrong.
- */
- synchronized public void signalCommandError(Integer app_id,
- Integer cmd_id, Object obj) {
- signalReply(app_id, cmd_id, obj, COMMAND_ERROR);
- }
-
-} // JDE
-
+package jde.debugger;
+import java.io.BufferedReader;
+import java.io.PrintWriter;
+import java.io.InputStreamReader;
+import java.util.List;
+import java.util.Iterator;
+
+/**
+ * JDE.java
+ *
+ *
+ * Created: Thu Feb 15 12:58:59 2001
+ *
+ * @author <a href="mailto: "</a>
+ * @version
+ */
+
+public class JDE implements Protocol {
+
+
+ private JDE (){}
+
+
+ public void init() {
+
+ // The debugger uses standard out to sent command responses, error
+ // messages and event notifications to the JDE.
+ out = new PrintWriter(System.out);
+
+ // The debugger uses standard int to read commands from the JDE.
+ in = new BufferedReader(new InputStreamReader(System.in));
+
+ commandStream = new CommandStream(in);
+
+ }
+
+
+ public List nextCommand() {
+ return commandStream.nextCommand();
+ }
+
+ /*
+ *
+ * FUNCTIONS FOR SENDING INFORMATION OVER TO THE JDE SIDE
+ *
+ */
+
+
+ /**
+ * Returns a string representation of the object. Here is the logic:
+ * <ul>
+ * <li> If the object is null, return an empty string
+ * <li> If the object is string, quote it within quotation marks.
+ * <li> If the object is a list, recursively call stringRep, appending
+ * a space.
+ * <li> If it's any other kind of object, return the .toString()
+ * </ul>
+ */
+ public String stringRep(Object obj) {
+ if (obj == null) {
+ return "";
+ } else if (obj instanceof String) {
+ return "\""+obj.toString()+"\"";
+ } else if (obj instanceof List) {
+ StringBuffer returnString = new StringBuffer("");
+ Iterator it = ((List)obj).iterator();
+ while (it.hasNext()) {
+ returnString.append(stringRep(it.next())+" ");
+ }
+ return BR +returnString.toString().trim();
+ } else {
+ return obj.toString();
+ }
+ }
+
+
+ /**
+ * Send an arbitrary lisp function across.
+ *
+ * @param app_id The application ID
+ * @param type The function name. JDE_BUG gets added to
+ * its beginning
+ * @param obj An arbitrary object. If a string, it's just printed out,
+ * if a list, each of its elements is printed out, with a space after
+ * each.
+ */
+ synchronized public void signal(Integer app_id, String type,
+ Object obj) {
+ String strRep = stringRep(obj);
+ if (strRep.equals("")) {
+ System.out.println(BR+"("+JDE_BUG+type+"
"+app_id+")"+BR);
+ } else {
+ String temp="("+JDE_BUG+type+ BR +app_id+"
"+stringRep(obj)+")";
+ if (temp.length() <= 80)
+ System.out.println(BR+"("+JDE_BUG+type+" "+app_id+" "+
+ stringRep(obj)+")"+BR);
+ else
+ System.out.println( BR +temp+ BR );
+ }
+ System.out.flush();
+ }
+
+ /**
+ * Signal a reply: a result or an error
+ */
+ synchronized private void signalReply(Integer app_id, Integer cmd_id,
+ Object obj, String type) {
+ String strRep = stringRep(obj);
+ if (strRep.equals("")) {
+ System.out.println(BR+"("+type+" "+cmd_id+")"+BR);
+ } else {
+ String temp = "("+type+ BR +cmd_id+" "+strRep+")";
+ if (temp.length() <= 80)
+ System.out.println(BR+"("+type+" "+cmd_id+"
"+strRep+")"+BR);
+ else
+ System.out.println( BR +temp+ BR );
+ }
+ System.out.flush();
+ }
+
+
+ /**
+ * send the result of a command. indicates a positive completion of
+ * the command. this could of course be provisional: eg. in case of
+ * provisional breakpoints
+ */
+ public void signalCommandResult(Integer app_id, Integer cmd_id) {
+ signalCommandResult(app_id, cmd_id, null);
+ }
+
+ public void signalDebug(String msg) {
+ signal(Jdebug.debuggerID, MESSAGE, msg);
+ }
+
+ /**
+ *
+ * the result of a command. if it's a string, just send it across, else
+ * it should be a list. each element is sent across, just doing a
+ * toString() -> ie, if you want to send (... 23 "some string" 45), you
+ * need to put in the quotes (ie "") yourself: else what will be sent
+ * will be (... 23 some string 45), obviously wrong.
+ */
+ synchronized public void signalCommandResult(Integer app_id,
+ Integer cmd_id, Object obj) {
+ signalReply(app_id, cmd_id, obj, COMMAND_RESULT);
+ }
+
+
+ /**
+ * reply to a command with an error.
+ * @param obj Is usually a string explaining what went wrong.
+ */
+ synchronized public void signalCommandError(Integer app_id,
+ Integer cmd_id, Object obj) {
+ signalReply(app_id, cmd_id, obj, COMMAND_ERROR);
+ }
+
+ public static JDE getJDE() {
+ return jde;
+ }
+
+ /*
+ * Reads commands from JDE.
+ */
+ BufferedReader in;
+
+ /*
+ * Writes command responses, messages, and event notifications to
+ * JDE.
+ */
+ PrintWriter out;
+
+
+ CommandStream commandStream;
+
+ private static JDE jde = new JDE();
+
+
+}// JDE
Index: xemacs-packages/jde/java/src/jde/debugger/JDEException.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/JDEException.java,v
retrieving revision 1.1
diff -u -r1.1 JDEException.java
--- xemacs-packages/jde/java/src/jde/debugger/JDEException.java 2000/08/13 13:36:09 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/JDEException.java 2001/08/15 05:27:46
@@ -1,28 +1,28 @@
-
-package jde.debugger;
-
-/**
- * JDEException.java
- * <p>
- * This is the standard exception raised whenever something wrong happens...
- * The only thing worth mentioning is that the message is a description of
- * what went wrong.
- * <p>
- * Created: Fri Jul 9 10:55:21 1999
- *
- * @author Amit Kumar
- * @since 0.1
- */
-
-public class JDEException extends Exception implements Protocol {
-
- final String message;
-
- public JDEException(String str) {
- super(str);
- this.message = str;
- }
-
- public String getMessage() { return message; }
-
-} // JDEException
+
+package jde.debugger;
+
+/**
+ * JDEException.java
+ * <p>
+ * This is the standard exception raised whenever something wrong happens...
+ * The only thing worth mentioning is that the message is a description of
+ * what went wrong.
+ * <p>
+ * Created: Fri Jul 9 10:55:21 1999
+ *
+ * @author Amit Kumar
+ * @since 0.1
+ */
+
+public class JDEException extends Exception implements Protocol {
+
+ final String message;
+
+ public JDEException(String str) {
+ super(str);
+ this.message = str;
+ }
+
+ public String getMessage() { return message; }
+
+} // JDEException
Index: xemacs-packages/jde/java/src/jde/debugger/JDENumberFormatException.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/JDENumberFormatException.java,v
retrieving revision 1.1
diff -u -r1.1 JDENumberFormatException.java
--- xemacs-packages/jde/java/src/jde/debugger/JDENumberFormatException.java 2000/08/13
13:36:09 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/JDENumberFormatException.java 2001/08/15
05:27:46
@@ -1,21 +1,21 @@
-
-package jde.debugger;
-
-/**
- * JDENumberFormatException.java
- * <p>
- *
- * <p>
- * Created: Thu Aug 5 18:52:41 1999
- *
- * @author Amit Kumar
- * @since 0.1
- */
-
-public class JDENumberFormatException extends JDEException {
-
- public JDENumberFormatException(String str) {
- super("Non-numeric "+str);
- }
-
-} // JDENumberFormatException
+
+package jde.debugger;
+
+/**
+ * JDENumberFormatException.java
+ * <p>
+ *
+ * <p>
+ * Created: Thu Aug 5 18:52:41 1999
+ *
+ * @author Amit Kumar
+ * @since 0.1
+ */
+
+public class JDENumberFormatException extends JDEException {
+
+ public JDENumberFormatException(String str) {
+ super("Non-numeric "+str);
+ }
+
+} // JDENumberFormatException
Index: xemacs-packages/jde/java/src/jde/debugger/Jdebug.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/Jdebug.java,v
retrieving revision 1.2
diff -u -r1.2 Jdebug.java
--- xemacs-packages/jde/java/src/jde/debugger/Jdebug.java 2001/02/12 06:34:15 1.2
+++ xemacs-packages/jde/java/src/jde/debugger/Jdebug.java 2001/08/15 05:27:46
@@ -13,7 +13,6 @@
import java.util.Map;
import java.util.Collection;
import java.io.IOException;
-import java.io.StreamTokenizer;
import java.util.List;
import java.io.InputStreamReader;
import java.util.HashMap;
@@ -53,17 +52,8 @@
public void init() throws IOException {
- // The debugger uses standard out to sent command responses, error
- // messages and event notifications to the JDE.
- out = new PrintWriter(System.out);
-
- // The debugger uses standard int to read commands from the JDE.
- in = new BufferedReader(new InputStreamReader(System.in));
-
- applications = Collections.synchronizedMap(new HashMap());
+ jde.init();
- pendingCommands = Collections.synchronizedSet(new HashSet());
-
}
/********************************************************************
@@ -71,360 +61,35 @@
********************************************************************/
/**
- * Sets the syntax of the input stream. We want the input to be broken
- * into lines, with whitespaces separating tokens
- */
- private void setSyntax(StreamTokenizer st) {
- st.resetSyntax();
- st.eolIsSignificant(true);
- st.whitespaceChars('\u0000', '\u0020');
- st.wordChars('\u0021', '\u00ff');
- st.quoteChar('"');
- }
-
- /**
* Runs the debugger thread. This method reads and executes commands
* from the JDE.
*/
public void run() {
-
- // read till we get an error
- try {
- StreamTokenizer st = new StreamTokenizer(in);
- setSyntax(st);
-
- int ttype;
-
- // read a line at a time
- ttype = st.nextToken();
- while (ttype != StreamTokenizer.TT_EOF) {
-
- try {
-
- List commandLine = new ArrayList();
- while(ttype != StreamTokenizer.TT_EOL) {
-
- if (ttype == StreamTokenizer.TT_EOF) {
- throw new IOException("I/O EOF occured");
- } else if (ttype == StreamTokenizer.TT_WORD) {
- //Debug.printIf(Debug.JDE_PIPE, "word "+st.sval);
- commandLine.add(st.sval);
- } else if ((ttype == '"') || (ttype == '\'')) {
- //Debug.printIf(Debug.JDE_PIPE, "phrase "+st.sval);
- commandLine.add(st.sval);
- } else {
- // should be a char. see if we need to get ttype
- // and convert it into a string instead of using
- // tostring
- //Debug.printIf(Debug.JDE_PIPE, "char "+st);
- commandLine.add(String.valueOf((char)ttype));
- }
-
- ttype = st.nextToken();
-
- } // finished reading a line, or eof raised.
-
- // if (Debug.set(Debug.JDE_PIPE)) Etc.dump(commandLine);
-
- // we have the complete command. since we're really a
- // private interface, we assume that the line is really
- // well formed. if not, we don't raise an exception,
- // just
- // warn the jde side that we didn't understand the last
- // command. just to be consistent, we will *not* send
- // back
- // the app_id and cmd_id back (they will both be -1)
- // when
- // we complain about malformed commands, even if
- // one/both
- // *were* available to us (ie were parsed correctly)
-
- if (commandLine.size() < 3) {
- if (commandLine.size() > 0)
- signalCommandError(debuggerID, new Integer(-1), "Malformed command");
- ttype = st.nextToken();
- // don't get irritated by simple newlines
- continue;
- }
-
- final Integer app_id =
- Integer.valueOf(commandLine.get(0).toString());
- final Integer cmd_id =
- Integer.valueOf(commandLine.get(1).toString());
- final String command =
- commandLine.get(2).toString().toLowerCase();
- final List arguments =
- commandLine.subList(3, commandLine.size());
-
- Thread cmd =
- DebugCommandFactory.theFactory.createCommand(app_id, cmd_id, command, arguments);
-
-
- if (cmd == null) {
-
- cmd = new Thread("Executing ("+app_id+","+cmd_id+")")
{
- public void run() {
- handleAppCommand(app_id, cmd_id, command, arguments);
- }
- };
- }
-
- cmd.start();
-
- } catch (IOException ex) {
- // if there is an ioexception, the connection was
- // broken. fall through the loop, raising another
- // exception as the outer loop tries to read a token
- // Debug.printIf(ex);
- } catch (Exception ex) {
- // any other exception means the command wasn't good.
- // Debug.printIf(ex);
- // since we cannot be sure of app_id and cmd_id being
- // good, we send back a general error.
- signalCommandError(debuggerID, new Integer(-1), "Malformed command:
"+ex.toString());
- }
-
- // read another token
- ttype = st.nextToken();
-
- } // finished reading all input
-
- }
- catch (IOException ex) {
- // Debug.printIf(ex);
- }
- finally {
- // close down gracefully, shutting down all VMs
- // jdeexceptions might be raised: ignore them.
- try {
- shutdown();
- } catch (Exception ex) {
- // do nothing
- }
- }
- }
+ List command = JDE.getJDE().nextCommand();
+ while (command != null) {
- /**
- * Commands received from Jdebug that don't have app_id == -1 get
- * funneled to handleAppCommand. We have to check if the app_id is
- * valid and if it corresponds to a valid app. If not, we send a
- * general error message back to jde, with debuggerID=1 and cmd_id=-1
- * since app_id is not valid anyway
- *
- * @param app_id The ID of the app this command targets
- * @param cmd_id ID of the command
- * @param command the command
- * @param arguments command arguments
- */
- private void handleAppCommand(Integer app_id, Integer cmd_id,
- String command, List arguments) {
- Application app;
-
- synchronized(applications) {
- // this app id should be valid. register using a connector
- // earlier
- if (!applications.containsKey(app_id)) {
- signalCommandError(debuggerID, cmd_id, "Application ID
'"+app_id+"' does not exist");
- return;
- }
- }
- synchronized(applications) {
- // also, it should be a valid application
- if ((app = (Application)applications.get(app_id)) == null) {
- signalCommandError(debuggerID, cmd_id, "Application ID
'"+app_id+"' does not correspond to a valid application");
- }
- }
- // at this point, we call the handleCommand function of the
- // app to take care of actions.
- app.handleCommand(cmd_id, command, arguments);
- }
-
+ final Integer proc_id = Integer.valueOf(command.get(0).toString());
+ final Integer cmd_id = Integer.valueOf(command.get(1).toString());
+ final String cmd_name = command.get(2).toString().toLowerCase();
+ final List arguments = command.subList(3, command.size());
- public void addApplication(Integer appID, Application app) {
- synchronized (applications) {
- applications.put(appID, app);
- }
- }
-
- /**
- * called by {@link Application#shutdown}
- * to remove it's own entry from
- * the applications collection here
- */
- public void removeApplication(Integer app_id) {
- synchronized (applications) {
- applications.remove(app_id);
- }
- }
-
- public boolean appExists(Integer appID) {
- synchronized (applications) {
- return applications.containsKey(appID);
- }
- }
-
- public Application getApplication(Integer appID) {
- synchronized (applications) {
- return (Application) applications.get(appID);
- }
- }
-
-
-
- public void addPendingCommand(Integer cmdID) {
- synchronized (pendingCommands) {
- pendingCommands.add(cmdID);
- }
- }
-
- public void removePendingCommand(Integer cmdID) {
- synchronized (pendingCommands) {
- pendingCommands.remove(cmdID);
- }
- }
-
- public boolean pendingCmdExists(Integer cmdID) {
- synchronized (pendingCommands) {
- return pendingCommands.contains(cmdID);
- }
- }
-
-
- /**
- * Shuts down all the applications prior to exiting
- */
- public void shutdown()
- throws JDEException {
- // run the "shutdown" function for all the apps currently being
- // debugged.
- synchronized (applications) {
- Iterator iterator = applications.values().iterator();
- while (iterator.hasNext()) {
- ((Application)iterator.next()).shutdown();
- iterator.remove();
+ try {
+ Thread cmd =
+ DebugCommandFactory.theFactory.createCommand(proc_id, cmd_id, cmd_name, arguments);
+ cmd.start();
}
- }
- }
-
-
-
- /*
- *
- * FUNCTIONS FOR SENDING INFORMATION OVER TO THE JDE SIDE
- *
- */
-
-
-
-
- /**
- * Returns a string representation of the object. Here is the logic:
- * <ul>
- * <li> If the object is null, return an empty string
- * <li> If the object is string, quote it within quotation marks.
- * <li> If the object is a list, recursively call stringRep, appending
- * a space.
- * <li> If it's any other kind of object, return the .toString()
- * </ul>
- */
- public String stringRep(Object obj) {
- if (obj == null) {
- return "";
- } else if (obj instanceof String) {
- return "\""+obj.toString()+"\"";
- } else if (obj instanceof List) {
- StringBuffer returnString = new StringBuffer("");
- Iterator it = ((List)obj).iterator();
- while (it.hasNext()) {
- returnString.append(stringRep(it.next())+" ");
+ catch (JDEException ex) {
+ jde.signal(proc_id, ERROR, "Error occurred while executing " + cmd_name +
+ ". Error: " + ex);
}
- return BR +returnString.toString().trim();
- } else {
- return obj.toString();
- }
- }
-
-
- /**
- * Send an arbitrary lisp function across.
- *
- * @param app_id The application ID
- * @param type The function name. JDE_BUG gets added to
- * its beginning
- * @param obj An arbitrary object. If a string, it's just printed out,
- * if a list, each of its elements is printed out, with a space after
- * each.
- */
- synchronized public void signal(Integer app_id, String type,
- Object obj) {
- String strRep = stringRep(obj);
- if (strRep.equals("")) {
- System.out.println(BR+"("+JDE_BUG+type+"
"+app_id+")"+BR);
- } else {
- String temp="("+JDE_BUG+type+ BR +app_id+"
"+stringRep(obj)+")";
- if (temp.length() <= 80)
- System.out.println(BR+"("+JDE_BUG+type+" "+app_id+" "+
- stringRep(obj)+")"+BR);
- else
- System.out.println( BR +temp+ BR );
- }
- System.out.flush();
- }
-
- /**
- * Signal a reply: a result or an error
- */
- synchronized private void signalReply(Integer app_id, Integer cmd_id,
- Object obj, String type) {
- String strRep = stringRep(obj);
- if (strRep.equals("")) {
- System.out.println(BR+"("+type+" "+cmd_id+")"+BR);
- } else {
- String temp = "("+type+ BR +cmd_id+" "+strRep+")";
- if (temp.length() <= 80)
- System.out.println(BR+"("+type+" "+cmd_id+"
"+strRep+")"+BR);
- else
- System.out.println( BR +temp+ BR );
- }
- System.out.flush();
- }
-
- /**
- * send the result of a command. indicates a positive completion of
- * the command. this could of course be provisional: eg. in case of
- * provisional breakpoints
- */
- public void signalCommandResult(Integer app_id, Integer cmd_id) {
- signalCommandResult(app_id, cmd_id, null);
- }
-
- public void signalDebug(String msg) {
- signal(debuggerID, MESSAGE, msg);
- }
-
- /**
- *
- * the result of a command. if it's a string, just send it across, else
- * it should be a list. each element is sent across, just doing a
- * toString() -> ie, if you want to send (... 23 "some string" 45), you
- * need to put in the quotes (ie "") yourself: else what will be sent
- * will be (... 23 some string 45), obviously wrong.
- */
- synchronized public void signalCommandResult(Integer app_id,
- Integer cmd_id, Object obj) {
- signalReply(app_id, cmd_id, obj, COMMAND_RESULT);
+ command = JDE.getJDE().nextCommand();
+ }
}
-
- /**
- * reply to a command with an error.
- * @param obj Is usually a string explaining what went wrong.
- */
- synchronized public void signalCommandError(Integer app_id,
- Integer cmd_id, Object obj) {
- signalReply(app_id, cmd_id, obj, COMMAND_ERROR);
+ public static Jdebug getTheDebugger() {
+ return theDebugger;
}
@@ -432,40 +97,8 @@
* FIELDS *
********************************************************************/
- /*
- * Reads commands from the JDE.
- */
- BufferedReader in;
-
- /*
- * Writes command responses, messages, and event notifications to
- * the JDE.
- */
- PrintWriter out;
- /**
- * Registry of active applications. The registry maps each application
- * to its ID. The app removes itself from the registry once it's finished.
- */
- Map applications;
- /**
- * Each command has a command id associated with it, that is used by
- * jde, to match with the corresponding result/error. jdebug maintains
- * the pending command ids in this collection (as does {@link
- * Application}, see
- * {@link Application#pendingCommands}),
- * and removes
- * them once the command processing is over.<br>
- * Hence, the command id can actually be reused.
- * <p>
- * Note that in case the command is actually meant for one of the apps
- * (ie as ascertained by matching the app_id), the id isn't stored in
- * our Collection, but the applications. This means that, in fact, it
- * is the tuple (app_id, cmd_id) that need be unique (assuming that a
- * "general" command has a app_id of -1
- */
- private Collection pendingCommands;
/**
* The ID of jdebug. This is used by jde when issuing commands that
@@ -477,13 +110,18 @@
public static Jdebug theDebugger = new Jdebug();
+ private JDE jde = JDE.getJDE();
+
+ private ProcessRegistry procRegistry = ProcessRegistry.getRegistry();
+
+
} // Jdebug
/*
* $Log: Jdebug.java,v $
- * Revision 1.2 2001/02/12 06:34:15 paulk
- * Updated for JDE-2.2.7.
+ * Revision 1.9 2001/03/24 05:36:48 paulk
+ * Updated to reflect reorganization of debuggee code.
*
* Revision 1.8 2000/10/20 04:18:29 paulk
* *** empty log message ***
Index: xemacs-packages/jde/java/src/jde/debugger/LispForm.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/LispForm.java,v
retrieving revision 1.1
diff -u -r1.1 LispForm.java
--- xemacs-packages/jde/java/src/jde/debugger/LispForm.java 2000/08/13 13:36:09 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/LispForm.java 2001/08/15 05:27:46
@@ -1,36 +1,36 @@
-
-package jde.debugger;
-
-/**
- * LispForm.java
- * <p>
- * A wrapper on a string, used to differentiate a normal string and a string
- * that's actually a lisp form
- * <p>
- * Created: Fri Jul 30 11:00:29 1999
- *
- * @author Amit Kumar
- * @since 0.1
- */
-
-public class LispForm {
-
- private String str;
-
- public LispForm() {
- this.str = "";
- }
-
- public LispForm(String str) {
- this.str = str;
- }
-
- public void cat(String str) {
- this.str += str;
- }
-
- public String toString() {
- return str;
- }
-
-} // LispForm
+
+package jde.debugger;
+
+/**
+ * LispForm.java
+ * <p>
+ * A wrapper on a string, used to differentiate a normal string and a string
+ * that's actually a lisp form
+ * <p>
+ * Created: Fri Jul 30 11:00:29 1999
+ *
+ * @author Amit Kumar
+ * @since 0.1
+ */
+
+public class LispForm {
+
+ private String str;
+
+ public LispForm() {
+ this.str = "";
+ }
+
+ public LispForm(String str) {
+ this.str = str;
+ }
+
+ public void cat(String str) {
+ this.str += str;
+ }
+
+ public String toString() {
+ return str;
+ }
+
+} // LispForm
Index: xemacs-packages/jde/java/src/jde/debugger/Main.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/Main.java,v
retrieving revision 1.1
diff -u -r1.1 Main.java
--- xemacs-packages/jde/java/src/jde/debugger/Main.java 2000/08/13 13:36:09 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/Main.java 2001/08/15 05:27:47
@@ -1,38 +1,38 @@
-
-package jde.debugger;
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-
-/**
- * Main class that has the "main" is called by jde.
- * <p>
- * Created: Wed Jul 7 21:02:39 1999
- *
- * @author Amit Kumar
- * @since 0.1
- */
-
-public class Main implements Protocol {
-
- public static void main(String[] args) {
- if (args.length > 0) {
- System.out.println("Usage: java jde.debugger.Main");
- // Etc.dump(args);
- System.out.flush();
- System.exit(0);
- } else {
- System.out.println(BR+"(" + JDE_INIT_DEBUG_SESSION+")"+BR);
- System.out.flush();
- try {
- Jdebug.theDebugger.init();
- Jdebug.theDebugger.start();
- } catch (IOException ex) {
- System.out.println("I/O Error");
- System.exit(1);
- }
- }
- }
-
-} // Main
+
+package jde.debugger;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+/**
+ * Main class that has the "main" is called by jde.
+ * <p>
+ * Created: Wed Jul 7 21:02:39 1999
+ *
+ * @author Amit Kumar
+ * @since 0.1
+ */
+
+public class Main implements Protocol {
+
+ public static void main(String[] args) {
+ if (args.length > 0) {
+ System.out.println("Usage: java jde.debugger.Main");
+ // Etc.dump(args);
+ System.out.flush();
+ System.exit(0);
+ } else {
+ System.out.println(BR+"(" + JDE_INIT_DEBUG_SESSION+")"+BR);
+ System.out.flush();
+ try {
+ Jdebug.theDebugger.init();
+ Jdebug.theDebugger.start();
+ } catch (IOException ex) {
+ System.out.println("I/O Error");
+ System.exit(1);
+ }
+ }
+ }
+
+} // Main
Index: xemacs-packages/jde/java/src/jde/debugger/ObjectStore.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/ObjectStore.java,v
retrieving revision 1.1
diff -u -r1.1 ObjectStore.java
--- xemacs-packages/jde/java/src/jde/debugger/ObjectStore.java 2000/08/13 13:36:09 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/ObjectStore.java 2001/08/15 05:27:47
@@ -1,124 +1,129 @@
-
-package jde.debugger;
-
-import java.util.*;
-
-import com.sun.jdi.*;
-
-/**
- * ObjectStore.java
- * <p>
- *
- * The main function of this class is to keep a store of all the currently
- * referenced objects. Any time jdebug sends an object ID across, it stores
- * the ObjectReference itself in {@link #objectMap}, mapped to the id that
- * will identify this object. This id is the ObjectReference.uniqueID().
- * <p>
- * We need to do this because if we don't keep a link to the ObjectReference
- * <i>some</i>where, it might get garbage collected, and the id used to
- * identify it (ie the uniqueID) reused. If the user then requests info
- * about that ID, he'll be sent information about the new object, which is
- * obviously wrong.
- * <p>
- * When jde wants to know more about the object, it sends across the id,
- * which is used to reference the ObjectReference in the Map
- * <p>
- * Since this is done with each object that's ever reported to jde, the list
- * can get pretty huge, and needs to be refreshed from time to time. For
- * this purpose, we maintain the variable {@link #maximumLimit}.
- * <p>
- * Objects keep getting added to the list, until we
- * reach {@link #maximumLimit}. At this point, a notification is sent to the
- * jde side requesting for a list of all the object references (ie, the ids)
- * that it is currently interested in.
- * <p>
- * When this list is obtained, the {@link #objectMap} is scanned and entries
- * <i>not</i> in this list removed. {@link #maximumLimit} is then set to
- * 2 times the current size of the list, or the old maximumLimit, whichever
- * is larger. This is to ensure we don't keep sending the request over and
- * over again very frequently.
- * <p>
- * Note that we keep adding objects to the Map even after sending the
- * notification to jde: any reducing the size of the list is only done
- * when jde responds.
- * <p>
- * <b>Note:</b> Question: Should we disable garbage collection of objects
- * in the debugee VM once we put their corresponding ObjectReference in the
- * debugger VM in the objectstore? And maybe enable the gc once they're
- * removed from the store? This way we'll never get the ObjectCollected
- * exception, and we can use the object as long as its displayed on the
- * emacs side. The only thing is, we'd need the emacs side to be pretty
- * frequent about the list of things it is displaying so we don't encumber
- * the debuggee VM too much with objects it's unable to collect.
- * <p>
- * Created: Thu Jul 29 10:38:06 1999
- *
- * @author Amit Kumar
- * @since 0.1
- */
-
-public class ObjectStore implements Protocol {
-
- /** my very own application! */
- final Application app;
-
- /** maps object_id -> ObjectReference */
- private Map objectMap;
-
- /** maximum number of objects before we send a notification to jde */
- private long maximumLimit = 8;
-
- /** keep track of if our request has been met yet */
- private boolean requestPending = false;
-
- /** Create a new object map for a new application */
- public ObjectStore(Application app) {
- this.app = app;
- objectMap = new HashMap();
- }
-
- /** Register that an object is being sent to the jde side */
- public void put(ObjectReference ref) {
- long size;
- synchronized (this) {
- objectMap.put(new Long(ref.uniqueID()), ref);
- size = objectMap.size();
- }
- if (size > maximumLimit) {
- if (!requestPending) {
- app.signal(REPORT_IDS_IN_USE, null);
- requestPending = true;
- }
- }
- }
-
- /**
- * jde sent us a list of objects it is currently interested in. Trim
- * objectMap based on this list
- */
- public void trim(List objectIDs) {
- Map newMap = new HashMap();
- Iterator it = objectIDs.iterator();
- while (it.hasNext()) {
- Long id = (Long)it.next();
- synchronized (this) {
- if (objectMap.containsKey(id)) {
- newMap.put(id, objectMap.get(id));
- }
- }
- }
- maximumLimit = 2*newMap.size();
- synchronized (this) {
- objectMap = newMap;
- }
- requestPending = false;
- }
-
- /** Returns the object corresponding to the id, or null */
- public ObjectReference get(Object id) {
- synchronized (this) {
- return (ObjectReference)objectMap.get(id);
- }
- }
-
-} // ObjectStore
+
+package jde.debugger;
+
+import java.util.*;
+
+import com.sun.jdi.*;
+
+/**
+ * ObjectStore.java
+ * <p>
+ *
+ * The main function of this class is to keep a store of all the currently
+ * referenced objects. Any time jdebug sends an object ID across, it stores
+ * the ObjectReference itself in {@link #objectMap}, mapped to the id that
+ * will identify this object. This id is the ObjectReference.uniqueID().
+ * <p>
+ * We need to do this because if we don't keep a link to the ObjectReference
+ * <i>some</i>where, it might get garbage collected, and the id used to
+ * identify it (ie the uniqueID) reused. If the user then requests info
+ * about that ID, he'll be sent information about the new object, which is
+ * obviously wrong.
+ * <p>
+ * When jde wants to know more about the object, it sends across the id,
+ * which is used to reference the ObjectReference in the Map
+ * <p>
+ * Since this is done with each object that's ever reported to jde, the list
+ * can get pretty huge, and needs to be refreshed from time to time. For
+ * this purpose, we maintain the variable {@link #maximumLimit}.
+ * <p>
+ * Objects keep getting added to the list, until we
+ * reach {@link #maximumLimit}. At this point, a notification is sent to the
+ * jde side requesting for a list of all the object references (ie, the ids)
+ * that it is currently interested in.
+ * <p>
+ * When this list is obtained, the {@link #objectMap} is scanned and entries
+ * <i>not</i> in this list removed. {@link #maximumLimit} is then set to
+ * 2 times the current size of the list, or the old maximumLimit, whichever
+ * is larger. This is to ensure we don't keep sending the request over and
+ * over again very frequently.
+ * <p>
+ * Note that we keep adding objects to the Map even after sending the
+ * notification to jde: any reducing the size of the list is only done
+ * when jde responds.
+ * <p>
+ * <b>Note:</b> Question: Should we disable garbage collection of objects
+ * in the debugee VM once we put their corresponding ObjectReference in the
+ * debugger VM in the objectstore? And maybe enable the gc once they're
+ * removed from the store? This way we'll never get the ObjectCollected
+ * exception, and we can use the object as long as its displayed on the
+ * emacs side. The only thing is, we'd need the emacs side to be pretty
+ * frequent about the list of things it is displaying so we don't encumber
+ * the debuggee VM too much with objects it's unable to collect.
+ * <p>
+ * Created: Thu Jul 29 10:38:06 1999
+ *
+ * @author Amit Kumar
+ * @since 0.1
+ */
+
+public class ObjectStore implements Protocol {
+
+ /** my very own process! */
+ final DebuggeeProcess proc;
+
+ final Integer procID;
+
+ JDE jde = JDE.getJDE();
+
+ /** maps object_id -> ObjectReference */
+ private Map objectMap;
+
+ /** maximum number of objects before we send a notification to jde */
+ private long maximumLimit = 8;
+
+ /** keep track of if our request has been met yet */
+ private boolean requestPending = false;
+
+ /** Create a new object map for a new process. */
+ public ObjectStore(DebuggeeProcess proc) {
+ this.proc = proc;
+ procID = proc.getId();
+ objectMap = new HashMap();
+ }
+
+ /** Register that an object is being sent to the jde side */
+ public void put(ObjectReference ref) {
+ long size;
+ synchronized (this) {
+ objectMap.put(new Long(ref.uniqueID()), ref);
+ size = objectMap.size();
+ }
+ if (size > maximumLimit) {
+ if (!requestPending) {
+ jde.signal(procID, REPORT_IDS_IN_USE, null);
+ requestPending = true;
+ }
+ }
+ }
+
+ /**
+ * jde sent us a list of objects it is currently interested in. Trim
+ * objectMap based on this list
+ */
+ public void trim(List objectIDs) {
+ Map newMap = new HashMap();
+ Iterator it = objectIDs.iterator();
+ while (it.hasNext()) {
+ Long id = (Long)it.next();
+ synchronized (this) {
+ if (objectMap.containsKey(id)) {
+ newMap.put(id, objectMap.get(id));
+ }
+ }
+ }
+ maximumLimit = 2*newMap.size();
+ synchronized (this) {
+ objectMap = newMap;
+ }
+ requestPending = false;
+ }
+
+ /** Returns the object corresponding to the id, or null */
+ public ObjectReference get(Object id) {
+ synchronized (this) {
+ return (ObjectReference)objectMap.get(id);
+ }
+ }
+
+} // ObjectStore
Index: xemacs-packages/jde/java/src/jde/debugger/ProcessRegistry.java
===================================================================
RCS file: ProcessRegistry.java
diff -N ProcessRegistry.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ ProcessRegistry.java Tue Aug 14 22:27:47 2001
@@ -0,0 +1,79 @@
+package jde.debugger;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Collections;
+import java.util.Iterator;
+
+/**
+ * ProcessRegistry.java
+ *
+ *
+ * Registry of processes. The registry maps each process
+ * to its ID.
+ *
+ * Created: Thu Feb 15 13:48:06 2001
+ *
+ * @author <a href="mailto:pkinnucan@mediaone.net">Paul
Kinnucan</a>
+ * @version $Revision: 1.1 $
+ */
+public class ProcessRegistry {
+
+ private ProcessRegistry (){}
+
+ public void addProcess(Integer procID, DebuggeeProcess proc) {
+ synchronized (processes) {
+ processes.put(procID, proc);
+ }
+ }
+
+ /**
+ * called by {@link DebuggeeProcess#shutdown}
+ * to remove it's own entry from
+ * the applications collection here
+ */
+ public void removeProcess(Integer procID) {
+ synchronized (processes) {
+ processes.remove(procID);
+ }
+ }
+
+ public boolean processExists(Integer procID) {
+ synchronized (processes) {
+ return
+ processes.containsKey(procID) &&
+ (((DebuggeeProcess)getProcess(procID)) != null);
+ }
+ }
+
+ public DebuggeeProcess getProcess(Integer procID) {
+ synchronized (processes) {
+ return (DebuggeeProcess) processes.get(procID);
+ }
+ }
+
+ public static ProcessRegistry getRegistry() {
+ return registry;
+ }
+
+ /**
+ * Shuts down all the applications prior to exiting
+ */
+ public void shutdownProcesses()
+ throws JDEException {
+ // run the "shutdown" function for all the apps currently being
+ // debugged.
+ synchronized (processes) {
+ Iterator iterator = processes.values().iterator();
+ while (iterator.hasNext()) {
+ ((DebuggeeProcess)iterator.next()).shutdown();
+ iterator.remove();
+ }
+ }
+ }
+
+
+ Map processes = Collections.synchronizedMap(new HashMap());
+
+ private static ProcessRegistry registry = new ProcessRegistry();
+
+}// ProcessRegistry
Index: xemacs-packages/jde/java/src/jde/debugger/Rep.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/Rep.java,v
retrieving revision 1.1
diff -u -r1.1 Rep.java
--- xemacs-packages/jde/java/src/jde/debugger/Rep.java 2000/08/13 13:36:10 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/Rep.java 2001/08/15 05:27:47
@@ -1,860 +1,868 @@
-/*
- * Copyright (c) 2000 Paul Kinnucan
- *
- * $Revision: 1.1 $
- */
-
-package jde.debugger;
-
-import com.sun.jdi.*;
-
-import java.util.*;
-
-/**
- * Rep.java
- * <p>
- * Responsible for providing static methods used in spewing out string
- * representations.
- * <ul>
- * <li> A useful hierarchy:
- * <ul>
- * <li> Value
- * <ul>
- * <li> ObjectReference
- * <ul>
- * <li> StringReference
- * <li> ArrayReference
- * <li> ThreadReference
- * <li> ThreadGroupReference
- * <li> Other...
- * </ul>
- * <li> PrimitiveValue
- * <ul>
- * <li> BooleanValue
- * <li> etc....
- * </ul>
- * </ul>
- * </ul>
- * </ul>
- * In our design, whenever we encounter an objectReference, we pass a
- * sort of summary to jde, as well as an 'id' to identify it with.
- * Whenever jde needs info about the objectReference, it uses the id to
- * uniquely identify the object.
- * <p>
- * Now, the representation that is sent across for the threads (ie to the
- * jde) depends on the context. When it is sent with reference to thread
- * commands, eg. get_threads, get_thread, get_object_monitors; it has
- * a lot of thread specific information, eg. its state and all.
- * <p>
- * When it's sent treating the thread as an object, eg. get_object, it's
- * represented differently, and a different set of information is sent.
- * <p>
- * Similary, when an array command is used, a different set of information
- * is sent across, as against when it's treated as an object.
- * <p>
- * Created: Tue Aug 3 16:36:54 1999
- *
- * @author Amit Kumar
- * @since 0.1
- */
-
-public class Rep implements Protocol {
-
- /**
- * Returns a representation of a Location
- * <p>
- *
- * <b>Syntax:</b>
- * <pre>
- * (list "type-name" "sourcefile" lineNumber)
- * (list "type-name" nil lineNumber)
- * </pre>
- *
- * <b>Comments:</b>
- * <ul>
- * <li> lineNumber is -1 if that information is not available
- * </ul>
- */
- static LispForm getLocationRep(Location loc) {
- String locationString = "(list
\""+loc.declaringType().name()+"\"";
- try {
- locationString += " \""+loc.sourceName()+"\"";
- } catch (AbsentInformationException ex) {
- locationString += " nil";
- }
- locationString += " "+loc.lineNumber()+")";
- return new LispForm(locationString);
- }
-
-
- /**
- * Returns a representation of a method
- * <p>
- *
- * <b>Syntax:</b>
- * <pre>
- * (list "name of method" return-type-name
- * (list [argument-type-name]*)
- * ["final"] ["static"] ["native"]
["constructor"] ["abstract"]
- * ["synchronized"] ["static_initializer"])
- * </pre>
- */
- static LispForm getMethodRep(Method m) {
- List l = m.argumentTypeNames();
- String argList = "(list";
- Iterator it = l.iterator();
- while (it.hasNext()) {
- argList += " \""+it.next().toString()+"\"";
- }
- argList += ")";
-
- return new LispForm("(list
\""+m.declaringType().name()+"\""
- +" \""+m.name()+"\""
- +" \""+m.returnTypeName()+"\""
- + BR +argList
- +(m.isFinal()?" \"final\"":"")
- +(m.isStatic()?" \"static\"":"")
- +(m.isNative()?" \"native\"":"")
- +(m.isConstructor()?" \"constructor\"":"")
- +(m.isAbstract()?" \"abstract\"":"")
- +(m.isSynchronized()?" \"synchronized\"":"")
- +(m.isStaticInitializer()
- ?" \"static_initializer\"":"")
- +")");
- }
-
-
-
- /**
- * Returns a representation of a local variable on a stack frame
- * <p>
- * <b>Syntax:</b>
- * <pre>
- * (list "name of variable" "type of variable")
- * </pre>
- */
- static public LispForm getLocalVariableRep(LocalVariable lv) {
- return new LispForm("(list"
- + " \""+lv.name()+"\""
- + " \""+lv.typeName()+"\")");
- }
-
- /**
- * Returns a representation of a (local variable, value) pair.
- * <p>
- * <b>Syntax:</b>
- * <pre>
- * ({@link #getLocalVariableRep local-variable} . {@link #getValueRep value})
- * </pre>
- */
- static public LispForm getLocalVariableValueRep(LocalVariable lv, Value v,
- ObjectStore s) {
- return new LispForm("(cons "+getLocalVariableRep(lv)
- +" "+getValueRep(v, s)+")");
- }
-
- /**
- * Returns a list of (local variable, value) pairs.
- * <p>
- * <b>Syntax:</b>
- * <pre>
- * (list [{@link #getLocalVariableValueRep (local variable, value) pair}]*)
- * </pre>
- */
- static public LispForm getLocalVariableValueMapRep(Map map, ObjectStore s) {
- String localVariablesValuesString = "(list ";
- Set keys = map.keySet();
- Iterator iter = keys.iterator();
- while (iter.hasNext()) {
- LocalVariable localVariable = (LocalVariable)iter.next();
- Value val = (Value)map.get(localVariable);
- localVariablesValuesString +=
- BR +getLocalVariableValueRep(localVariable, val, s);
- }
- localVariablesValuesString += ")";
- return new LispForm(localVariablesValuesString);
- }
-
-
- /**
- * Returns a representation of a field.
- * <p>
- * <b>Syntax:</b>
- * <pre>
- * (list "name of field" "type of field" ["transient"]
["volatile"]
- * ["final"] ["static"])
- * </pre>
- */
- static LispForm getFieldRep(Field f) {
- return new LispForm("(list"
- + " \""+f.name()+"\""
- + " \""+f.typeName()+"\""
- + (f.isTransient() ? " \"transient\"" : "")
- + (f.isVolatile() ? " \"volatile\"" : "")
- + (f.isFinal() ? " \"final\"" : "")
- + (f.isStatic() ? " \"static\"" : "")
- +")");
- }
-
- /**
- * Returns a representation of a (field, value) pair.
- * <p>
- * <b>Syntax:</b>
- * <pre>
- * ({@link #getFieldRep field} . {@link #getValueRep value})
- * </pre>
- */
- static LispForm getFieldValueRep(Field f, Value v, ObjectStore s) {
- return new LispForm("(cons "+getFieldRep(f)+" "+getValueRep(v,
s)+")");
- }
-
- /**
- * Returns a list of (field, value) pairs.
- * <p>
- * <b>Syntax:</b>
- * <pre>
- * (list [{@link #getFieldValueRep (field, value) pair}]*)
- * </pre>
- */
- static LispForm getFieldValueMapRep(Map map, ObjectStore s) {
- String fieldsValuesString = "(list ";
- Set keys = map.keySet();
- Iterator iter = keys.iterator();
- while (iter.hasNext()) {
- Field field = (Field)iter.next();
- Value val = (Value)map.get(field);
- fieldsValuesString += BR +getFieldValueRep(field, val, s);
- }
- fieldsValuesString += ")";
- return new LispForm(fieldsValuesString);
- }
-
- private static String filterFPValue(String fpValue) {
- if (fpValue.equals("NaN"))
- return "\"NaN\"";
- else
- if (fpValue.equals("-Infinity"))
- return "\"-Infinity\"";
- else
- if (fpValue.equals("Infinity"))
- return "\"Infinity\"";
- else
- return fpValue;
- }
-
-
- /**
- * Returns a representation of a 'value', that can be primitive
- * or an object reference, or void.
- * <p>
- * <b>Syntax:</b>
- * <pre>
- * (list "null")
- * (list "void")
- *
- * {@link #getObjectRep(ObjectReference,ObjectStore) object-rep}
- *
- * (list "boolean" "true") (list "boolean"
"false")
- * (list "byte" 'byte-value')
- * (list "char" 'char-value')
- * (list "double" double-value)
- * (list "float" float-value)
- * (list "int" int-value)
- * (list "long" long-value)
- * (list "short" short-value)
- * </pre>
- */
- static public LispForm getValueRep(Value value, ObjectStore store) {
- if (value == null) {
- return new LispForm("(list \"null\")");
- } else if (value instanceof VoidValue) {
- return new LispForm("(list \"void\")");
- } else if (value instanceof ObjectReference) {
- return getObjectRep((ObjectReference)value, store);
- } else {
- PrimitiveValue v = (PrimitiveValue)value;
- if (v instanceof BooleanValue) {
- return new LispForm("(list \"boolean\"
\""+v.booleanValue()+"\")");
- } else if (v instanceof ByteValue) {
- return new LispForm("(list \"byte\"
\""+v.byteValue()+"\")");
- } else if (v instanceof CharValue) {
- return new LispForm("(list \"char\"
\""+v.charValue()+"\")");
- } else if (v instanceof DoubleValue) {
- String sv = "" + v.doubleValue();
- return new LispForm("(list \"double\"
"+filterFPValue(sv)+")");
- } else if (v instanceof FloatValue) {
- String sv = "" + v.floatValue();
- return new LispForm("(list \"float\"
"+filterFPValue(sv)+")");
- } else if (v instanceof IntegerValue) {
- return new LispForm("(list \"int\"
\""+v.intValue()+"\")");
- } else if (v instanceof LongValue) {
- return new LispForm("(list \"long\"
\""+v.longValue()+"\")");
- } else if (v instanceof ShortValue) {
- return new LispForm("(list \"short\"
"+v.shortValue()+")");
- }
- }
- return null;
- }
-
- /**
- * Returns information about an array
- * <p>
- *
- * <b>Syntax:</b>
- * <pre>
- * "Error message"
- * (list "type name" uniqueID ['t|nil] length [element]*)
- * </pre>
- *
- * <b>Comments:</b>
- * <ul>
- * <li> The third argument (['t|nil]) indicates if the object has
- * been garbage collected in the debugee vm: it's nil if it hasn't.
- * <li> elements are only present if the index/length make sense. See
- * param list.
- * </ul>
- * <p>
- *
- * @param index if -1, represents the begin of index from where
- * elements are to be sent
- * @param length Number of elements to be sent
- */
- static public LispForm getArrayRep(ArrayReference a, ObjectStore store,
- int index, int length) {
- if (a == null) {
- return new LispForm("\"Error!\"");
- } else {
- store.put(a);
-
- String elementsString = "";
- try {
- if (index != -1) {
- List elements = a.getValues(index, length);
- Iterator it = elements.iterator();
- while (it.hasNext()) {
- elementsString += " "+getValueRep((Value)it.next(),
- store);
- }
- }
- } catch (IndexOutOfBoundsException ex) {
- elementsString = "\"Index out of bounds\"";
- } catch (ObjectCollectedException ex) {
- elementsString = "\"The object has already been collected\"";
- }
- return new LispForm("(list "
- + "\""+a.referenceType().name()+"\""
- + " " +a.uniqueID()
- + (a.isCollected() ? " 't":" nil")
- + " " + a.length()
- + elementsString + ")");
- }
- }
-
-
- /**
- * Prefix \ escapes to all \ and " characters in a string so that
- * the string can be read byte the Lisp interpreter. For efficiency,
- * if no such characters are found, the argument String itself
- * is returned.
- *
- * @param str String to be prefixed.
- * @return A String.
- *
- * @author David Hay
- * @author Mark Gibson
- * @author Steve Haflich
- * @author Charles Hart
- * @author David Dagon
- */
- public static String escapeString (String str) {
-
- if ( str.indexOf('\\') == -1 &&
- str.indexOf('"') == -1 )
- {
- return str;
- }
- else
- {
- StringBuffer buf = new StringBuffer(str.length() + 16);
- for ( int i = 0; i < str.length(); i++ ) {
- char ch = str.charAt( i );
- switch ( ch ) {
- case '"': buf.append("\\\"" ); break;
- case '\\': buf.append("\\\\" ); break;
- default: buf.append( ch ); break;
- }
- }
- return buf.toString();
- }
- }
-
-
-
- /**
- * Returns the value of a string
- * <p>
- *
- * <b>Syntax:</b>
- * <pre>
- * "Error message"
- * (list "java.lang.String" uniqueID ['t|nil]
"string-value")
- * </pre>
- * <b>Comments:</b>
- * <ul>
- * <li> The third argument (['t|nil]) indicates if the object has
- * been garbage collected in the debugee vm: it's nil if it hasn't.
- * </ul>
- * <p>
- */
- static public LispForm getStringRep(StringReference s, ObjectStore store) {
- if (s == null) {
- return new LispForm("\"Error!\"");
- } else {
- store.put(s);
-
- return new LispForm("(list "
- + "\""+s.referenceType().name()+"\""
- + " "+s.uniqueID()
- + (s.isCollected() ? " 't":" nil")
- + " \"" + escapeString(s.value()) + "\")");
- }
- }
-
-
- /**
- * Returns a non-detailed representation of an object.
- *
- * @see #getObjectRep(ObjectReference,ObjectStore,boolean)
- */
- static public LispForm getObjectRep(ObjectReference o, ObjectStore store) {
- return getObjectRep(o, store, false);
- }
-
- /**
- * Returns a canonical representation of an object.
- * <p>
- *
- * <b>Syntax:</b>
- * <pre>
- * "Error Message"
- * (list "null")
- * <i>Non-detailed</i>
- * (list "type of object" uniqueID ['t|nil])
- * <i>Detailed</i>
- * (list "type of object" uniqueID ['t|nil] {@link #getFieldValueMapRep
fields-values})
- * </pre>
- *
- * <b>Comments:</b>
- * <ul>
- * <li> The third argument (['t|nil]) indicates if the object has
- * been garbage collected in the debugee vm: it's nil if it hasn't.
- * </ul>
- */
- static public LispForm getObjectRep(ObjectReference o, ObjectStore store,
- boolean detailed) {
- if (o == null) {
- return new LispForm("(list \"null\")");
- } else {
- store.put(o);
- if (detailed) {
- // fields and values
- String fieldsValuesString;
- try {
- // XXX a more complete list is available using
- // allFields().... fyi
- fieldsValuesString =
getFieldValueMapRep(o.getValues(o.referenceType().visibleFields()), store).toString();
- } catch (ClassNotPreparedException ex) {
- fieldsValuesString = "\"The class isn't prepared\"";
- } catch (ObjectCollectedException ex) {
- fieldsValuesString = "\"The object has already been
collected\"";
- } catch (Exception ex) {
- fieldsValuesString = "\"Unable to access fields and values. Optimized
class?\"";
- }
-
- return new LispForm("(list "
- + "\""+o.referenceType().name()+"\""
- + " "+o.uniqueID()
- + (o.isCollected() ? " 't":" nil")+BR
- + fieldsValuesString+")");
- } else {
- return new LispForm("(list "
- + "\""+o.referenceType().name()+"\""
- + " "+o.uniqueID()
- + (o.isCollected() ? " 't":" nil")
- +")");
- }
- }
- }
-
-
- /*
- * THREAD REPRESENTATIONS
- */
-
- /**
- * Returns information about monitors of an object.
- * <p>
- *
- * <b>Syntax:</b>
- * <pre>
- * (list uniqueID "type of object" ['t|nil] {@link #getThreadRep
owning-thread} (list [{@link #getThreadRep waiting-thread}]*))
- * </pre>
- *
- * <b>Comments:</b>
- * <ul>
- * <li> The third argument (['t|nil]) indicates if the object has
- * been garbage collected in the debugee vm: it's nil if it hasn't.
- * </ul>
- */
- static LispForm getObjectMonitorsRep(ObjectReference o, ObjectStore store) {
- if (o == null) {
- return new LispForm("null");
- } else {
- store.put(o);
-
- // owning thread
- String owningThread;
- try {
- ThreadReference t = o.owningThread();
- if (t == null) {
- owningThread = "nil";
- } else {
- owningThread = getThreadRep(t, store).toString();
- }
- } catch (IncompatibleThreadStateException ex) {
- owningThread = "\"Information Not Available\"";
- } catch (UnsupportedOperationException ex) {
- owningThread = "\"VM has no information\"";
- }
-
- // waiting threads
- String waitingThreadsString;
- try {
- waitingThreadsString = "(list";
- List waitingThreads = o.waitingThreads();
- Iterator it = waitingThreads.iterator();
- while (it.hasNext()) {
- waitingThreadsString += BR +getThreadRep((ThreadReference)it.next(), store);
- }
- waitingThreadsString += ")";
- } catch (IncompatibleThreadStateException ex) {
- waitingThreadsString = "\"Information Not Available\"";
- } catch (UnsupportedOperationException ex) {
- waitingThreadsString = "\"VM has no information\"";
- }
-
-
- return new LispForm("(list "+o.uniqueID()+" "
- +"\""+o.referenceType().name()+"\""
- + (o.isCollected() ? " 't":" nil")+BR
- +owningThread+ BR
- +waitingThreadsString+")");
- }
- }
-
- /* thread information retrieval routines */
-
-
-
- /**
- * Returns a canonical representation of a given ThreadGroupReference.
- * <p>
- * <b>Syntax:</b>
- * <pre>
- * (list "ThreadGroup" uniqueID "name of threadgroup"
- * (list [{@link #getThreadRep(ThreadReference, ObjectStore)
child thread}]*)
- * (list [{@link #getThreadGroupRep child threadgroup}]*))
- * </pre>
- */
- static LispForm getThreadGroupRep(ThreadGroupReference t,
- ObjectStore store) {
- store.put(t);
- String rep = "(list \"ThreadGroup\" "+t.uniqueID()
- +" \""+t.name()+"\" ";
-
- List list = t.threads();
- Iterator it = list.iterator();
- rep += BR+"(list";
- while (it.hasNext()) {
- rep += BR +getThreadRep((ThreadReference)it.next(), store);
- }
- rep += ")";
-
- list = t.threadGroups();
- it = list.iterator();
- rep += BR+"(list";
- while (it.hasNext()) {
- rep += BR +getThreadGroupRep((ThreadGroupReference)it.next(), store);
- }
- rep += ")";
-
- rep += ")";
-
- return new LispForm(rep);
- }
-
- /**
- * Returns a detailed thread representation.
- * @see #getThreadRep(ThreadReference, ObjectStore, boolean)
- */
- static LispForm getThreadRep(ThreadReference t, ObjectStore store) {
- return getThreadRep(t, store, true);
- }
-
- /**
- * Returns a canonical representation of a given ThreadReference.
- * <p>
- *
- * <b>Syntax:</b>
- * <pre>
- * <i>Non-detailed</i>
- * (list "Thread" uniqueID "name of thread"
<u>status</u> <u>currentState</u>)
- * <i>Detailed</i>
- * (list "Thread" uniqueID "name of thread" status currentState
- * (list [{@link #getStackFrameRep stack-frame}]*)
- * <u>owned-monitors-string</u>
- * <u>current-contended-monitor-string</u>)
- * </pre>
- *
- * <b>Comments:</b>
- * <ul>
- * <li> <u>status</u> is one of: "unknown", "waiting
on monitor",
- * "not started", "runnable", "sleeping",
"waiting", and "zombie"
- *
- * <li> <u>currentState</u> is one of "normal",
"suspended by debugger",
- * and "suspended at breakpoint"
-
- * <li> <u>owned-monitors-string</u>:
- * <pre>
- * "Error Message"
- * (list [{@link #getObjectRep(ObjectReference, ObjectStore) owned monitor}]*)
- * </pre>
- * <li> <u>current-contended-monitor-string</u>:
- * <pre>
- * "Error Message"
- * nil
- * {@link #getObjectRep(ObjectReference, ObjectStore) current contended monitor}
- * </pre>
- * <li>
- * Examples:
- * <pre>
- * (list "Thread" 53 "Thread 1, continuous"
- * "suspended by debugger" "waiting on monitor"
- * (list
- * (list 0 "test.Test" "Test.java" 45))
- * (list)
- * (list "java.lang.String" 55))
- *
- * (list "Thread" 54 "Thread 2"
- * "suspended by debugger" "waiting on monitor"
- * (list
- * (list 0 "java.lang.Thread" "Thread.java" -1)
- * (list 1 "test.Test" "Test.java" 47))
- * (list
- * (list "java.lang.String" 55)
- * (list "java.lang.Integer" 61))
- * (list))
- * </pre>
- * </ul>
- *
- * <p>
- * @param detailed True if a more detailed representation is desired:
- * includes the stackframe as well as information about the monitors.
- */
- static LispForm getThreadRep(ThreadReference t, ObjectStore store,
- boolean detailed) {
- int status = t.status();
- String statusString = "unknown";
- switch (status) {
- case ThreadReference.THREAD_STATUS_MONITOR: {
- statusString = "waiting on monitor";
- break;
- }
- case ThreadReference.THREAD_STATUS_NOT_STARTED: {
- statusString = "not started";
- break;
- }
- case ThreadReference.THREAD_STATUS_RUNNING: {
- statusString = "runnable";
- break;
- }
- case ThreadReference.THREAD_STATUS_SLEEPING: {
- statusString = "sleeping";
- break;
- }
- case ThreadReference.THREAD_STATUS_WAIT: {
- statusString = "waiting";
- break;
- }
- case ThreadReference.THREAD_STATUS_ZOMBIE: {
- statusString = "zombie";
- break;
- }
- case ThreadReference.THREAD_STATUS_UNKNOWN: {
- statusString = "unknown";
- break;
- }
- default: {
- break;
- }
- }
-
- // note that the above status string refers to the state of the
- // thread *before* a suspension, if there was a suspension.
-
- /* Due to a bug in ThreadReference.isSuspended(), we need to
- use suspendCount() */
- String stateString = "normal";
- if (t.isAtBreakpoint()) {
- stateString = "suspended at breakpoint";
- } else if (t.suspendCount() > 0) {
- stateString = "suspended by debugger";
- }
-
- if (detailed) {
-
- // info on the stack
-
- String stackString;
- try {
- stackString = "(list";
- // a list of the stackframes is also sent...
- List stackFrames = t.frames();
- Iterator it = stackFrames.iterator();
- int index = 0;
- while (it.hasNext()) {
- stackString += BR + getStackFrameRep((StackFrame)it.next(), index++);
- }
- stackString += ")";
- } catch (IncompatibleThreadStateException ex) {
- stackString = "\"Information Not Available\"";
- }
-
- // info on the monitors
-
- // owned monitors
-
- String ownedMonitorsString;
- try {
- ownedMonitorsString = "(list";
- List ownedMonitors = t.ownedMonitors();
- Iterator it = ownedMonitors.iterator();
- while (it.hasNext()) {
- ownedMonitorsString += BR +getObjectRep((ObjectReference)it.next(), store);
- }
- ownedMonitorsString += ")";
- } catch (IncompatibleThreadStateException ex) {
- ownedMonitorsString = "\"Information Not Available\"";
- } catch (UnsupportedOperationException ex) {
- ownedMonitorsString = "\"VM has no information\"";
- } catch (ObjectCollectedException ex) {
- ownedMonitorsString = "\"The object has been collected\"";
- }
-
- // current contended monitor
- // note, however, from the jdi api:
- // The thread can be waiting for a monitor through entry into a
- // synchronized method, the synchronized statement, or
- // Object.wait(). The status() method can be used to
- // differentiate between the first two cases and the third.
-
- String currentContendedMonitorString;
- try {
- ObjectReference o = t.currentContendedMonitor();
- if (o == null) {
- currentContendedMonitorString = "nil";
- } else {
- currentContendedMonitorString =
- getObjectRep(o, store).toString();
- }
- } catch (IncompatibleThreadStateException ex) {
- currentContendedMonitorString =
- "\"Information Not Available\"";
- } catch (UnsupportedOperationException ex) {
- currentContendedMonitorString =
- "\"VM has no information\"";
- } catch (ObjectCollectedException ex) {
- currentContendedMonitorString =
- "\"The object has been collected\"";
- }
-
- store.put(t);
- return new LispForm("(list \"Thread\""
- +" "+t.uniqueID()
- +" \""+t.name()+"\""
- +" \""+statusString+"\""
- +" \""+stateString+"\""
- + BR +stackString
- + BR +ownedMonitorsString
- + BR +currentContendedMonitorString
- +")");
- } else {
- store.put(t);
- return new LispForm("(list \"Thread\""
- +" "+t.uniqueID()
- +" \""+t.name()+"\""
- +" \""+statusString+"\""
- +" \""+stateString+"\")");
- }
- }
-
- /**
- * Returns a canonical representation of a given StackFrame.
- * <p>
- *
- * <b>Syntax:</b>
- * <pre>
- * (list "StackFrame" index "Information not available")
- * (list "StackFrame" index "type name" "source name"
lineNumber "method name")
- * </pre>
- *
- * <b>Comments:</b>
- * <ul>
- * <li> lineNumber is -1 for native methods
- * </ul>
- *
- * @param index Gives the index of this particular stack frame for
- * the thread. This basically goes into the string returned as a
- * convenience.
- */
- static LispForm getStackFrameRep(StackFrame s, int index) {
- try {
- Location loc = s.location();
- Method method = loc.method();
- return new LispForm("(list "+index+" "
- +"\""+loc.declaringType().name()+"\" "
- +"\""+loc.sourceName()+"\" "
- +loc.lineNumber()+" "
- +"\""+method.name()+"\")");
- } catch (AbsentInformationException ex) {
- return new LispForm("(list \"StackFrame\" "+index
- +" \"Information not available\")");
- }
- }
-
-} // Rep
-
-/*
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.15 $
+ */
+
+package jde.debugger;
+
+import com.sun.jdi.*;
+
+import java.util.*;
+
+/**
+ * Rep.java
+ * <p>
+ * Responsible for providing static methods used in spewing out string
+ * representations.
+ * <ul>
+ * <li> A useful hierarchy:
+ * <ul>
+ * <li> Value
+ * <ul>
+ * <li> ObjectReference
+ * <ul>
+ * <li> StringReference
+ * <li> ArrayReference
+ * <li> ThreadReference
+ * <li> ThreadGroupReference
+ * <li> Other...
+ * </ul>
+ * <li> PrimitiveValue
+ * <ul>
+ * <li> BooleanValue
+ * <li> etc....
+ * </ul>
+ * </ul>
+ * </ul>
+ * </ul>
+ * In our design, whenever we encounter an objectReference, we pass a
+ * sort of summary to jde, as well as an 'id' to identify it with.
+ * Whenever jde needs info about the objectReference, it uses the id to
+ * uniquely identify the object.
+ * <p>
+ * Now, the representation that is sent across for the threads (ie to the
+ * jde) depends on the context. When it is sent with reference to thread
+ * commands, eg. get_threads, get_thread, get_object_monitors; it has
+ * a lot of thread specific information, eg. its state and all.
+ * <p>
+ * When it's sent treating the thread as an object, eg. get_object, it's
+ * represented differently, and a different set of information is sent.
+ * <p>
+ * Similary, when an array command is used, a different set of information
+ * is sent across, as against when it's treated as an object.
+ * <p>
+ * Created: Tue Aug 3 16:36:54 1999
+ *
+ * @author Amit Kumar
+ * @since 0.1
+ */
+
+public class Rep implements Protocol {
+
+ /**
+ * Returns a representation of a Location
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * (list "type-name" "sourcefile" lineNumber)
+ * (list "type-name" nil lineNumber)
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> lineNumber is -1 if that information is not available
+ * </ul>
+ */
+ static LispForm getLocationRep(Location loc) {
+ String locationString = "(list
\""+loc.declaringType().name()+"\"";
+ try {
+ locationString += " \""+loc.sourceName()+"\"";
+ } catch (AbsentInformationException ex) {
+ locationString += " nil";
+ }
+ locationString += " "+loc.lineNumber()+")";
+ return new LispForm(locationString);
+ }
+
+
+ /**
+ * Returns a representation of a method
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * (list "name of method" return-type-name
+ * (list [argument-type-name]*)
+ * ["final"] ["static"] ["native"]
["constructor"] ["abstract"]
+ * ["synchronized"] ["static_initializer"])
+ * </pre>
+ */
+ static LispForm getMethodRep(Method m) {
+ List l = m.argumentTypeNames();
+ String argList = "(list";
+ Iterator it = l.iterator();
+ while (it.hasNext()) {
+ argList += " \""+it.next().toString()+"\"";
+ }
+ argList += ")";
+
+ return new LispForm("(list
\""+m.declaringType().name()+"\""
+ +" \""+m.name()+"\""
+ +" \""+m.returnTypeName()+"\""
+ + BR +argList
+ +(m.isFinal()?" \"final\"":"")
+ +(m.isStatic()?" \"static\"":"")
+ +(m.isNative()?" \"native\"":"")
+ +(m.isConstructor()?" \"constructor\"":"")
+ +(m.isAbstract()?" \"abstract\"":"")
+ +(m.isSynchronized()?" \"synchronized\"":"")
+ +(m.isStaticInitializer()
+ ?" \"static_initializer\"":"")
+ +")");
+ }
+
+
+
+ /**
+ * Returns a representation of a local variable on a stack frame
+ * <p>
+ * <b>Syntax:</b>
+ * <pre>
+ * (list "name of variable" "type of variable")
+ * </pre>
+ */
+ static public LispForm getLocalVariableRep(LocalVariable lv) {
+ return new LispForm("(list"
+ + " \""+lv.name()+"\""
+ + " \""+lv.typeName()+"\")");
+ }
+
+ /**
+ * Returns a representation of a (local variable, value) pair.
+ * <p>
+ * <b>Syntax:</b>
+ * <pre>
+ * ({@link #getLocalVariableRep local-variable} . {@link #getValueRep value})
+ * </pre>
+ */
+ static public LispForm getLocalVariableValueRep(LocalVariable lv, Value v,
+ ObjectStore s) {
+ return new LispForm("(cons "+getLocalVariableRep(lv)
+ +" "+getValueRep(v, s)+")");
+ }
+
+ /**
+ * Returns a list of (local variable, value) pairs.
+ * <p>
+ * <b>Syntax:</b>
+ * <pre>
+ * (list [{@link #getLocalVariableValueRep (local variable, value) pair}]*)
+ * </pre>
+ */
+ static public LispForm getLocalVariableValueMapRep(Map map, ObjectStore s) {
+ String localVariablesValuesString = "(list ";
+ Set keys = map.keySet();
+ Iterator iter = keys.iterator();
+ while (iter.hasNext()) {
+ LocalVariable localVariable = (LocalVariable)iter.next();
+ Value val = (Value)map.get(localVariable);
+ localVariablesValuesString +=
+ BR +getLocalVariableValueRep(localVariable, val, s);
+ }
+ localVariablesValuesString += ")";
+ return new LispForm(localVariablesValuesString);
+ }
+
+
+ /**
+ * Returns a representation of a field.
+ * <p>
+ * <b>Syntax:</b>
+ * <pre>
+ * (list "name of field" "type of field" ["transient"]
["volatile"]
+ * ["final"] ["static"])
+ * </pre>
+ */
+ static LispForm getFieldRep(Field f) {
+ return new LispForm("(list"
+ + " \""+f.name()+"\""
+ + " \""+f.typeName()+"\""
+ + (f.isTransient() ? " \"transient\"" : "")
+ + (f.isVolatile() ? " \"volatile\"" : "")
+ + (f.isFinal() ? " \"final\"" : "")
+ + (f.isStatic() ? " \"static\"" : "")
+ +")");
+ }
+
+ /**
+ * Returns a representation of a (field, value) pair.
+ * <p>
+ * <b>Syntax:</b>
+ * <pre>
+ * ({@link #getFieldRep field} . {@link #getValueRep value})
+ * </pre>
+ */
+ static LispForm getFieldValueRep(Field f, Value v, ObjectStore s) {
+ return new LispForm("(cons "+getFieldRep(f)+" "+getValueRep(v,
s)+")");
+ }
+
+ /**
+ * Returns a list of (field, value) pairs.
+ * <p>
+ * <b>Syntax:</b>
+ * <pre>
+ * (list [{@link #getFieldValueRep (field, value) pair}]*)
+ * </pre>
+ */
+ static LispForm getFieldValueMapRep(Map map, ObjectStore s) {
+ String fieldsValuesString = "(list ";
+ Set keys = map.keySet();
+ Iterator iter = keys.iterator();
+ while (iter.hasNext()) {
+ Field field = (Field)iter.next();
+ Value val = (Value)map.get(field);
+ fieldsValuesString += BR +getFieldValueRep(field, val, s);
+ }
+ fieldsValuesString += ")";
+ return new LispForm(fieldsValuesString);
+ }
+
+ private static String filterFPValue(String fpValue) {
+ if (fpValue.equals("NaN"))
+ return "\"NaN\"";
+ else
+ if (fpValue.equals("-Infinity"))
+ return "\"-Infinity\"";
+ else
+ if (fpValue.equals("Infinity"))
+ return "\"Infinity\"";
+ else
+ return fpValue;
+ }
+
+
+
+ /**
+ * Returns a representation of a 'value', that can be primitive
+ * or an object reference, or void.
+ * <p>
+ * <b>Syntax:</b>
+ * <pre>
+ * (list "null")
+ * (list "void")
+ *
+ * {@link #getObjectRep(ObjectReference,ObjectStore) object-rep}
+ *
+ * (list "boolean" "true") (list "boolean"
"false")
+ * (list "byte" 'byte-value')
+ * (list "char" 'char-value')
+ * (list "double" double-value)
+ * (list "float" float-value)
+ * (list "int" int-value)
+ * (list "long" long-value)
+ * (list "short" short-value)
+ * </pre>
+ */
+ static public LispForm getValueRep(Value value, ObjectStore store) {
+ if (value == null) {
+ return new LispForm("(list \"null\")");
+ } else if (value instanceof VoidValue) {
+ return new LispForm("(list \"void\")");
+ } else if (value instanceof ObjectReference) {
+ return getObjectRep((ObjectReference)value, store);
+ } else {
+ PrimitiveValue v = (PrimitiveValue)value;
+ if (v instanceof BooleanValue) {
+ return new LispForm("(list \"boolean\"
\""+v.booleanValue()+"\")");
+ } else if (v instanceof ByteValue) {
+ return new LispForm("(list \"byte\"
\""+v.byteValue()+"\")");
+ } else if (v instanceof CharValue) {
+ return new LispForm("(list \"char\" \""+
+ escapeString(String.valueOf(v.charValue()))+"\")");
+ } else if (v instanceof DoubleValue) {
+ String sv = "" + v.doubleValue();
+ return new LispForm("(list \"double\"
"+filterFPValue(sv)+")");
+ } else if (v instanceof FloatValue) {
+ String sv = "" + v.floatValue();
+ return new LispForm("(list \"float\"
"+filterFPValue(sv)+")");
+ } else if (v instanceof IntegerValue) {
+ return new LispForm("(list \"int\"
\""+v.intValue()+"\")");
+ } else if (v instanceof LongValue) {
+ return new LispForm("(list \"long\"
\""+v.longValue()+"\")");
+ } else if (v instanceof ShortValue) {
+ return new LispForm("(list \"short\"
"+v.shortValue()+")");
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns information about an array
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * "Error message"
+ * (list "type name" uniqueID ['t|nil] length [element]*)
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> The third argument (['t|nil]) indicates if the object has
+ * been garbage collected in the debugee vm: it's nil if it hasn't.
+ * <li> elements are only present if the index/length make sense. See
+ * param list.
+ * </ul>
+ * <p>
+ *
+ * @param index if -1, represents the begin of index from where
+ * elements are to be sent
+ * @param length Number of elements to be sent
+ */
+ static public LispForm getArrayRep(ArrayReference a, ObjectStore store,
+ int index, int length) {
+ if (a == null) {
+ return new LispForm("\"Error!\"");
+ } else {
+ store.put(a);
+
+ String elementsString = "";
+ try {
+ if (index != -1) {
+ List elements = a.getValues(index, length);
+ Iterator it = elements.iterator();
+ while (it.hasNext()) {
+ elementsString += " "+getValueRep((Value)it.next(),
+ store);
+ }
+ }
+ } catch (IndexOutOfBoundsException ex) {
+ elementsString = "\"Index out of bounds\"";
+ } catch (ObjectCollectedException ex) {
+ elementsString = "\"The object has already been collected\"";
+ }
+ return new LispForm("(list "
+ + "\""+a.referenceType().name()+"\""
+ + " " +a.uniqueID()
+ + (a.isCollected() ? " 't":" nil")
+ + " " + a.length()
+ + elementsString + ")");
+ }
+ }
+
+
+ /**
+ * Prefix \ escapes to all \ and " characters in a string so that
+ * the string can be read byte the Lisp interpreter. For efficiency,
+ * if no such characters are found, the argument String itself
+ * is returned.
+ *
+ * @param str String to be prefixed.
+ * @return A String.
+ *
+ * @author David Hay
+ * @author Mark Gibson
+ * @author Steve Haflich
+ * @author Charles Hart
+ * @author David Dagon
+ */
+ public static String escapeString (String str) {
+
+ if ( str.indexOf('\\') == -1 &&
+ str.indexOf('"') == -1 )
+ {
+ return str;
+ }
+ else
+ {
+ StringBuffer buf = new StringBuffer(str.length() + 16);
+ for ( int i = 0; i < str.length(); i++ ) {
+ char ch = str.charAt( i );
+ switch ( ch ) {
+ case '"': buf.append("\\\"" ); break;
+ case '\\': buf.append("\\\\" ); break;
+ default: buf.append( ch ); break;
+ }
+ }
+ return buf.toString();
+ }
+ }
+
+
+
+ /**
+ * Returns the value of a string
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * "Error message"
+ * (list "java.lang.String" uniqueID ['t|nil]
"string-value")
+ * </pre>
+ * <b>Comments:</b>
+ * <ul>
+ * <li> The third argument (['t|nil]) indicates if the object has
+ * been garbage collected in the debugee vm: it's nil if it hasn't.
+ * </ul>
+ * <p>
+ */
+ static public LispForm getStringRep(StringReference s, ObjectStore store) {
+ if (s == null) {
+ return new LispForm("\"Error!\"");
+ } else {
+ store.put(s);
+
+ return new LispForm("(list "
+ + "\""+s.referenceType().name()+"\""
+ + " "+s.uniqueID()
+ + (s.isCollected() ? " 't":" nil")
+ + " \"" + escapeString(s.value()) + "\")");
+ }
+ }
+
+
+ /**
+ * Returns a non-detailed representation of an object.
+ *
+ * @see #getObjectRep(ObjectReference,ObjectStore,boolean)
+ */
+ static public LispForm getObjectRep(ObjectReference o, ObjectStore store) {
+ return getObjectRep(o, store, false);
+ }
+
+ /**
+ * Returns a canonical representation of an object.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * "Error Message"
+ * (list "null")
+ * <i>Non-detailed</i>
+ * (list "type of object" uniqueID ['t|nil])
+ * <i>Detailed</i>
+ * (list "type of object" uniqueID ['t|nil] {@link #getFieldValueMapRep
fields-values})
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> The third argument (['t|nil]) indicates if the object has
+ * been garbage collected in the debugee vm: it's nil if it hasn't.
+ * </ul>
+ */
+ static public LispForm getObjectRep(ObjectReference o, ObjectStore store,
+ boolean detailed) {
+ if (o == null) {
+ return new LispForm("(list \"null\")");
+ } else {
+ store.put(o);
+ if (detailed) {
+ // fields and values
+ String fieldsValuesString;
+ try {
+ // XXX a more complete list is available using
+ // allFields().... fyi
+ fieldsValuesString =
getFieldValueMapRep(o.getValues(o.referenceType().visibleFields()), store).toString();
+ } catch (ClassNotPreparedException ex) {
+ fieldsValuesString = "\"The class isn't prepared\"";
+ } catch (ObjectCollectedException ex) {
+ fieldsValuesString = "\"The object has already been
collected\"";
+ } catch (Exception ex) {
+ fieldsValuesString = "\"Unable to access fields and values. Optimized
class?\"";
+ }
+
+ return new LispForm("(list "
+ + "\""+o.referenceType().name()+"\""
+ + " "+o.uniqueID()
+ + (o.isCollected() ? " 't":" nil")+BR
+ + fieldsValuesString+")");
+ } else {
+ return new LispForm("(list "
+ + "\""+o.referenceType().name()+"\""
+ + " "+o.uniqueID()
+ + (o.isCollected() ? " 't":" nil")
+ +")");
+ }
+ }
+ }
+
+
+ /*
+ * THREAD REPRESENTATIONS
+ */
+
+ /**
+ * Returns information about monitors of an object.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * (list uniqueID "type of object" ['t|nil] {@link #getThreadRep
owning-thread} (list [{@link #getThreadRep waiting-thread}]*))
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> The third argument (['t|nil]) indicates if the object has
+ * been garbage collected in the debugee vm: it's nil if it hasn't.
+ * </ul>
+ */
+ static public LispForm getObjectMonitorsRep(ObjectReference o, ObjectStore store) {
+ if (o == null) {
+ return new LispForm("null");
+ } else {
+ store.put(o);
+
+ // owning thread
+ String owningThread;
+ try {
+ ThreadReference t = o.owningThread();
+ if (t == null) {
+ owningThread = "nil";
+ } else {
+ owningThread = getThreadRep(t, store).toString();
+ }
+ } catch (IncompatibleThreadStateException ex) {
+ owningThread = "\"Information Not Available\"";
+ } catch (UnsupportedOperationException ex) {
+ owningThread = "\"VM has no information\"";
+ }
+
+ // waiting threads
+ String waitingThreadsString;
+ try {
+ waitingThreadsString = "(list";
+ List waitingThreads = o.waitingThreads();
+ Iterator it = waitingThreads.iterator();
+ while (it.hasNext()) {
+ waitingThreadsString += BR +getThreadRep((ThreadReference)it.next(), store);
+ }
+ waitingThreadsString += ")";
+ } catch (IncompatibleThreadStateException ex) {
+ waitingThreadsString = "\"Information Not Available\"";
+ } catch (UnsupportedOperationException ex) {
+ waitingThreadsString = "\"VM has no information\"";
+ }
+
+
+ return new LispForm("(list "+o.uniqueID()+" "
+ +"\""+o.referenceType().name()+"\""
+ + (o.isCollected() ? " 't":" nil")+BR
+ +owningThread+ BR
+ +waitingThreadsString+")");
+ }
+ }
+
+ /* thread information retrieval routines */
+
+
+
+ /**
+ * Returns a canonical representation of a given ThreadGroupReference.
+ * <p>
+ * <b>Syntax:</b>
+ * <pre>
+ * (list "ThreadGroup" uniqueID "name of threadgroup"
+ * (list [{@link #getThreadRep(ThreadReference, ObjectStore)
child thread}]*)
+ * (list [{@link #getThreadGroupRep child threadgroup}]*))
+ * </pre>
+ */
+ static LispForm getThreadGroupRep(ThreadGroupReference t,
+ ObjectStore store) {
+ store.put(t);
+ String rep = "(list \"ThreadGroup\" "+t.uniqueID()
+ +" \""+t.name()+"\" ";
+
+ List list = t.threads();
+ Iterator it = list.iterator();
+ rep += BR+"(list";
+ while (it.hasNext()) {
+ rep += BR +getThreadRep((ThreadReference)it.next(), store);
+ }
+ rep += ")";
+
+ list = t.threadGroups();
+ it = list.iterator();
+ rep += BR+"(list";
+ while (it.hasNext()) {
+ rep += BR +getThreadGroupRep((ThreadGroupReference)it.next(), store);
+ }
+ rep += ")";
+
+ rep += ")";
+
+ return new LispForm(rep);
+ }
+
+ /**
+ * Returns a detailed thread representation.
+ * @see #getThreadRep(ThreadReference, ObjectStore, boolean)
+ */
+ static public LispForm getThreadRep(ThreadReference t, ObjectStore store) {
+ return getThreadRep(t, store, true);
+ }
+
+ /**
+ * Returns a canonical representation of a given ThreadReference.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * <i>Non-detailed</i>
+ * (list "Thread" uniqueID "name of thread"
<u>status</u> <u>currentState</u>)
+ * <i>Detailed</i>
+ * (list "Thread" uniqueID "name of thread" status currentState
+ * (list [{@link #getStackFrameRep stack-frame}]*)
+ * <u>owned-monitors-string</u>
+ * <u>current-contended-monitor-string</u>)
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> <u>status</u> is one of: "unknown", "waiting
on monitor",
+ * "not started", "runnable", "sleeping",
"waiting", and "zombie"
+ *
+ * <li> <u>currentState</u> is one of "normal",
"suspended by debugger",
+ * and "suspended at breakpoint"
+
+ * <li> <u>owned-monitors-string</u>:
+ * <pre>
+ * "Error Message"
+ * (list [{@link #getObjectRep(ObjectReference, ObjectStore) owned monitor}]*)
+ * </pre>
+ * <li> <u>current-contended-monitor-string</u>:
+ * <pre>
+ * "Error Message"
+ * nil
+ * {@link #getObjectRep(ObjectReference, ObjectStore) current contended monitor}
+ * </pre>
+ * <li>
+ * Examples:
+ * <pre>
+ * (list "Thread" 53 "Thread 1, continuous"
+ * "suspended by debugger" "waiting on monitor"
+ * (list
+ * (list 0 "test.Test" "Test.java" 45))
+ * (list)
+ * (list "java.lang.String" 55))
+ *
+ * (list "Thread" 54 "Thread 2"
+ * "suspended by debugger" "waiting on monitor"
+ * (list
+ * (list 0 "java.lang.Thread" "Thread.java" -1)
+ * (list 1 "test.Test" "Test.java" 47))
+ * (list
+ * (list "java.lang.String" 55)
+ * (list "java.lang.Integer" 61))
+ * (list))
+ * </pre>
+ * </ul>
+ *
+ * <p>
+ * @param detailed True if a more detailed representation is desired:
+ * includes the stackframe as well as information about the monitors.
+ */
+ static public LispForm getThreadRep(ThreadReference t, ObjectStore store,
+ boolean detailed) {
+ int status = t.status();
+ String statusString = "unknown";
+ switch (status) {
+ case ThreadReference.THREAD_STATUS_MONITOR: {
+ statusString = "waiting on monitor";
+ break;
+ }
+ case ThreadReference.THREAD_STATUS_NOT_STARTED: {
+ statusString = "not started";
+ break;
+ }
+ case ThreadReference.THREAD_STATUS_RUNNING: {
+ statusString = "runnable";
+ break;
+ }
+ case ThreadReference.THREAD_STATUS_SLEEPING: {
+ statusString = "sleeping";
+ break;
+ }
+ case ThreadReference.THREAD_STATUS_WAIT: {
+ statusString = "waiting";
+ break;
+ }
+ case ThreadReference.THREAD_STATUS_ZOMBIE: {
+ statusString = "zombie";
+ break;
+ }
+ case ThreadReference.THREAD_STATUS_UNKNOWN: {
+ statusString = "unknown";
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+
+ // note that the above status string refers to the state of the
+ // thread *before* a suspension, if there was a suspension.
+
+ /* Due to a bug in ThreadReference.isSuspended(), we need to
+ use suspendCount() */
+ String stateString = "normal";
+ if (t.isAtBreakpoint()) {
+ stateString = "suspended at breakpoint";
+ } else if (t.suspendCount() > 0) {
+ stateString = "suspended by debugger";
+ }
+
+ if (detailed) {
+
+ // info on the stack
+
+ String stackString;
+ try {
+ stackString = "(list";
+ // a list of the stackframes is also sent...
+ List stackFrames = t.frames();
+ Iterator it = stackFrames.iterator();
+ int index = 0;
+ while (it.hasNext()) {
+ stackString += BR + getStackFrameRep((StackFrame)it.next(), index++);
+ }
+ stackString += ")";
+ } catch (IncompatibleThreadStateException ex) {
+ stackString = "\"Information Not Available\"";
+ }
+
+ // info on the monitors
+
+ // owned monitors
+
+ String ownedMonitorsString;
+ try {
+ ownedMonitorsString = "(list";
+ List ownedMonitors = t.ownedMonitors();
+ Iterator it = ownedMonitors.iterator();
+ while (it.hasNext()) {
+ ownedMonitorsString += BR +getObjectRep((ObjectReference)it.next(), store);
+ }
+ ownedMonitorsString += ")";
+ } catch (IncompatibleThreadStateException ex) {
+ ownedMonitorsString = "\"Information Not Available\"";
+ } catch (UnsupportedOperationException ex) {
+ ownedMonitorsString = "\"VM has no information\"";
+ } catch (ObjectCollectedException ex) {
+ ownedMonitorsString = "\"The object has been collected\"";
+ }
+
+ // current contended monitor
+ // note, however, from the jdi api:
+ // The thread can be waiting for a monitor through entry into a
+ // synchronized method, the synchronized statement, or
+ // Object.wait(). The status() method can be used to
+ // differentiate between the first two cases and the third.
+
+ String currentContendedMonitorString;
+ try {
+ ObjectReference o = t.currentContendedMonitor();
+ if (o == null) {
+ currentContendedMonitorString = "nil";
+ } else {
+ currentContendedMonitorString =
+ getObjectRep(o, store).toString();
+ }
+ } catch (IncompatibleThreadStateException ex) {
+ currentContendedMonitorString =
+ "\"Information Not Available\"";
+ } catch (UnsupportedOperationException ex) {
+ currentContendedMonitorString =
+ "\"VM has no information\"";
+ } catch (ObjectCollectedException ex) {
+ currentContendedMonitorString =
+ "\"The object has been collected\"";
+ }
+
+ store.put(t);
+ return new LispForm("(list \"Thread\""
+ +" "+t.uniqueID()
+ +" \""+t.name()+"\""
+ +" \""+statusString+"\""
+ +" \""+stateString+"\""
+ + BR +stackString
+ + BR +ownedMonitorsString
+ + BR +currentContendedMonitorString
+ +")");
+ } else {
+ store.put(t);
+ return new LispForm("(list \"Thread\""
+ +" "+t.uniqueID()
+ +" \""+t.name()+"\""
+ +" \""+statusString+"\""
+ +" \""+stateString+"\")");
+ }
+ }
+
+ /**
+ * Returns a canonical representation of a given StackFrame.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * (list "StackFrame" index "Information not available")
+ * (list "StackFrame" index "type name" "source name"
lineNumber "method name")
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> lineNumber is -1 for native methods
+ * </ul>
+ *
+ * @param index Gives the index of this particular stack frame for
+ * the thread. This basically goes into the string returned as a
+ * convenience.
+ */
+ static LispForm getStackFrameRep(StackFrame s, int index) {
+ try {
+ Location loc = s.location();
+ Method method = loc.method();
+ return new LispForm("(list "+index+" "
+ +"\""+loc.declaringType().name()+"\" "
+ +"\""+loc.sourceName()+"\" "
+ +loc.lineNumber()+" "
+ +"\""+method.name()+"\")");
+ } catch (AbsentInformationException ex) {
+ return new LispForm("(list \"StackFrame\" "+index
+ +" \"Information not available\")");
+ }
+ }
+
+} // Rep
+
+/*
* $Log: Rep.java,v $
- * Revision 1.1 2000/08/13 13:36:10 michaels
- * Initial checkin.
- *
- * Revision 1.12 2000/04/10 05:57:30 paulk
- * Publicized some methods.
- *
- * Revision 1.11 2000/04/01 06:02:37 paulk
- * Wrap NaN, Infinity, and -Infinity values in quotes to prevent Lisp evaluation errors.
- *
- * Revision 1.10 2000/03/17 03:35:23 paulk
- * Enhanced getStackFrameRep to return method. Thanks to Paul Michael Reilly
<pmr(a)pajato.com>.
- *
- * Revision 1.9 2000/03/10 06:53:25 paulk
- * Escape quotes in strings.
- *
- * Revision 1.8 2000/03/04 08:58:11 paulk
- * Put quotes around byte, int, and long values to avoid Lisp
- * representation problems. Thanks to Charles Hart <cfhart(a)Z-TEL.com> for this
fix.
- *
- */
-
-// End Rep.java
+ * Revision 1.15 2001/04/19 04:43:55 paulk
+ * Now escapes char values.
+ *
+ * Revision 1.14 2001/03/24 05:36:49 paulk
+ * Updated to reflect reorganization of debuggee code.
+ *
+ * Revision 1.13 2000/07/28 06:26:31 paulk
+ * Committing all modified files.
+ *
+ * Revision 1.12 2000/04/10 05:57:30 paulk
+ * Publicized some methods.
+ *
+ * Revision 1.11 2000/04/01 06:02:37 paulk
+ * Wrap NaN, Infinity, and -Infinity values in quotes to prevent Lisp evaluation
errors.
+ *
+ * Revision 1.10 2000/03/17 03:35:23 paulk
+ * Enhanced getStackFrameRep to return method. Thanks to Paul Michael Reilly
<pmr(a)pajato.com>.
+ *
+ * Revision 1.9 2000/03/10 06:53:25 paulk
+ * Escape quotes in strings.
+ *
+ * Revision 1.8 2000/03/04 08:58:11 paulk
+ * Put quotes around byte, int, and long values to avoid Lisp
+ * representation problems. Thanks to Charles Hart <cfhart(a)Z-TEL.com> for this
fix.
+ *
+ */
+
+// End Rep.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/AttachShmem.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/command/AttachShmem.java,v
retrieving revision 1.1
diff -u -r1.1 AttachShmem.java
--- xemacs-packages/jde/java/src/jde/debugger/command/AttachShmem.java 2000/08/13
13:49:11 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/command/AttachShmem.java 2001/08/15
05:27:47
@@ -1,106 +1,106 @@
-/*
- * Copyright (c) 2000 Paul Kinnucan
- *
- * $Revision: 1.1 $
- */
-
-package jde.debugger.command;
-import com.sun.jdi.connect.AttachingConnector;
-import jde.debugger.JDEException;
-import java.util.Map;
-import com.sun.jdi.connect.Connector;
-import com.sun.jdi.VirtualMachine;
-import jde.debugger.Application;
-import java.io.IOException;
-import com.sun.jdi.connect.IllegalConnectorArgumentsException;
-import jde.debugger.Jdebug;
-import jde.debugger.Debug;
-
-
-/**
- * Attaches to an already running application through shared memory.
- * <p>
- *
- * <b>Syntax:</b>
- * <pre>
- * attach_shmem app_id name
- * </pre>
- *
- * <b>Comments:</b>
- * <ul>
- * <li> The debugee vm has to have been launched with the right parameters.
- * See the <italic>Connection and Invocation</italic> section of the
- * JPDA documentation.
- * </ul>
- *
- * @author Paul Kinnucan
- * @version $Revision: 1.1 $
- */
-public class AttachShmem extends DebugSessionCommand {
-
- protected void doCommand() throws JDEException {
-
- // the attaching connector...
- String connectSpec = null;
- connectSpec = "com.sun.jdi.SharedMemoryAttach";
-
- AttachingConnector connector = (AttachingConnector) getConnector(connectSpec);
- if (connector == null)
- throw new JDEException("No such connector is available: "+connectSpec);
-
- if (args.size() < 1)
- throw new JDEException("Missing name");
-
- try {
- Map argumentMap = connector.defaultArguments();
-
- Connector.Argument nameArg =
- (Connector.Argument)argumentMap.get("name");
- nameArg.setValue(args.remove(0).toString());
-
- VirtualMachine vm = connector.attach(argumentMap);
-
-
- // note that new App might raise a jdeexception.
- Application app = new Application(Jdebug.theDebugger, appID, vm);
-
- if (Jdebug.theDebugger.appExists(appID)) {
- app.shutdown();
- throw new JDEException("An application with the ID" + appID +
- " already exists.");
- }
-
- Jdebug.theDebugger.addApplication(appID, app);
-
- app.signalCommandResult(cmdID);
-
- app.signal(MESSAGE, "Attached VM (shmem) " + vm.description());
-
- } catch (IOException ex) {
- Debug.printIf(ex);
- throw new JDEException("Error attempting to attach to process via shared
memory.");
- } catch (IllegalConnectorArgumentsException ex) {
- throw new JDEException("Illegal connector arguments for connector
'"+connector);
- }
- }
-
- public Object clone() {return new AttachShmem();}
-
-
-} // AttachShmem
-
-
-/*
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.3 $
+ */
+
+package jde.debugger.command;
+import com.sun.jdi.connect.AttachingConnector;
+import jde.debugger.JDEException;
+import java.util.Map;
+import com.sun.jdi.connect.Connector;
+import com.sun.jdi.VirtualMachine;
+import jde.debugger.DebuggeeProcess;
+import java.io.IOException;
+import com.sun.jdi.connect.IllegalConnectorArgumentsException;
+import jde.debugger.Jdebug;
+import jde.debugger.Debug;
+
+
+/**
+ * Attaches to an already running application through shared memory.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * attach_shmem app_id name
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> The debugee vm has to have been launched with the right parameters.
+ * See the <italic>Connection and Invocation</italic> section of the
+ * JPDA documentation.
+ * </ul>
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.3 $
+ */
+public class AttachShmem extends DebugSessionCommand {
+
+ protected void doCommand() throws JDEException {
+
+ // the attaching connector...
+ String connectSpec = null;
+ connectSpec = "com.sun.jdi.SharedMemoryAttach";
+
+ AttachingConnector connector = (AttachingConnector) getConnector(connectSpec);
+ if (connector == null)
+ throw new JDEException("No such connector is available: "+connectSpec);
+
+ if (args.size() < 1)
+ throw new JDEException("Missing name");
+
+ try {
+ Map argumentMap = connector.defaultArguments();
+
+ Connector.Argument nameArg =
+ (Connector.Argument)argumentMap.get("name");
+ nameArg.setValue(args.remove(0).toString());
+
+ VirtualMachine vm = connector.attach(argumentMap);
+
+
+ // note that new process might raise a jdeexception.
+ DebuggeeProcess proc = new DebuggeeProcess(procID, vm);
+
+ if (procRegistry.processExists(procID)) {
+ proc.shutdown();
+ throw new JDEException("A process with the ID" + procID +
+ " already exists.");
+ }
+
+ procRegistry.addProcess(procID, proc);
+
+ jde.signalCommandResult(procID, cmdID);
+
+ jde.signal(procID, MESSAGE, "Attached VM (shmem) " + vm.description());
+
+ } catch (IOException ex) {
+ Debug.printIf(ex);
+ throw new JDEException("Error attempting to attach to process via shared
memory.");
+ } catch (IllegalConnectorArgumentsException ex) {
+ throw new JDEException("Illegal connector arguments for connector
'"+connector);
+ }
+ }
+
+ public Object clone() {return new AttachShmem();}
+
+
+} // AttachShmem
+
+
+/*
* $Log: AttachShmem.java,v $
- * Revision 1.1 2000/08/13 13:49:11 michaels
- * Initial checkin
- *
- * Revision 1.2 2000/02/02 05:58:12 paulk
- * Added command succeeded messages.
- *
- * Revision 1.1 2000/01/31 12:44:15 paulk
- * Attach existing application through shared memory.
- *
- */
-
-// End of AttachShmem.java
+ * Revision 1.3 2001/03/24 05:42:36 paulk
+ * Updated to reflect reorganization of debugger code.
+ *
+ * Revision 1.2 2000/02/02 05:58:12 paulk
+ * Added command succeeded messages.
+ *
+ * Revision 1.1 2000/01/31 12:44:15 paulk
+ * Attach existing application through shared memory.
+ *
+ */
+
+// End of AttachShmem.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/AttachSocket.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/command/AttachSocket.java,v
retrieving revision 1.1
diff -u -r1.1 AttachSocket.java
--- xemacs-packages/jde/java/src/jde/debugger/command/AttachSocket.java 2000/08/13
13:49:11 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/command/AttachSocket.java 2001/08/15
05:27:47
@@ -1,130 +1,133 @@
-/*
- * Copyright (c) 2000 Paul Kinnucan
- *
- * $Revision: 1.1 $
- */
-
-package jde.debugger.command;
-import jde.debugger.JDEException;
-import com.sun.jdi.connect.AttachingConnector;
-import java.util.Map;
-import com.sun.jdi.connect.Connector;
-import com.sun.jdi.VirtualMachine;
-import jde.debugger.Application;
-import jde.debugger.Jdebug;
-import java.io.IOException;
-import jde.debugger.Debug;
-import com.sun.jdi.connect.IllegalConnectorArgumentsException;
-
-
-/**
- * Attaches to an already running application through a socket.
- * <p>
- *
- * <b>Syntax:</b>
- * <pre>
- * attach_socket app_id -port p_value [-host h_value]
- * </pre>
- *
- * <b>Comments:</b>
- * <ul>
- * <li> The debugee vm has to have been launched with the right parameters.
- * See the <italic>Connection and Invocation</italic> section of the
- * JPDA documentation.
- * </ul>
- *
- * @author Paul Kinnucan
- * @version $Revision: 1.1 $
- */
-public class AttachSocket extends DebugSessionCommand {
-
- /**
- *
- * @exception jde.debugger.JDEException <description>
- */
- protected void doCommand() throws JDEException {
-
- // the attaching connector...
- String connectSpec = null;
- connectSpec = "com.sun.jdi.SocketAttach";
-
-
- AttachingConnector connector = (AttachingConnector) getConnector(connectSpec);
- if (connector == null)
- throw new JDEException("No such connector is available: "+connectSpec);
-
- if (args.size() < 1)
- throw new JDEException("Missing arguments: specify at least the port");
-
- try {
- Map argumentMap = connector.defaultArguments();
-
- while ((args.size() > 0)
- && args.get(0).toString().startsWith("-")) {
- String arg = args.remove(0).toString().toLowerCase();
- if (arg.equals("-host")) {
- if (args.size() == 0)
- throw new JDEException("Missing argument to 'host'");
- String host = args.remove(0).toString();
- Connector.Argument hostArg =
- (Connector.Argument)argumentMap.get("host");
- hostArg.setValue(host);
- } else if (arg.equals("-port")) {
- if (args.size() == 0)
- throw new JDEException("Missing argument to 'port'");
- String port = args.remove(0).toString();
- Connector.Argument portArg =
- (Connector.Argument)argumentMap.get("port");
- portArg.setValue(port);
- } else {
- args.add(0, arg);
- break;
- }
- }
-
- VirtualMachine vm = connector.attach(argumentMap);
-
- // note that new App might raise a jdeexception.
- Application app = new Application(Jdebug.theDebugger, appID, vm);
-
- if (Jdebug.theDebugger.appExists(appID)) {
- app.shutdown();
- throw new JDEException("An application with the ID " + appID +
- " already exists.");
- }
-
- Jdebug.theDebugger.addApplication(appID, app);
-
- app.signalCommandResult(cmdID);
-
- app.signal(MESSAGE, "Attached VM (socket) " + vm.description());
-
- } catch (IOException ex) {
- Debug.printIf(ex);
- throw new JDEException("I/O error occurred while attempting to attach
process.");
- } catch (IllegalConnectorArgumentsException ex) {
- throw new JDEException("Illegal connector arguments for connector
'"+connector);
- }
-
- }
-
- public Object clone() {return new AttachSocket();}
-
-
-} // AttachSocket
-
-
-/*
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.4 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+import com.sun.jdi.connect.AttachingConnector;
+import java.util.Map;
+import com.sun.jdi.connect.Connector;
+import com.sun.jdi.VirtualMachine;
+import jde.debugger.DebuggeeProcess;
+import jde.debugger.Jdebug;
+import java.io.IOException;
+import jde.debugger.Debug;
+import com.sun.jdi.connect.IllegalConnectorArgumentsException;
+
+
+/**
+ * Attaches to an already running application through a socket.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * attach_socket app_id -port p_value [-host h_value]
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> The debugee vm has to have been launched with the right parameters.
+ * See the <italic>Connection and Invocation</italic> section of the
+ * JPDA documentation.
+ * </ul>
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.4 $
+ */
+public class AttachSocket extends DebugSessionCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ protected void doCommand() throws JDEException {
+
+ // the attaching connector...
+ String connectSpec = null;
+ connectSpec = "com.sun.jdi.SocketAttach";
+
+
+ AttachingConnector connector = (AttachingConnector) getConnector(connectSpec);
+ if (connector == null)
+ throw new JDEException("No such connector is available: "+connectSpec);
+
+ if (args.size() < 1)
+ throw new JDEException("Missing arguments: specify at least the port");
+
+ try {
+ Map argumentMap = connector.defaultArguments();
+
+ while ((args.size() > 0)
+ && args.get(0).toString().startsWith("-")) {
+ String arg = args.remove(0).toString().toLowerCase();
+ if (arg.equals("-host")) {
+ if (args.size() == 0)
+ throw new JDEException("Missing argument to 'host'");
+ String host = args.remove(0).toString();
+ Connector.Argument hostArg =
+ (Connector.Argument)argumentMap.get("hostname");
+ hostArg.setValue(host);
+ } else if (arg.equals("-port")) {
+ if (args.size() == 0)
+ throw new JDEException("Missing argument to 'port'");
+ String port = args.remove(0).toString();
+ Connector.Argument portArg =
+ (Connector.Argument)argumentMap.get("port");
+ portArg.setValue(port);
+ } else {
+ args.add(0, arg);
+ break;
+ }
+ }
+
+ VirtualMachine vm = connector.attach(argumentMap);
+
+ // note that new process might raise a jdeexception.
+ DebuggeeProcess proc = new DebuggeeProcess(procID, vm);
+
+ if (procRegistry.processExists(procID)) {
+ proc.shutdown();
+ throw new JDEException("A process with the ID " + procID +
+ " already exists.");
+ }
+
+ procRegistry.addProcess(procID, proc);
+
+ jde.signalCommandResult(procID, cmdID);
+
+ jde.signal(procID, MESSAGE, "Attached VM (socket) " + vm.description());
+
+ } catch (IOException ex) {
+ Debug.printIf(ex);
+ throw new JDEException("I/O error occurred while attempting to attach
process.");
+ } catch (IllegalConnectorArgumentsException ex) {
+ throw new JDEException("Illegal connector arguments for connector
'"+connector);
+ }
+
+ }
+
+ public Object clone() {return new AttachSocket();}
+
+
+} // AttachSocket
+
+
+/*
* $Log: AttachSocket.java,v $
- * Revision 1.1 2000/08/13 13:49:11 michaels
- * Initial checkin
- *
- * Revision 1.2 2000/02/02 05:58:12 paulk
- * Added command succeeded messages.
- *
- * Revision 1.1 2000/01/31 12:45:08 paulk
- * Attach existing application through socket.
- *
- */
-
-// End of AttachSocket.java
+ * Revision 1.4 2001/03/24 05:42:36 paulk
+ * Updated to reflect reorganization of debugger code.
+ *
+ * Revision 1.3 2000/08/09 03:43:07 paulk
+ * Fixed bug where JDEBug would not attach to a process running on a remote host because
it was setting the wrong connector argument (host instead of hostname). Thanks to Matthew
Conway <matt_conway(a)i2.com>.
+ *
+ * Revision 1.2 2000/02/02 05:58:12 paulk
+ * Added command succeeded messages.
+ *
+ * Revision 1.1 2000/01/31 12:45:08 paulk
+ * Attach existing application through socket.
+ *
+ */
+
+// End of AttachSocket.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/Break.java
===================================================================
RCS file: Break.java
diff -N Break.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ Break.java Tue Aug 14 22:27:47 2001
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.1 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+import jde.debugger.spec.EventRequestSpec;
+import jde.debugger.Etc;
+import jde.debugger.spec.EventRequestSpecList;
+
+
+/**
+ * 'break' command.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * break {@link #doBreakInMethod in_method} class method [(args)]
+ * [{@link Etc#getThreadFromArgs(List) thread-restriction}]
+ * [{@link Etc#getExprFromArgs(List) expression-restriction}]
+ * [{@link Etc#getSuspendPolicyFromArgs(List) suspend-policy}]
+ *
+ * break {@link #doBreakOnLine on_line} class line
+ * [{@link Etc#getThreadFromArgs(List) thread-restriction}]
+ * [{@link Etc#getExprFromArgs(List) expression-restriction}]
+ * [{@link Etc#getSuspendPolicyFromArgs(List) suspend-policy}]
+ *
+ * break {@link #doBreakAbsolute absolute} file line
+ * [{@link Etc#getThreadFromArgs(List) thread-restriction}]
+ * [{@link Etc#getExprFromArgs(List) expression-restriction}]
+ * [{@link Etc#getSuspendPolicyFromArgs(List) suspend-policy}]
+ * </pre>
+ *
+ * <b>Returns:</b>
+ * <pre>
+ * (jde-dbo-command-result cmdID specID)
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> There are exactly three kinds of 'break' commands. One
+ * of in_method, on_line, or absolute need to be used.
+ * <li> 'class' can be a string pattern of the type *.Test
+ * <li> specID is a 'long', that can be used in 'clear' commands.
+ * </ul>
+ *
+ * <p>
+ * @see EventHandler#breakpointEvent(BreakpointEvent)
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.1 $
+ *
+ */
+public class Break extends DebugProcessCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ public void doCommand() throws JDEException {
+ try {
+ // whatever function is called, should do a signalCommandResult
+ // during the execution.
+ String type = args.remove(0).toString().toLowerCase();
+ if (type.equals("in_method")) {
+ doBreakInMethod(args);
+ } else if (type.equals("on_line")) {
+ doBreakOnLine(args);
+ } else if (type.equals("absolute")) {
+ doBreakAbsolute(args);
+ } else
+ throw new JDEException("Syntax error: expecting one of 'in_method',
'on_line', or 'absolute'; '"+type+"' is not
supported");
+ } catch (UnsupportedOperationException ex) {
+ throw new JDEException("Unspecified Error occured");
+ } catch (IndexOutOfBoundsException ex) {
+ throw new JDEException("Syntax error: argument missing");
+ }
+ }
+
+
+ /**
+ * A break in a particular method.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * break in_method class method [(arg1,arg2,...)]
+ * [{@link Etc#getThreadFromArgs(List) thread-restriction}]
+ * [{@link Etc#getExprFromArgs(List) expression-restriction}]
+ * [{@link Etc#getSuspendPolicyFromArgs(List) suspend-policy}]
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> There should be <b>no spaces</b> before or after the
','; when
+ * the arguments are supplied.
+ * <li> A void method should be indicated by <code>()</code>
+ * <li> A unique method doesn't need to supply the arguments. The
+ * <b>entire</b> argument list should be absent in this case.
+ * </ul>
+ */
+ public void doBreakInMethod(List args)
+ throws JDEException {
+
+ if (args.size() < 2)
+ throw new JDEException("Insufficient arguments");
+
+ String classPattern = args.remove(0).toString();
+ String method = args.remove(0).toString();
+
+ // the argument list
+ List argumentList = null;
+
+ // see if more arguments are present
+ if (args.size() > 0) {
+
+ String arg = args.remove(0).toString();
+
+ // see if any arglist was provided at all
+ if (arg.startsWith("(")) {
+ // apparently it was. double check.
+ if (!arg.endsWith(")")) {
+ throw new JDEException("The argument list seems to be corrupt");
+ }
+ // trim the parens
+ arg = arg.substring(1, arg.length() - 1);
+ argumentList = new ArrayList();
+ StringTokenizer t = new StringTokenizer(arg, ",");
+ while (t.hasMoreTokens()) {
+ argumentList.add(t.nextToken());
+ }
+ }
+ }
+ EventRequestSpecList eventRequests = proc.getEventRequestSpecs();
+ EventRequestSpec er = eventRequests.createMethodBreakpoint(classPattern, method,
argumentList);
+ er.setThread(Etc.getThreadFromArgs(args));
+ er.setExpression(Etc.getExprFromArgs(args));
+ er.setSuspendPolicy(Etc.getSuspendPolicyFromArgs(args));
+ eventRequests.install(er);
+
+ jde.signalCommandResult(procID, cmdID, er.getID());
+ }
+
+ /** A break on a particular line of a class */
+ public void doBreakOnLine(List args)
+ throws JDEException {
+
+ if (args.size() < 2)
+ throw new JDEException("Insufficient arguments");
+
+ String classPattern = args.remove(0).toString();
+ int line = Etc.safeGetint(args.remove(0), "line number");
+
+ EventRequestSpecList eventRequests = proc.getEventRequestSpecs();
+ EventRequestSpec er =
+ eventRequests.createClassLineBreakpoint(classPattern, line);
+ er.setThread(Etc.getThreadFromArgs(args));
+ er.setExpression(Etc.getExprFromArgs(args));
+ er.setSuspendPolicy(Etc.getSuspendPolicyFromArgs(args));
+ eventRequests.install(er);
+
+ jde.signalCommandResult(procID, cmdID, er.getID());
+ }
+
+ /** A break on a line of a given source file */
+ public void doBreakAbsolute(List args)
+ throws JDEException {
+
+ if (args.size() < 2)
+ throw new JDEException("Insufficient arguments");
+
+ String file = args.remove(0).toString();
+ int line = Etc.safeGetint(args.remove(0), "line number");
+
+ EventRequestSpecList eventRequests = proc.getEventRequestSpecs();
+ EventRequestSpec er =
+ eventRequests.createSourceLineBreakpoint(file, line);
+ er.setThread(Etc.getThreadFromArgs(args));
+ er.setExpression(Etc.getExprFromArgs(args));
+ er.setSuspendPolicy(Etc.getSuspendPolicyFromArgs(args));
+ eventRequests.install(er);
+
+ jde.signalCommandResult(procID, cmdID, er.getID());
+ }
+
+ public Object clone() {return new Break();}
+
+} // Break
+
+/*
+ * $Log: Break.java,v $
+ * Revision 1.1 2001/03/24 05:48:39 paulk
+ * Initial version.
+ *
+ *
+ */
+
+// End of Break.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/CancelTraceClasses.java
===================================================================
RCS file: CancelTraceClasses.java
diff -N CancelTraceClasses.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ CancelTraceClasses.java Tue Aug 14 22:27:47 2001
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.1 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+import jde.debugger.Etc;
+
+
+
+/**
+ * 'cancel_trace_classes' command.
+ * <p>
+ *
+ * <b>Syntax: </b>
+ * <pre>
+ * cancel_trace_classes <u>requestID</u>
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> <u>requestID</u> is returned in the trace classes reply
+ * </ul>
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.1 $
+ *
+ */
+public class CancelTraceClasses extends DebugProcessCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ public void doCommand() throws JDEException {
+ if (args.size() < 1)
+ throw new JDEException("Insufficient arguments");
+
+ deleteIdentifiableRequest(Etc.safeGetLong
+ (args.remove(0), "request ID"));
+
+ jde.signalCommandResult(procID, cmdID);
+ }
+
+ public Object clone() {return new CancelTraceClasses();}
+
+} // CancelTraceClasses
+
+/*
+ * $Log: CancelTraceClasses.java,v $
+ * Revision 1.1 2001/03/24 05:48:39 paulk
+ * Initial version.
+ *
+ *
+ */
+
+// End of CancelTraceClasses.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/CancelTraceMethods.java
===================================================================
RCS file: CancelTraceMethods.java
diff -N CancelTraceMethods.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ CancelTraceMethods.java Tue Aug 14 22:27:47 2001
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.1 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+import jde.debugger.Etc;
+
+
+/**
+ * 'cancel_trace_methods' command.
+ * <p>
+ *
+ * <b>Syntax: </b>
+ * <pre>
+ * cancel_trace_methods <u>requestID</u>
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> <u>requestID</u> is returned in the trace methods reply
+ * </ul>
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.1 $
+ *
+ */
+public class CancelTraceMethods extends DebugProcessCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ public void doCommand() throws JDEException {
+ if (args.size() < 1)
+ throw new JDEException("Insufficient arguments");
+
+ deleteIdentifiableRequest(Etc.safeGetLong
+ (args.remove(0), "request ID"));
+
+ jde.signalCommandResult(procID, cmdID);
+ }
+
+ public Object clone() {return new CancelTraceMethods();}
+
+} // CancelTraceMethods
+
+/*
+ * $Log: CancelTraceMethods.java,v $
+ * Revision 1.1 2001/03/24 05:48:39 paulk
+ * Initial version.
+ *
+ *
+ */
+
+// End of CancelTraceMethods.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/CancelTraceThreads.java
===================================================================
RCS file: CancelTraceThreads.java
diff -N CancelTraceThreads.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ CancelTraceThreads.java Tue Aug 14 22:27:47 2001
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.1 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+import jde.debugger.Etc;
+
+
+/**
+ * 'cancel_trace_threads' command.
+ * <p>
+ *
+ * <b>Syntax: </b>
+ * <pre>
+ * cancel_trace_threads <u>requestID</u>
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> <u>requestID</u> is returned in the trace threads reply
+ * </ul>
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.1 $
+ *
+ */
+public class CancelTraceThreads extends DebugProcessCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ public void doCommand() throws JDEException {
+ if (args.size() < 1)
+ throw new JDEException("Insufficient arguments");
+
+ deleteIdentifiableRequest(Etc.safeGetLong
+ (args.remove(0), "request ID"));
+
+ jde.signalCommandResult(procID, cmdID);
+ }
+
+
+
+ public Object clone() {return new CancelTraceThreads();}
+
+} // CancelTraceThreads
+
+/*
+ * $Log: CancelTraceThreads.java,v $
+ * Revision 1.1 2001/03/24 05:48:40 paulk
+ * Initial version.
+ *
+ *
+ */
+
+// End of CancelTraceThreads.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/Clear.java
===================================================================
RCS file: Clear.java
diff -N Clear.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ Clear.java Tue Aug 14 22:27:47 2001
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.1 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+import jde.debugger.Etc;
+
+
+
+/**
+ * 'clear' command. Clears a breakpoint, watchpoint or an exception
+ * intercept
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * clear specID
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> specIDs are returned in the
'break'/'watch'/'trace_exceptions'
+ * commands.
+ * </ul>
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.1 $
+ *
+ */
+public class Clear extends DebugProcessCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ public void doCommand() throws JDEException {
+ if (args.size() < 1)
+ throw new JDEException("Insufficient arguments");
+ Long specID = Etc.safeGetLong(args.remove(0), "spec ID");
+ proc.getEventRequestSpecs().removeSpec(specID);
+ jde.signalCommandResult(procID, cmdID); }
+
+ public Object clone() {return new Clear();}
+
+} // Clear
+
+/*
+ * $Log: Clear.java,v $
+ * Revision 1.1 2001/03/24 05:48:40 paulk
+ * Initial version.
+ *
+ *
+ */
+
+// End of Clear.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/CommandRegistry.java
===================================================================
RCS file: CommandRegistry.java
diff -N CommandRegistry.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ CommandRegistry.java Tue Aug 14 22:27:47 2001
@@ -0,0 +1,51 @@
+package jde.debugger.command;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Collections;
+
+/**
+ * Each command has a command id associated with it, that is used by
+ * jde, to match with the corresponding result/error. jdebug maintains
+ * the pending command ids in this collection (as does {@link
+ * Application}, see
+ * {@link Application#pendingCommands}),
+ * and removes
+ * them once the command processing is over.<br>
+ * Hence, the command id can actually be reused.
+ *
+ * Created: Sun Feb 18 00:22:14 2001
+ *
+ * @author <a href="mailto: "</a>
+ * @version
+ */
+public class CommandRegistry {
+
+ private CommandRegistry (){}
+
+ public void addCommand(Integer cmdID) {
+ synchronized (pendingCommands) {
+ pendingCommands.add(cmdID);
+ }
+ }
+
+ public void removeCommand(Integer cmdID) {
+ synchronized (pendingCommands) {
+ pendingCommands.remove(cmdID);
+ }
+ }
+
+ public boolean commandExists(Integer cmdID) {
+ synchronized (pendingCommands) {
+ return pendingCommands.contains(cmdID);
+ }
+ }
+
+ static public CommandRegistry getTheRegistry() {
+ return theRegistry;
+ }
+
+ private Collection pendingCommands = Collections.synchronizedSet(new HashSet());
+
+ static CommandRegistry theRegistry = new CommandRegistry();
+
+}// CommandRegistry
Index: xemacs-packages/jde/java/src/jde/debugger/command/DebugCommand.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/command/DebugCommand.java,v
retrieving revision 1.1
diff -u -r1.1 DebugCommand.java
--- xemacs-packages/jde/java/src/jde/debugger/command/DebugCommand.java 2000/08/13
13:49:11 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/command/DebugCommand.java 2001/08/15
05:27:48
@@ -1,107 +1,114 @@
-/*
- * Copyright (c) 2000 Paul Kinnucan
- *
- * $Revision: 1.1 $
- */
-
-package jde.debugger.command;
-import java.util.List;
-import jde.debugger.JDEException;
-import jde.debugger.Protocol;
-import jde.debugger.Jdebug;
-import jde.debugger.Debug;
-
-
-/**
- * Class of debugger commands.
- *
- * Command-line syntax:
- *
- * app_id cmd_id cmd_name [arg]*
- *
- * @author Paul Kinnucan
- * @version $Revision: 1.1 $
- */
-
-abstract public class DebugCommand extends Thread
- implements Protocol,Cloneable {
-
- public DebugCommand() {super("JDEbug command");}
-
- public void init(Integer appID, Integer cmdID,
- String cmdName, List args) throws JDEException {
- this.appID = appID;
- this.cmdID = cmdID;
- this.cmdName = cmdName;
- this.args = args;
-
- setName("JDEbug command(" + appID + " " + cmdID + " " +
cmdName + ")");
-
- }
-
- abstract protected void doCommand() throws JDEException;
-
-
- public void run() {
-
- // see if there already is a command with this cmd_id. this
- // should never happen.
- if (Jdebug.theDebugger.pendingCmdExists(cmdID)) {
- Jdebug.theDebugger.signalCommandError(Jdebug.debuggerID,
- new Integer(-1),
- "Duplicate cmd_id '" + cmdID + "'");
- return;
- }
-
- // if not, add to pending commands.
- Jdebug.theDebugger.addPendingCommand(cmdID);
-
-
- try {
- doCommand();
- }
- catch (JDEException ex) {
- Debug.printIf(ex);
- // a jde exception was raised. the kind of error is already
- // in there.
- Jdebug.theDebugger.signalCommandError(Jdebug.debuggerID,
- cmdID, ex.getMessage());
- return;
- }
- catch (Exception ex) {
- Debug.printIf(ex);
- Jdebug.theDebugger.signalCommandError(Jdebug.debuggerID,
- cmdID, "Unspecified error: "+ex.toString());
- return;
- }
- finally {
- Jdebug.theDebugger.removePendingCommand(cmdID);
- }
-
- }
-
- abstract public Object clone();
-
- Integer appID;
-
- Integer cmdID;
-
- String cmdName;
-
- List args;
-
-
-} // DebugCommand
-
-
-/*
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.2 $
+ */
+
+package jde.debugger.command;
+import java.util.List;
+import jde.debugger.JDEException;
+import jde.debugger.Protocol;
+import jde.debugger.Jdebug;
+import jde.debugger.Debug;
+import jde.debugger.JDE;
+import jde.debugger.ProcessRegistry;
+
+
+/**
+ * Class of debugger commands.
+ *
+ * Command-line syntax:
+ *
+ * app_id cmd_id cmd_name [arg]*
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.2 $
+ */
+
+abstract public class DebugCommand extends Thread
+ implements Protocol, Cloneable {
+
+ public DebugCommand() {super("JDEbug command");}
+
+ public void init(Integer procID, Integer cmdID,
+ String cmdName, List args) throws JDEException {
+ this.procID = procID;
+ this.cmdID = cmdID;
+ this.cmdName = cmdName;
+ this.args = args;
+
+ setName("JDEbug command(" + procID + " " + cmdID + " "
+ cmdName + ")");
+
+ }
+
+ abstract protected void doCommand() throws JDEException;
+
+
+ public void run() {
+
+ CommandRegistry commandRegistry = CommandRegistry.getTheRegistry();
+
+ // see if there already is a command with this cmd_id. this
+ // should never happen.
+ if (commandRegistry.commandExists(cmdID)) {
+ jde.signalCommandError(Jdebug.debuggerID,
+ Jdebug.debuggerID,
+ "Duplicate cmd_id '" + cmdID + "'");
+ return;
+ }
+
+ // if not, add to pending commands.
+ commandRegistry.addCommand(cmdID);
+
+
+ try {
+ doCommand();
+ }
+ catch (JDEException ex) {
+ Debug.printIf(ex);
+ // a jde exception was raised. the kind of error is already
+ // in there.
+ jde.signalCommandError(Jdebug.debuggerID, cmdID, ex.getMessage());
+ return;
+ }
+ catch (Exception ex) {
+ Debug.printIf(ex);
+ jde.signalCommandError(Jdebug.debuggerID, cmdID, "Unspecified error:
"+ex.toString());
+ return;
+ }
+ finally {
+ commandRegistry.removeCommand(cmdID);
+ }
+
+ }
+
+ abstract public Object clone();
+
+ Integer procID;
+
+ Integer cmdID;
+
+ String cmdName;
+
+ List args;
+
+ protected JDE jde = JDE.getJDE();
+
+ protected Jdebug jdebug = Jdebug.getTheDebugger();
+
+ protected ProcessRegistry procRegistry = ProcessRegistry.getRegistry();
+
+} // DebugCommand
+
+
+/*
* $Log: DebugCommand.java,v $
- * Revision 1.1 2000/08/13 13:49:11 michaels
- * Initial checkin
- *
- * Revision 1.1 2000/01/30 12:31:51 paulk
- * Initial revision.
- *
- */
-
-// End of DebugCommand.java
+ * Revision 1.2 2001/03/24 05:42:36 paulk
+ * Updated to reflect reorganization of debugger code.
+ *
+ * Revision 1.1 2000/01/30 12:31:51 paulk
+ * Initial revision.
+ *
+ */
+
+// End of DebugCommand.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/DebugCommandFactory.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/command/DebugCommandFactory.java,v
retrieving revision 1.2
diff -u -r1.2 DebugCommandFactory.java
--- xemacs-packages/jde/java/src/jde/debugger/command/DebugCommandFactory.java 2001/02/12
06:27:24 1.2
+++ xemacs-packages/jde/java/src/jde/debugger/command/DebugCommandFactory.java 2001/08/15
05:27:48
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2000 Paul Kinnucan
+ * Copyright (c) 2000, 2001 Paul Kinnucan
*
- * $Revision: 1.2 $
+ * $Revision: 1.7 $
*/
package jde.debugger.command;
@@ -22,7 +22,7 @@
* Created: Fri Jan 28 22:04:57 2000
*
* @author Paul Kinnucan
- * @version $Revision: 1.2 $
+ * @version $Revision: 1.7 $
*/
public class DebugCommandFactory {
@@ -36,15 +36,36 @@
prototypes.put("listen_socket", new ListenSocket());
prototypes.put("quit", new Quit());
prototypes.put("run", new Run());
+ prototypes.put("finish", new Finish());
prototypes.put("get_string", new GetString());
prototypes.put("get_array", new GetArray());
prototypes.put("get_locals", new GetLocals());
prototypes.put("get_this", new GetThis());
+ prototypes.put("get_object", new GetObject());
+ prototypes.put("get_loaded_classes", new GetLoadedClasses());
+ prototypes.put("get_path_information", new GetPathInfo());
+ prototypes.put("trace_classes", new TraceClasses());
+ prototypes.put("cancel_trace_classes", new CancelTraceClasses());
+ prototypes.put("trace_exceptions", new TraceExceptions());
+ prototypes.put("trace_methods", new TraceMethods());
+ prototypes.put("cancel_trace_methods", new CancelTraceMethods());
prototypes.put("evaluate", new EvaluateExpression());
+ prototypes.put("watch", new Watch());
+ prototypes.put("break", new Break());
+ prototypes.put("clear", new Clear());
prototypes.put("step", new Step());
+ prototypes.put("suspend", new Suspend());
+ prototypes.put("resume", new Resume());
+ prototypes.put("interrupt", new Interrupt());
+ prototypes.put("kill_thread", new KillThread());
+ prototypes.put("get_threads", new GetThreads());
+ prototypes.put("get_thread", new GetThread());
+ prototypes.put("get_object_monitors", new GetObjectMonitors());
+ prototypes.put("trace_threads", new TraceThreads());
+ prototypes.put("cancel_trace_threads", new CancelTraceThreads());
}
- public final DebugCommand createCommand(Integer appID, Integer cmdID,
+ public final DebugCommand createCommand(Integer procID, Integer cmdID,
String cmdName, List args)
throws JDEException {
@@ -53,7 +74,7 @@
if (prototype == null) return null;
DebugCommand cmd = (DebugCommand) prototype.clone();
- cmd.init(appID, cmdID, cmdName, args);
+ cmd.init(procID, cmdID, cmdName, args);
return cmd;
@@ -68,8 +89,8 @@
/*
* $Log: DebugCommandFactory.java,v $
- * Revision 1.2 2001/02/12 06:27:24 paulk
- * Updated for JDE-2.2.7.
+ * Revision 1.7 2001/03/24 05:42:36 paulk
+ * Updated to reflect reorganization of debugger code.
*
* Revision 1.6 2000/10/20 04:19:00 paulk
* *** empty log message ***
Index: xemacs-packages/jde/java/src/jde/debugger/command/DebugProcessCommand.java
===================================================================
RCS file: DebugProcessCommand.java
diff -N DebugProcessCommand.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ DebugProcessCommand.java Tue Aug 14 22:27:48 2001
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.1 $
+ */
+
+package jde.debugger.command;
+import java.util.List;
+import jde.debugger.JDEException;
+import jde.debugger.Jdebug;
+import jde.debugger.DebuggeeProcess;
+import com.sun.jdi.request.EventRequest;
+import java.util.Map;
+import com.sun.jdi.request.EventRequestManager;
+import java.util.HashMap;
+import java.util.Collections;
+
+
+/**
+ * DebugProcessCommand.java
+ *
+ *
+ * Created: Fri Jan 28 21:58:06 2000
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.1 $
+ */
+
+abstract public class DebugProcessCommand extends DebugCommand {
+
+ public void init(Integer procID, Integer cmdID,
+ String cmdName, List args) throws JDEException {
+ super.init(procID, cmdID, cmdName, args);
+
+ // this app id should be valid.
+ if (!procRegistry.processExists(procID))
+ throw new JDEException("Application "+ procID + " does not
exist");
+
+ proc = procRegistry.getProcess(procID);
+
+ }
+
+
+ /**
+ * Adds an event request to the above map. Also enables the request.
+ *
+ * @return an identifier for the request
+ */
+ protected Long addIdentifiableRequest(EventRequest e) {
+ Long id;
+ synchronized (identifiableEventRequests) {
+ id = proc.generateObjectID();
+ identifiableEventRequests.put(id, e);
+ }
+ e.enable();
+ return id;
+ }
+
+ /**
+ * Removes an event request. Also disables/deletes from the vm.
+ */
+ protected void deleteIdentifiableRequest(Long id)
+ throws JDEException {
+
+ EventRequestManager erm = proc.getVM().eventRequestManager();
+
+ synchronized (identifiableEventRequests) {
+ if (!identifiableEventRequests.containsKey(id)) {
+ throw new JDEException("Invalid request ID");
+ } else {
+ Object e = identifiableEventRequests.get(id);
+ if (e == null) {
+ throw new JDEException("No such event request");
+ } else if (e instanceof EventRequest) {
+ ((EventRequest)e).disable();
+ erm.deleteEventRequest((EventRequest)e);
+ } else {
+ throw new JDEException("Not an event request");
+ }
+ }
+ }
+ }
+
+
+ DebuggeeProcess proc;
+
+ /**
+ * This map stores the event requests that are NOT specs. storing
+ * it here allows the user to cancel them easily: they just specify the
+ * id, that gets reverse-looked up here, uniquely identifying the actual
+ * request.
+ * <p>
+ * Of course, the id is sent back to the user when the actual command is
+ * responded to, so that the handle is available to jde in the first
+ * place
+ */
+ protected Map identifiableEventRequests =
+ Collections.synchronizedMap(new HashMap());
+
+
+} // DebugApplicationCommand
+
+
+/*
+ * $Log: DebugProcessCommand.java,v $
+ * Revision 1.1 2001/03/24 05:48:40 paulk
+ * Initial version.
+ *
+ * Revision 1.2 2000/03/03 07:40:32 paulk
+ * Converted get_string and get_array commands from functions to objects.
+ *
+ * Revision 1.1 2000/01/31 12:46:10 paulk
+ * Defines general behavior of application debug commands.
+ *
+ */
+
+// End of DebugProcessCommand.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/DebugSessionCommand.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/command/DebugSessionCommand.java,v
retrieving revision 1.1
diff -u -r1.1 DebugSessionCommand.java
--- xemacs-packages/jde/java/src/jde/debugger/command/DebugSessionCommand.java 2000/08/13
13:49:11 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/command/DebugSessionCommand.java 2001/08/15
05:27:48
@@ -1,105 +1,106 @@
-/*
- * Copyright (c) 2000 Paul Kinnucan
- *
- * $Revision: 1.1 $
- */
-
-package jde.debugger.command;
-import java.util.List;
-import jde.debugger.JDEException;
-import jde.debugger.Etc;
-import jde.debugger.Jdebug;
-import com.sun.jdi.connect.Connector;
-import com.sun.jdi.Bootstrap;
-import java.util.Iterator;
-
-
-/**
- * DebugSessionCommand.java
- *
- *
- * Created: Fri Jan 28 21:59:32 2000
- *
- * @author Paul Kinnucan
- * @version $Revision: 1.1 $
- */
-
-abstract public class DebugSessionCommand extends DebugCommand {
-
- public DebugSessionCommand() { }
-
- public void init(Integer debuggerID, Integer cmdID,
- String cmdName, List args) throws JDEException {
-
- super.init(debuggerID, cmdID, cmdName, args);
-
- if (cmdName.equals("quit")) return;
-
- if (args.size() < 1 )
- throw new JDEException("Missing application ID");
-
- // the app id with which it will be known.
- // note that we remove the arguments as we consume them from the
- // list.
- appID = new Integer(Etc.safeGetint(args.remove(0), "application ID"));
-
- // the app id cannot be same as the debugger ID (-1)
- if (appID.equals(Jdebug.debuggerID)) {
- throw new JDEException("Invalid Application ID");
- }
-
- // an app using this id is already present!
- // XXX make sure you dispose the id once done with the app
-
- if (Jdebug.theDebugger.appExists(appID)) {
- throw new JDEException("Application ID is duplicate");
- }
-
-
- }
-
- /*
- * Gets a connector.
- *
- * @param type connector class name
- *
- */
- protected final Connector getConnector(String name) {
-
- Iterator iter = connectors.iterator();
- while (iter.hasNext()) {
- Connector connector = (Connector)iter.next();
- if (connector.name().equals(name)) {
- return connector;
- }
- }
- return null;
- }
-
- static List connectors = Bootstrap.virtualMachineManager().allConnectors();
-
-
-} // DebugSessionCommand
-
-
-/*
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.4 $
+ */
+
+package jde.debugger.command;
+import java.util.List;
+import jde.debugger.JDEException;
+import jde.debugger.Etc;
+import jde.debugger.Jdebug;
+import com.sun.jdi.connect.Connector;
+import com.sun.jdi.Bootstrap;
+import java.util.Iterator;
+import jde.debugger.ProcessRegistry;
+
+
+/**
+ * DebugSessionCommand.java
+ *
+ *
+ * Created: Fri Jan 28 21:59:32 2000
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.4 $
+ */
+
+abstract public class DebugSessionCommand extends DebugCommand {
+
+ public DebugSessionCommand() { }
+
+ public void init(Integer debuggerID, Integer cmdID,
+ String cmdName, List args) throws JDEException {
+
+ super.init(debuggerID, cmdID, cmdName, args);
+
+ if (cmdName.equals("quit")) return;
+
+ if (args.size() < 1 )
+ throw new JDEException("Missing application ID");
+
+ // the app id with which it will be known.
+ // note that we remove the arguments as we consume them from the
+ // list.
+ procID = new Integer(Etc.safeGetint(args.remove(0), "application ID"));
+
+ // the app id cannot be same as the debugger ID (-1)
+ if (procID.equals(Jdebug.debuggerID)) {
+ throw new JDEException("Invalid Application ID");
+ }
+
+ // an app using this id is already present!
+ // XXX make sure you dispose the id once done with the app
+
+ if (procRegistry.processExists(procID)) {
+ throw new JDEException("Application ID is duplicate");
+ }
+
+
+ }
+
+ /*
+ * Gets a connector.
+ *
+ * @param type connector class name
+ *
+ */
+ protected final Connector getConnector(String name) {
+
+ Iterator iter = connectors.iterator();
+ while (iter.hasNext()) {
+ Connector connector = (Connector)iter.next();
+ if (connector.name().equals(name)) {
+ return connector;
+ }
+ }
+ return null;
+ }
+
+ static List connectors = Bootstrap.virtualMachineManager().allConnectors();
+
+
+} // DebugSessionCommand
+
+
+/*
* $Log: DebugSessionCommand.java,v $
- * Revision 1.1 2000/08/13 13:49:11 michaels
- * Initial checkin
- *
- * Revision 1.3 2000/02/02 06:01:14 paulk
- * Removed the get connector list code from getConnectors method and
- * instead made the connector list a static member that is initialized
- * once per session. Did this because it is suspected that getting the
- * connector list on the command thread was causing the debugger to hang
- * on some Windows/NT systems.
- *
- * Revision 1.2 2000/02/01 06:02:47 paulk
- * Added special handling for quit command.
- *
- * Revision 1.1 2000/01/30 12:37:44 paulk
- * Defines debug session commands (e.g., launch, attach, quit, etc.).
- *
- */
-
-// End of DebugSessionCommand.java
+ * Revision 1.4 2001/03/24 05:42:36 paulk
+ * Updated to reflect reorganization of debugger code.
+ *
+ * Revision 1.3 2000/02/02 06:01:14 paulk
+ * Removed the get connector list code from getConnectors method and
+ * instead made the connector list a static member that is initialized
+ * once per session. Did this because it is suspected that getting the
+ * connector list on the command thread was causing the debugger to hang
+ * on some Windows/NT systems.
+ *
+ * Revision 1.2 2000/02/01 06:02:47 paulk
+ * Added special handling for quit command.
+ *
+ * Revision 1.1 2000/01/30 12:37:44 paulk
+ * Defines debug session commands (e.g., launch, attach, quit, etc.).
+ *
+ */
+
+// End of DebugSessionCommand.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/EvaluateExpression.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/command/EvaluateExpression.java,v
retrieving revision 1.2
diff -u -r1.2 EvaluateExpression.java
--- xemacs-packages/jde/java/src/jde/debugger/command/EvaluateExpression.java 2001/02/12
06:27:24 1.2
+++ xemacs-packages/jde/java/src/jde/debugger/command/EvaluateExpression.java 2001/08/15
05:27:48
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000 Paul Kinnucan
+ * Copyright (c) 2000, 2001 Paul Kinnucan
*
* $Revision: 1.2 $
*/
@@ -42,7 +42,7 @@
* might not be possible depending on the state of the thread
* </ul>
*/
- public class EvaluateExpression extends DebugApplicationCommand {
+ public class EvaluateExpression extends DebugProcessCommand {
/**
*
@@ -65,7 +65,7 @@
Long uniqueID = Etc.safeGetLong(args.remove(0), "thread ID");
int frameIndex = Etc.safeGetint(args.remove(0), "frame index");
- Object oRef = app.getStore().get(uniqueID);
+ Object oRef = proc.getStore().get(uniqueID);
if (oRef == null) {
throw new JDEException("No such thread exists");
} else if (!(oRef instanceof ThreadReference)) {
@@ -96,7 +96,7 @@
String expr = args.remove(0).toString();
Value val = Etc.evaluate(expr, frame);
- app.signalCommandResult(cmdID, Rep.getValueRep(val, app.getStore()));
+ jde.signalCommandResult(procID, cmdID, Rep.getValueRep(val, proc.getStore()));
} finally {
if (weSuspendedThread && (tRef != null)) tRef.resume();
@@ -110,8 +110,8 @@
/*
* $Log: EvaluateExpression.java,v $
- * Revision 1.2 2001/02/12 06:27:24 paulk
- * Updated for JDE-2.2.7.
+ * Revision 1.2 2001/03/24 05:42:36 paulk
+ * Updated to reflect reorganization of debugger code.
*
* Revision 1.1 2000/08/14 02:37:40 paulk
* Initial revision.
Index: xemacs-packages/jde/java/src/jde/debugger/command/Finish.java
===================================================================
RCS file: Finish.java
diff -N Finish.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ Finish.java Tue Aug 14 22:27:48 2001
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.1 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+
+
+/**
+ * 'finish' command.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * finish
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> if multiple VMs are being debugged, this command will
+ * kill the one corresponding to app_id, retaining others.
+ * </ul>
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.1 $
+ *
+ */
+public class Finish extends DebugProcessCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ public void doCommand() throws JDEException {
+ proc.shutdown();
+ jde.signalCommandResult(procID, cmdID);
+ }
+
+ public Object clone() {return new Finish();}
+
+} // Finish
+
+/*
+ * $Log: Finish.java,v $
+ * Revision 1.1 2001/03/24 05:52:12 paulk
+ * Initial version.
+ *
+ *
+ */
+
+// End of Finish.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/GetArray.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/command/GetArray.java,v
retrieving revision 1.1
diff -u -r1.1 GetArray.java
--- xemacs-packages/jde/java/src/jde/debugger/command/GetArray.java 2000/08/13
13:49:12 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/command/GetArray.java 2001/08/15 05:27:48
@@ -1,78 +1,78 @@
-/*
- * Copyright (c) 2000 Paul Kinnucan
- *
- * $Revision: 1.1 $
- */
-
-package jde.debugger.command;
-import jde.debugger.JDEException;
-import jde.debugger.Etc;
-import com.sun.jdi.ObjectReference;
-import jde.debugger.Rep;
-import com.sun.jdi.ArrayReference;
-
-/**
- * 'get_array' command. Information about a given array, and,
- * optionally, values of a range of indices
- * <p>
- *
- * <b>Syntax:</b>
- * <pre>
- * get_array objectID [index, length]
- * </pre>
- *
- * <b>Returns:</b>
- * <pre>
- * (jde-dbo-command-result cmd_id {@link Rep#getArrayRep(ArrayReference, ObjectStore,
int, int) array})
- * </pre>
- * @author Paul Kinnucan
- * @version $Revision: 1.1 $
- */
-public class GetArray extends DebugApplicationCommand {
-
- /**
- *
- * @exception jde.debugger.JDEException <description>
- */
- public void doCommand() throws JDEException {
-
- if (args.size() < 1)
- throw new JDEException("Insufficient arguments");
-
- Long uniqueID = Etc.safeGetLong(args.remove(0), "object ID");
- ObjectReference oRef = app.getStore().get(uniqueID);
-
- if (oRef == null) {
- throw new JDEException("No such object exists");
- } else if (!(oRef instanceof ArrayReference)) {
- throw new JDEException("Object is not an array");
- }
-
- if (args.size() == 0) {
- app.signalCommandResult(cmdID, Rep.getArrayRep((ArrayReference)oRef,
app.getStore(), -1, -1));
- } else if (args.size() == 2) {
- int index = Etc.safeGetint(args.remove(0), "index");
- int length = Etc.safeGetint(args.remove(0), "length");
- app.signalCommandResult(cmdID, Rep.getArrayRep((ArrayReference)oRef,
- app.getStore(), index, length));
- } else {
- throw new JDEException("Syntax error: Wrong number of arguments");
- }
-
- }
-
- public Object clone() {return new GetArray();}
-
-} // GetArray
-
-/*
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.2 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+import jde.debugger.Etc;
+import com.sun.jdi.ObjectReference;
+import jde.debugger.Rep;
+import com.sun.jdi.ArrayReference;
+
+/**
+ * 'get_array' command. Information about a given array, and,
+ * optionally, values of a range of indices
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * get_array objectID [index, length]
+ * </pre>
+ *
+ * <b>Returns:</b>
+ * <pre>
+ * (jde-dbo-command-result cmd_id {@link Rep#getArrayRep(ArrayReference, ObjectStore,
int, int) array})
+ * </pre>
+ * @author Paul Kinnucan
+ * @version $Revision: 1.2 $
+ */
+public class GetArray extends DebugProcessCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ public void doCommand() throws JDEException {
+
+ if (args.size() < 1)
+ throw new JDEException("Insufficient arguments");
+
+ Long uniqueID = Etc.safeGetLong(args.remove(0), "object ID");
+ ObjectReference oRef = proc.getStore().get(uniqueID);
+
+ if (oRef == null) {
+ throw new JDEException("No such object exists");
+ } else if (!(oRef instanceof ArrayReference)) {
+ throw new JDEException("Object is not an array");
+ }
+
+ if (args.size() == 0) {
+ jde.signalCommandResult(procID, cmdID, Rep.getArrayRep((ArrayReference)oRef,
proc.getStore(), -1, -1));
+ } else if (args.size() == 2) {
+ int index = Etc.safeGetint(args.remove(0), "index");
+ int length = Etc.safeGetint(args.remove(0), "length");
+ jde.signalCommandResult(procID, cmdID, Rep.getArrayRep((ArrayReference)oRef,
+ proc.getStore(), index, length));
+ } else {
+ throw new JDEException("Syntax error: Wrong number of arguments");
+ }
+
+ }
+
+ public Object clone() {return new GetArray();}
+
+} // GetArray
+
+/*
* $Log: GetArray.java,v $
- * Revision 1.1 2000/08/13 13:49:12 michaels
- * Initial checkin
- *
- * Revision 1.1 2000/03/03 07:08:39 paulk
- * Initial revision.
- *
- */
-
-// End of GetArray.java
+ * Revision 1.2 2001/03/24 05:42:36 paulk
+ * Updated to reflect reorganization of debugger code.
+ *
+ * Revision 1.1 2000/03/03 07:08:39 paulk
+ * Initial revision.
+ *
+ */
+
+// End of GetArray.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/GetLoadedClasses.java
===================================================================
RCS file: GetLoadedClasses.java
diff -N GetLoadedClasses.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ GetLoadedClasses.java Tue Aug 14 22:27:48 2001
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.1 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+import com.sun.jdi.ReferenceType;
+import jde.debugger.LispForm;
+import java.util.Iterator;
+
+
+/**
+ * 'get_loaded_classes' command. Returns a list of all loaded classes
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * get_loaded_classes
+ * </pre>
+ *
+ * <b>Returns:</b>
+ * <pre>
+ * (jde-dbo-command-result cmd_id (list ["type-name"]*))
+ * </pre>
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.1 $
+ *
+ */
+public class GetLoadedClasses extends DebugProcessCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ public void doCommand() throws JDEException {
+ String typeNames = "(list";
+ Iterator it = proc.getVM().allClasses().iterator();
+ while (it.hasNext()) {
+ typeNames += "
\""+((ReferenceType)it.next()).name()+"\"";
+ }
+ typeNames += ")";
+ jde.signalCommandResult(procID, cmdID, new LispForm(typeNames));
+ }
+
+ public Object clone() {return new GetLoadedClasses();}
+
+} // GetLoadedClasses
+
+/*
+ * $Log: GetLoadedClasses.java,v $
+ * Revision 1.1 2001/03/24 05:52:13 paulk
+ * Initial version.
+ *
+ *
+ */
+
+// End of GetLoadedClasses.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/GetLocals.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/command/GetLocals.java,v
retrieving revision 1.2
diff -u -r1.2 GetLocals.java
--- xemacs-packages/jde/java/src/jde/debugger/command/GetLocals.java 2001/02/12
06:27:24 1.2
+++ xemacs-packages/jde/java/src/jde/debugger/command/GetLocals.java 2001/08/15 05:27:48
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2000 Paul Kinnucan
+ * Copyright (c) 2000, 2001 Paul Kinnucan
*
- * $Revision: 1.2 $
+ * $Revision: 1.3 $
*/
package jde.debugger.command;
@@ -44,9 +44,9 @@
*
* @author Amit Kumar
* @author Paul Kinnucan
- * @version $Revision: 1.2 $
+ * @version $Revision: 1.3 $
*/
- public class GetLocals extends DebugApplicationCommand {
+ public class GetLocals extends DebugProcessCommand {
/**
*
@@ -65,7 +65,7 @@
Long uniqueID = Etc.safeGetLong(args.remove(0), "thread ID");
int frameIndex = Etc.safeGetint(args.remove(0), "frame index");
- Object oRef = app.getStore().get(uniqueID);
+ Object oRef = proc.getStore().get(uniqueID);
if (oRef == null) {
throw new JDEException("No such thread exists");
} else if (!(oRef instanceof ThreadReference)) {
@@ -98,14 +98,14 @@
try {
localVariableValues =
Rep.getLocalVariableValueMapRep(frame.getValues(frame.visibleVariables()),
- app.getStore());
+ proc.getStore());
} catch (AbsentInformationException ex) {
throw new JDEException("Local variable information not available: compile with
-g");
} catch (NativeMethodException ex) {
throw new JDEException("Can't access local variables in native
methods");
}
- app.signalCommandResult(cmdID, localVariableValues);
+ jde.signalCommandResult(procID, cmdID, localVariableValues);
} finally {
if (weSuspendedThread && (tRef != null)) tRef.resume();
@@ -119,8 +119,8 @@
/*
* $Log: GetLocals.java,v $
- * Revision 1.2 2001/02/12 06:27:24 paulk
- * Updated for JDE-2.2.7.
+ * Revision 1.3 2001/03/24 05:42:36 paulk
+ * Updated to reflect reorganization of debugger code.
*
* Revision 1.2 2000/08/14 02:42:16 paulk
* DebugCommandFactory.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/GetObject.java
===================================================================
RCS file: GetObject.java
diff -N GetObject.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ GetObject.java Tue Aug 14 22:27:48 2001
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.1 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+import jde.debugger.Etc;
+import com.sun.jdi.ObjectReference;
+import jde.debugger.Rep;
+
+
+/**
+ * 'get_object' command. Information about a particular object.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * get_object objectID
+ * </pre>
+ *
+ * <b>Returns:</b>
+ * <pre>
+ * (jde-dbo-command-result cmd_id {@link Rep#getObjectRep(ObjectReference, ObjectStore)
detailed-object-info})
+ * </pre>
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.1 $
+ *
+ */
+public class GetObject extends DebugProcessCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ public void doCommand() throws JDEException {
+
+ if (args.size() < 1)
+ throw new JDEException("Insufficient arguments");
+
+ Long uniqueID = Etc.safeGetLong(args.remove(0), "object ID");
+ ObjectReference oRef = proc.getStore().get(uniqueID);
+
+ if (oRef == null)
+ throw new JDEException("No such object exists");
+
+ jde.signalCommandResult(procID, cmdID, Rep.getObjectRep(oRef, proc.getStore(),
true));
+ }
+
+ public Object clone() {return new GetObject();}
+
+} // GetObject
+
+/*
+ * $Log: GetObject.java,v $
+ * Revision 1.1 2001/03/24 05:52:13 paulk
+ * Initial version.
+ *
+ *
+ */
+
+// End of Finish.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/GetObjectMonitors.java
===================================================================
RCS file: GetObjectMonitors.java
diff -N GetObjectMonitors.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ GetObjectMonitors.java Tue Aug 14 22:27:48 2001
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.1 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+import jde.debugger.Etc;
+import com.sun.jdi.ObjectReference;
+import com.sun.jdi.ThreadReference;
+import jde.debugger.Rep;
+import jde.debugger.ObjectStore;
+
+
+/**
+ * 'get_object_monitors' command. Information about the monitors
+ * corresponding to a particular object.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * get_object_monitors objectID
+ * </pre>
+ *
+ * <b>Returns:</b>
+ * <pre>
+ * (jde-dbo-command-result cmd_id
+ * {@link Rep#getObjectMonitorsRep(ObjectReference, ObjectStore)
object-monitors-info})
+ * </pre>
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.1 $
+ *
+ */
+public class GetObjectMonitors extends DebugProcessCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ public void doCommand() throws JDEException {
+ if (args.size() != 1)
+ throw new JDEException("Insufficient arguments");
+
+ Long uniqueID = Etc.safeGetLong(args.remove(0), "object ID");
+ ObjectStore store = proc.getStore();
+ ObjectReference oRef = store.get(uniqueID);
+ if (oRef == null)
+ throw new JDEException("No such object exists");
+
+ jde.signalCommandResult(procID, cmdID, Rep.getObjectMonitorsRep(oRef,store));
+ }
+
+
+
+ public Object clone() {return new GetObjectMonitors();}
+
+} // GetObjectMonitors
+
+/*
+ * $Log: GetObjectMonitors.java,v $
+ * Revision 1.1 2001/03/24 05:52:14 paulk
+ * Initial version.
+ *
+ *
+ */
+
+// End of GetObjectMonitors.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/GetPathInfo.java
===================================================================
RCS file: GetPathInfo.java
diff -N GetPathInfo.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ GetPathInfo.java Tue Aug 14 22:27:48 2001
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.1 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+import com.sun.jdi.PathSearchingVirtualMachine;
+import java.util.Iterator;
+import jde.debugger.LispForm;
+
+
+
+
+/**
+ * 'get_path_information' command. Returns all the vm knows about
+ * paths.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * get_path_information
+ * </pre>
+ *
+ * <b>Returns:</b>
+ * <pre>
+ * (jde-dbo-command-result cmd_id "base-directory" (list [boot-class-path
component]*) (list [class-path component]*))
+ * </pre>
+ *
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.1 $
+ *
+ */
+public class GetPathInfo extends DebugProcessCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ public void doCommand() throws JDEException {
+
+ if (!(proc.getVM() instanceof PathSearchingVirtualMachine))
+ throw new JDEException("VM doesn't search paths");
+
+ PathSearchingVirtualMachine vm =
+ (PathSearchingVirtualMachine)proc.getVM();
+
+ String bootClassPathString = "(list";
+ Iterator it = vm.bootClassPath().iterator();
+ while (it.hasNext()) {
+ bootClassPathString += " \""+it.next()+"\"";
+ }
+ bootClassPathString += ")";
+
+ bootClassPathString = bootClassPathString.replace('\\', '/');
+
+ String classPathString = "(list";
+ it = vm.classPath().iterator();
+ while (it.hasNext()) {
+ classPathString += " \""+it.next()+"\"";
+ }
+ classPathString += ")";
+
+ classPathString = classPathString.replace('\\', '/');
+
+ jde.signalCommandResult(procID, cmdID,
+ new LispForm("\""+vm.baseDirectory().replace('\\',
'/')+"\""
+ + BR +bootClassPathString
+ + BR +classPathString));
+ }
+
+ public Object clone() {return new Finish();}
+
+} // GetPathInfo
+
+/*
+ * $Log: GetPathInfo.java,v $
+ * Revision 1.1 2001/03/24 05:52:14 paulk
+ * Initial version.
+ *
+ *
+ */
+
+// End of GetPathInfo.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/GetString.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/command/GetString.java,v
retrieving revision 1.1
diff -u -r1.1 GetString.java
--- xemacs-packages/jde/java/src/jde/debugger/command/GetString.java 2000/08/13
13:49:12 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/command/GetString.java 2001/08/15 05:27:48
@@ -1,71 +1,71 @@
-/*
- * Copyright (c) 2000 Paul Kinnucan
- *
- * $Revision: 1.1 $
- */
-
-package jde.debugger.command;
-import jde.debugger.JDEException;
-import jde.debugger.Etc;
-import com.sun.jdi.ObjectReference;
-import com.sun.jdi.StringReference;
-import jde.debugger.Rep;
-
-
-
-/**
- * 'get_string' command. Returns the value of a string
- * <p>
- *
- * <b>Syntax:</b>
- * <pre>
- * get_string objectID
- * </pre>
- *
- * <b>Returns:</b>
- * <pre>
- * (jde-dbo-command-result cmd_id {@link Rep#getStringRep(StringReference, ObjectStore)
string-representation})
- * </pre>
- *
- * @author Paul Kinnucan
- * @version $Revision: 1.1 $
- */
- public class GetString extends DebugApplicationCommand {
-
- /**
- *
- * @exception jde.debugger.JDEException <description>
- */
- public void doCommand() throws JDEException {
-
- if (args.size() < 1)
- throw new JDEException("Insufficient arguments");
-
- Long uniqueID = Etc.safeGetLong(args.remove(0), "object ID");
- ObjectReference oRef = app.getStore().get(uniqueID);
-
- if (oRef == null) {
- throw new JDEException("No such object exists");
- } else if (!(oRef instanceof StringReference)) {
- throw new JDEException("Object is not a string");
- }
-
- app.signalCommandResult(cmdID, Rep.getStringRep((StringReference)oRef,
- app.getStore()));
- }
-
- public Object clone() {return new GetString();}
-
-} // Run
-
-/*
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.2 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+import jde.debugger.Etc;
+import com.sun.jdi.ObjectReference;
+import com.sun.jdi.StringReference;
+import jde.debugger.Rep;
+
+
+
+/**
+ * 'get_string' command. Returns the value of a string
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * get_string objectID
+ * </pre>
+ *
+ * <b>Returns:</b>
+ * <pre>
+ * (jde-dbo-command-result cmd_id {@link Rep#getStringRep(StringReference, ObjectStore)
string-representation})
+ * </pre>
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.2 $
+ */
+ public class GetString extends DebugProcessCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ public void doCommand() throws JDEException {
+
+ if (args.size() < 1)
+ throw new JDEException("Insufficient arguments");
+
+ Long uniqueID = Etc.safeGetLong(args.remove(0), "object ID");
+ ObjectReference oRef = proc.getStore().get(uniqueID);
+
+ if (oRef == null) {
+ throw new JDEException("No such object exists");
+ } else if (!(oRef instanceof StringReference)) {
+ throw new JDEException("Object is not a string");
+ }
+
+ jde.signalCommandResult(procID, cmdID, Rep.getStringRep((StringReference)oRef,
+ proc.getStore()));
+ }
+
+ public Object clone() {return new GetString();}
+
+} // Run
+
+/*
* $Log: GetString.java,v $
- * Revision 1.1 2000/08/13 13:49:12 michaels
- * Initial checkin
- *
- * Revision 1.1 2000/03/03 07:10:29 paulk
- * Initial revision.
- *
- */
-
-// End of GetString.java
+ * Revision 1.2 2001/03/24 05:42:36 paulk
+ * Updated to reflect reorganization of debugger code.
+ *
+ * Revision 1.1 2000/03/03 07:10:29 paulk
+ * Initial revision.
+ *
+ */
+
+// End of GetString.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/GetThis.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/command/GetThis.java,v
retrieving revision 1.2
diff -u -r1.2 GetThis.java
--- xemacs-packages/jde/java/src/jde/debugger/command/GetThis.java 2001/02/12
06:27:24 1.2
+++ xemacs-packages/jde/java/src/jde/debugger/command/GetThis.java 2001/08/15 05:27:48
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2000 Paul Kinnucan
+ * Copyright (c) 2000, 2001 Paul Kinnucan
*
- * $Revision: 1.2 $
+ * $Revision: 1.3 $
*/
package jde.debugger.command;
@@ -43,9 +43,9 @@
* </ul>
*
* @author Paul Kinnucan
- * @version $Revision: 1.2 $
+ * @version $Revision: 1.3 $
*/
- public class GetThis extends DebugApplicationCommand {
+ public class GetThis extends DebugProcessCommand {
/**
*
@@ -64,7 +64,7 @@
Long uniqueID = Etc.safeGetLong(args.remove(0), "thread ID");
int frameIndex = Etc.safeGetint(args.remove(0), "frame index");
- Object oRef = app.getStore().get(uniqueID);
+ Object oRef = proc.getStore().get(uniqueID);
if (oRef == null) {
throw new JDEException("No such thread exists");
} else if (!(oRef instanceof ThreadReference)) {
@@ -101,7 +101,7 @@
throw new JDEException("Invalid stack frame.");
}
- app.signalCommandResult(cmdID, Rep.getObjectRep(thisObj, app.getStore(), true));
+ jde.signalCommandResult(procID, cmdID, Rep.getObjectRep(thisObj, proc.getStore(),
true));
} finally {
if (weSuspendedThread && (tRef != null)) tRef.resume();
@@ -115,8 +115,8 @@
/*
* $Log: GetThis.java,v $
- * Revision 1.2 2001/02/12 06:27:24 paulk
- * Updated for JDE-2.2.7.
+ * Revision 1.3 2001/03/24 05:42:36 paulk
+ * Updated to reflect reorganization of debugger code.
*
* Revision 1.2 2000/08/14 02:42:16 paulk
* DebugCommandFactory.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/GetThread.java
===================================================================
RCS file: GetThread.java
diff -N GetThread.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ GetThread.java Tue Aug 14 22:27:48 2001
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.1 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+import jde.debugger.Etc;
+import com.sun.jdi.ObjectReference;
+import com.sun.jdi.ThreadReference;
+import jde.debugger.Rep;
+
+
+/**
+ * 'get_thread' command. List a thread in more detail.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * get_thread threadID
+ * </pre>
+ *
+ * <b>Returns:</b>
+ * <pre>
+ * (jde-dbo-command-result cmd_id
+ * {@link Rep#getThreadRep(ThreadReference, ObjectStore, boolean)
detailed-thread-info})
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> The thread can be waiting for a monitor through entry
+ * into a synchronized method, the synchronized
+ * statement, or Object.wait(). The status() method can be used to
+ * differentiate between the first two cases and the third.
+ * </ul>
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.1 $
+ *
+ */
+public class GetThread extends DebugProcessCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ public void doCommand() throws JDEException {
+ if (args.size() < 1)
+ throw new JDEException("Insufficient arguments");
+
+ Long uniqueID = Etc.safeGetLong(args.remove(0), "thread ID");
+ ObjectReference tRef = proc.getStore().get(uniqueID);
+
+ if (tRef == null) {
+ throw new JDEException("No such thread exists");
+ } else if (!(tRef instanceof ThreadReference)) {
+ throw new JDEException("No such thread exists (anymore?)");
+ }
+
+ jde.signalCommandResult(procID, cmdID,
+ Rep.getThreadRep((ThreadReference)tRef,
+ proc.getStore(), true));
+ }
+
+
+
+ public Object clone() {return new GetThread();}
+
+} // GetThread
+
+/*
+ * $Log: GetThread.java,v $
+ * Revision 1.1 2001/03/24 05:52:14 paulk
+ * Initial version.
+ *
+ *
+ */
+
+// End of GetThread.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/GetThreads.java
===================================================================
RCS file: GetThreads.java
diff -N GetThreads.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ GetThreads.java Tue Aug 14 22:27:48 2001
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.1 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+
+
+/**
+ * List all threads. 'get_threads' command.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * get_threads
+ * </pre>
+ *
+ * <b>Returns:</b>
+ * <pre>
+ * (jde-dbo-command-result cmd_id {@link #getAllThreadsInformation thread-info})
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> There are a couple of quirks regarding the reporting
+ * of thread state:
+ * <ul>
+ * <li> Quirk 1: Due to a bug in ThreadReference.isAtBreakpoint(),
+ * a thread will report a breakpoint at a location
+ * even if a threadFilter has been applied for the
+ * thread. ie, if test.Test.java:41 is your
+ * breakpoint, and you've applied a threadfilter
+ * saying you DON'T want an event if the thread ==
+ * Thread-A, and you somehow suspend Thread-A at
+ * exactly that line, and do a 'get_threads';
+ * Thread-A will report to be suspended on a
+ * breakpoint, although ordinarily it would have
+ * skipped it.
+ *
+ * <li> Quirk 2: There seems to be no way of reporting the
+ * status if the user does a
+ * Thread.suspend(). Well, it's deprecated
+ * anyways... *shrug*.
+ * </ul>
+ * </ul>
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.1 $
+ *
+ */
+public class GetThreads extends DebugProcessCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ public void doCommand() throws JDEException {
+ jde.signalCommandResult(procID, cmdID, proc.getAllThreadsInformation());
+ }
+
+
+
+ public Object clone() {return new GetThreads();}
+
+} // GetThreads
+
+/*
+ * $Log: GetThreads.java,v $
+ * Revision 1.1 2001/03/24 13:35:25 paulk
+ * Initial revision.
+ *
+ *
+ */
+
+// End of GetThreads.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/Interrupt.java
===================================================================
RCS file: Interrupt.java
diff -N Interrupt.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ Interrupt.java Tue Aug 14 22:27:48 2001
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.1 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+import java.util.Iterator;
+import jde.debugger.Etc;
+import com.sun.jdi.ObjectReference;
+import com.sun.jdi.ThreadReference;
+import com.sun.jdi.ThreadGroupReference;
+
+
+/**
+ * 'interrupt' command.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * interrupt [threadID]+
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> threadID can be retrieved using the get_threads command
+ * <li> at least one threadId should be specified
+ * </ul>
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.1 $
+ *
+ */
+public class Interrupt extends DebugProcessCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ public void doCommand() throws JDEException {
+ if (args.size() < 1)
+ throw new JDEException("Insufficient arguments");
+
+ Iterator it = args.iterator();
+ while (it.hasNext()) {
+ Long uniqueID = Etc.safeGetLong(it.next(), "thread ID");
+
+ ObjectReference oRef = (ObjectReference)proc.getStore().get(uniqueID);
+ if (oRef == null) {
+ throw new JDEException("Invalid ThreadID, or the thread is dead");
+ } else if (oRef instanceof ThreadReference) {
+ ((ThreadReference)oRef).interrupt();
+ } else {
+ throw new JDEException("The object is not a thread");
+ }
+ }
+ jde.signalCommandResult(procID, cmdID);
+ }
+
+ public Object clone() {return new Interrupt();}
+
+} // Interrupt
+
+/*
+ * $Log: Interrupt.java,v $
+ * Revision 1.1 2001/03/24 13:35:25 paulk
+ * Initial revision.
+ *
+ *
+ */
+
+// End of Interrupt.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/KillThread.java
===================================================================
RCS file: KillThread.java
diff -N KillThread.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ KillThread.java Tue Aug 14 22:27:48 2001
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.1 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+import java.util.Iterator;
+import jde.debugger.Etc;
+import com.sun.jdi.ObjectReference;
+import com.sun.jdi.ThreadReference;
+import com.sun.jdi.ThreadGroupReference;
+import com.sun.jdi.InvalidTypeException;
+
+
+/**
+ * 'kill thread' command. Kill a thread with a given exception object.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * kill_thread threadID exceptionObjectID
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> threadID can be retrieved using the get_threads command
+ * <li> exceptionObjectID is the object id of a Throwable object. It
+ * can be created using the 'evaluate' command, or an existing throwable
+ * object can be used.
+ * </ul>
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.1 $
+ *
+ */
+public class KillThread extends DebugProcessCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ public void doCommand() throws JDEException {
+ if (args.size() < 2)
+ throw new JDEException("Insufficient arguments");
+
+ Long uniqueID = Etc.safeGetLong(args.remove(0), "thread ID");
+
+ ObjectReference oRef = proc.getStore().get(uniqueID);
+ if (oRef == null) {
+ throw new JDEException("No such thread exists");
+ } else if (!(oRef instanceof ThreadReference)) {
+ throw new JDEException("The ID doesn't correspond to a thread");
+ }
+ ThreadReference tRef = (ThreadReference)oRef;
+
+ uniqueID = Etc.safeGetLong(args.remove(0), "thread ID");
+
+ oRef = proc.getStore().get(uniqueID);
+ if (oRef == null) {
+ throw new JDEException("No such thread exists");
+ }
+
+ try {
+ tRef.stop(oRef);
+ } catch (InvalidTypeException ex) {
+ throw new JDEException("Object ID doesn't correspond to a Throwable
object");
+ }
+ jde.signalCommandResult(procID, cmdID);
+ }
+
+ public Object clone() {return new KillThread();}
+
+} // KillThread
+
+/*
+ * $Log: KillThread.java,v $
+ * Revision 1.1 2001/03/24 13:35:25 paulk
+ * Initial revision.
+ *
+ *
+ */
+
+// End of KillThread.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/LaunchApplication.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/command/LaunchApplication.java,v
retrieving revision 1.1
diff -u -r1.1 LaunchApplication.java
--- xemacs-packages/jde/java/src/jde/debugger/command/LaunchApplication.java 2000/08/13
13:49:12 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/command/LaunchApplication.java 2001/08/15
05:27:48
@@ -1,179 +1,186 @@
-/*
- * Copyright (c) 2000 Paul Kinnucan
- *
- * $Revision: 1.1 $
- */
-
-package jde.debugger.command;
-import jde.debugger.JDEException;
-
-import com.sun.jdi.connect.LaunchingConnector;
-import java.util.Map;
-import com.sun.jdi.connect.Connector;
-import java.util.Iterator;
-import com.sun.jdi.VirtualMachine;
-import java.io.IOException;
-import com.sun.jdi.connect.IllegalConnectorArgumentsException;
-import com.sun.jdi.connect.VMStartException;
-import jde.debugger.Application;
-import jde.debugger.Jdebug;
-import jde.debugger.Debug;
-
-
-/**
- * Launches an application.
- * <p>
- *
- * <b>Syntax:</b>
- * <pre>
- * launch app_id [-use_executable javax] classname [args]
- * </pre>
- *
- * @author Paul Kinnucan
- * @version $Revision: 1.1 $
- */
-public class LaunchApplication extends DebugSessionCommand {
-
- /**
- *
- * @exception jde.debugger.JDEException <description>
- */
- public void doCommand() throws JDEException {
-
- // this is the connector that launches a debuggee vm
- String connectSpec = "com.sun.jdi.CommandLineLaunch";
-
- // check if this kind of connector is, indeed,
- // available. if not, throw an exception.
- LaunchingConnector connector = (LaunchingConnector) getConnector(connectSpec);
- if (connector == null)
- throw new JDEException("No such connector is avaliable: "+connectSpec);
-
-
- // first set up the argument map. a table that describes the
- // different keys should be in the public jpda documentation.
- // internally, it is at
- //
http://jbug/jbug/doc/conninv.html
- Map argumentMap = connector.defaultArguments();
-
- Connector.Argument mainArg =
- (Connector.Argument)argumentMap.get("main");
-
- // compose the command line
- String commandLine = "";
- String quote =((Connector.Argument)argumentMap.get("quote")).value();
-
- // check if there are special launch options we need to process
- if (args.size() == 0)
- throw new JDEException("Insufficient arguments");
-
- String executable = "java";
- // be careful with the loop here....
- while ((args.size() >0)
- && args.get(0).toString().startsWith("-")) {
- String arg = args.remove(0).toString().toLowerCase();
- if (arg.equals("-vmexec")) {
- if (args.size() == 0)
- throw new JDEException("Missing argument to 'use_executable'");
- executable = args.remove(0).toString();
- Connector.Argument vmexecArg =
- (Connector.Argument)argumentMap.get("vmexec");
- vmexecArg.setValue(executable);
- }
- else if (arg.equals("-home")) {
- if (args.size() == 0)
- throw new JDEException("Missing argument to 'home'");
- String home = args.remove(0).toString();
- Connector.Argument homeArg = (Connector.Argument) argumentMap.get("home");
- homeArg.setValue(home);
- continue;
- }
- else {
- args.add(0, arg);
- break;
- }
- }
-
- if (args.size() == 0)
- throw new JDEException("Missing arguments: no class specified?");
-
- // take care of spaces too! so quote everything.
- Iterator iterator = args.iterator();
- while(iterator.hasNext()) {
- // commandLine += quote + iterator.next() + quote + " ";
- String arg = (String)iterator.next();
- if (arg.equalsIgnoreCase("-classic")) {
- Connector.Argument optionsArg =
- (Connector.Argument)argumentMap.get("options");
- String options = optionsArg.value();
- options = "-classic" + " " + options;
- optionsArg.setValue(options);
- Jdebug.theDebugger.signal(appID, MESSAGE, "VM options: '" + options +
"'");
- }
- else
- commandLine += quote + arg + quote + " ";
- }
- mainArg.setValue(commandLine);
-
- // signal(DEBUG, "Command line: '"+executable+"
"+commandLine+"'");
-
- VirtualMachine vm = null;
-
- try {
- vm = connector.launch(argumentMap);
- Jdebug.theDebugger.signal(appID, MESSAGE, "Launched VM " +
vm.description());
- } catch (IOException ex) {
- Debug.printIf(ex);
- throw new JDEException("Unable to launch: " +
ex.toString().replace('\\','/'));
- } catch (IllegalConnectorArgumentsException ex) {
- throw new JDEException("Invalid or inconsistent connector arguments for
connector '"+connector+"'");
- } catch (VMStartException ex) {
- // dumpFailedAppStreams(ex.process());
- throw new
JDEException(ex.getMessage().toString().replace('\\','/'));
- }
-
- // note that new App might raise a jdeexception.
- Application app = new Application(Jdebug.theDebugger, appID, vm);
-
- if (Jdebug.theDebugger.appExists(appID)) {
- app.shutdown();
- throw new JDEException("An application with the same ID exists.");
- }
-
- Jdebug.theDebugger.addApplication(appID, app);
-
- // Create a socket for connecting the application's standard I/O
- // to Emacs and a thread that waits for Emacs to connect to the socket.
- int port = app.initSIOConnect();
-
- // Tell Emacs the number of the standard I/O socket.
- app.signalCommandResult(cmdID, new Integer(port));
-
- // Wait for Emacs to connect to the SIO socket, then
- // create threads for transporting standard in, out, and error.
- app.initSIOTransport();
-
- }
-
- public Object clone() {return new LaunchApplication();}
-
-} // LaunchApplication
-
-
-/*
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.6 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+
+import com.sun.jdi.connect.LaunchingConnector;
+import java.util.Map;
+import com.sun.jdi.connect.Connector;
+import java.util.Iterator;
+import com.sun.jdi.VirtualMachine;
+import java.io.IOException;
+import com.sun.jdi.connect.IllegalConnectorArgumentsException;
+import com.sun.jdi.connect.VMStartException;
+import jde.debugger.DebuggeeProcess;
+import jde.debugger.Jdebug;
+import jde.debugger.Debug;
+import jde.debugger.DebuggeeSIO;
+
+
+/**
+ * Launches an application.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * launch app_id [-use_executable javax] classname [args]
+ * </pre>
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.6 $
+ */
+public class LaunchApplication extends DebugSessionCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ public void doCommand() throws JDEException {
+
+ // this is the connector that launches a debuggee vm
+ String connectSpec = "com.sun.jdi.CommandLineLaunch";
+
+ // check if this kind of connector is, indeed,
+ // available. if not, throw an exception.
+ LaunchingConnector connector = (LaunchingConnector) getConnector(connectSpec);
+ if (connector == null)
+ throw new JDEException("No such connector is available: "+connectSpec);
+
+
+ // first set up the argument map. a table that describes the
+ // different keys should be in the public jpda documentation.
+ // internally, it is at
+ //
http://jbug/jbug/doc/conninv.html
+ Map argumentMap = connector.defaultArguments();
+
+ Connector.Argument mainArg =
+ (Connector.Argument)argumentMap.get("main");
+
+ // compose the command line
+ String commandLine = "";
+ String quote =((Connector.Argument)argumentMap.get("quote")).value();
+
+ // check if there are special launch options we need to process
+ if (args.size() == 0)
+ throw new JDEException("Insufficient arguments");
+
+ String executable = "java";
+ // be careful with the loop here....
+ while ((args.size() >0)
+ && args.get(0).toString().startsWith("-")) {
+ String arg = args.remove(0).toString().toLowerCase();
+ if (arg.equals("-vmexec")) {
+ if (args.size() == 0)
+ throw new JDEException("Missing argument to 'use_executable'");
+ executable = args.remove(0).toString();
+ Connector.Argument vmexecArg =
+ (Connector.Argument)argumentMap.get("vmexec");
+ vmexecArg.setValue(executable);
+ }
+ else if (arg.equals("-home")) {
+ if (args.size() == 0)
+ throw new JDEException("Missing argument to 'home'");
+ String home = args.remove(0).toString();
+ Connector.Argument homeArg = (Connector.Argument) argumentMap.get("home");
+ homeArg.setValue(home);
+ continue;
+ }
+ else {
+ args.add(0, arg);
+ break;
+ }
+ }
+
+ if (args.size() == 0)
+ throw new JDEException("Missing arguments: no class specified?");
+
+ // take care of spaces too! so quote everything.
+ Iterator iterator = args.iterator();
+ while(iterator.hasNext()) {
+ // commandLine += quote + iterator.next() + quote + " ";
+ String arg = (String)iterator.next();
+ if (arg.equalsIgnoreCase("-classic")) {
+ Connector.Argument optionsArg =
+ (Connector.Argument)argumentMap.get("options");
+ String options = optionsArg.value();
+ options = "-classic" + " " + options;
+ optionsArg.setValue(options);
+ jde.signal(procID, MESSAGE, "VM options: '" + options +
"'");
+ }
+ else
+ commandLine += quote + arg + quote + " ";
+ }
+ mainArg.setValue(commandLine);
+
+ // signal(DEBUG, "Command line: '"+executable+"
"+commandLine+"'");
+
+ VirtualMachine vm = null;
+
+ try {
+ vm = connector.launch(argumentMap);
+ jde.signal(procID, MESSAGE, "Launched VM " + vm.description());
+ } catch (IOException ex) {
+ Debug.printIf(ex);
+ throw new JDEException("Unable to launch: " +
ex.toString().replace('\\','/'));
+ } catch (IllegalConnectorArgumentsException ex) {
+ throw new JDEException("Invalid or inconsistent connector arguments for
connector '"+connector+"'");
+ } catch (VMStartException ex) {
+ // dumpFailedAppStreams(ex.process());
+ throw new
JDEException(ex.getMessage().toString().replace('\\','/'));
+ }
+
+ // note that new debuggee process might raise a jdeexception.
+ DebuggeeProcess proc = new DebuggeeProcess(procID, vm);
+
+ if (procRegistry.processExists(procID)) {
+ proc.shutdown();
+ throw new JDEException("An application with the same ID exists.");
+ }
+
+ procRegistry.addProcess(procID, proc);
+
+ DebuggeeSIO procSIO = proc.getSIO();
+
+ // Create a socket for connecting the application's standard I/O
+ // to Emacs and a thread that waits for Emacs to connect to the socket.
+ int port = procSIO.initConnect(cmdID);
+
+ // Tell Emacs the number of the standard I/O socket.
+// jde.signalCommandResult(procID, cmdID, new Integer(port));
+ }
+
+ public Object clone() {return new LaunchApplication();}
+
+} // LaunchApplication
+
+
+/*
* $Log: LaunchApplication.java,v $
- * Revision 1.1 2000/08/13 13:49:12 michaels
- * Initial checkin
- *
- * Revision 1.3 2000/03/03 07:45:05 paulk
- * Replaced backslashes with forward slashes in launch error messages.
- *
- * Revision 1.2 2000/01/31 12:41:45 paulk
- * * Continue converting commands from functional to OO implementation.
- *
- * Revision 1.1 2000/01/30 12:39:50 paulk
- * Defines command to launch debuggee application.
- *
- */
-
-// End of LaunchApplication.java
+ * Revision 1.6 2001/05/24 02:50:06 paulk
+ * Moved jde.signalCommandResult(....,
+ * port) from LaunchApplication.java into the same thread that creates a
+ * server SIO socket to make sure that Emacs connects to this socket after its
+ * creation. Thanks to "Eugene Gavrilov" <eag99(a)mail.ru>.
+ *
+ * Revision 1.5 2001/03/24 05:42:37 paulk
+ * Updated to reflect reorganization of debugger code.
+ *
+ * Revision 1.4 2000/07/28 06:27:02 paulk
+ * Committing all modified files.
+ *
+ * Revision 1.3 2000/03/03 07:45:05 paulk
+ * Replaced backslashes with forward slashes in launch error messages.
+ *
+ * Revision 1.2 2000/01/31 12:41:45 paulk
+ * * Continue converting commands from functional to OO implementation.
+ *
+ * Revision 1.1 2000/01/30 12:39:50 paulk
+ * Defines command to launch debuggee application.
+ *
+ */
+
+// End of LaunchApplication.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/ListenShmem.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/command/ListenShmem.java,v
retrieving revision 1.1
diff -u -r1.1 ListenShmem.java
--- xemacs-packages/jde/java/src/jde/debugger/command/ListenShmem.java 2000/08/13
13:49:12 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/command/ListenShmem.java 2001/08/15
05:27:48
@@ -1,123 +1,120 @@
-/*
- * Copyright (c) 2000 Paul Kinnucan
- *
- * $Revision: 1.1 $
- */
-
-package jde.debugger.command;
-import jde.debugger.JDEException;
-import com.sun.jdi.connect.ListeningConnector;
-import java.util.Map;
-import com.sun.jdi.connect.Connector;
-import jde.debugger.Jdebug;
-import com.sun.jdi.VirtualMachine;
-import jde.debugger.Application;
-import java.io.IOException;
-import jde.debugger.Debug;
-import com.sun.jdi.connect.IllegalConnectorArgumentsException;
-
-
-/**
- * Listens in shared memory for a debuggee vm requesting debug
- * services.
- * <p>
- *
- * <b>Syntax:</b>
- * <pre>
- * listen_shmem app_id name
- * </pre>
- *
- * @author Paul Kinnucan
- * @version $Revision: 1.1 $
- */
-public class ListenShmem extends DebugSessionCommand {
-
- protected void doCommand() throws JDEException {
-
- if (args.size() < 1)
- throw new JDEException("Missing name");
-
- final String address = args.remove(0).toString();
-
- String connectSpec = "com.sun.jdi.SharedMemoryListen";
-
- final ListeningConnector connector = (ListeningConnector) getConnector(connectSpec);
-
- if (connector == null)
- throw new JDEException("No such connector is available: "+connectSpec);
-
- Thread thread = new Thread("Listen on shared memory channel.") {
-
- public void run() {
-
- try {
- Map argumentMap = connector.defaultArguments();
-
- Connector.Argument nameArg =
- (Connector.Argument)argumentMap.get("name");
- nameArg.setValue(address);
-
- Jdebug.theDebugger.signalCommandResult(appID, cmdID);
- Jdebug.theDebugger.signal(appID,
- MESSAGE,
- "Listening at shared memory address: " + address);
- connector.startListening(argumentMap);
- VirtualMachine vm = connector.accept(argumentMap);
- connector.stopListening(argumentMap);
-
- // note that new App might raise a jdeexception.
- Application app = new Application(Jdebug.theDebugger, appID, vm);
-
-
- if (Jdebug.theDebugger.appExists(appID)) {
- app.shutdown();
- app.signal(MESSAGE, "An application with the same ID already exists.");
- }
-
- Jdebug.theDebugger.addApplication(appID, app);
-
-
-
- app.signal(MESSAGE, "Attached VM (shmem) " + vm.description());
-
-
- } catch (IOException ex) {
- Debug.printIf(ex);
- Jdebug.theDebugger.signal(appID,
- MESSAGE,
- "I/O error occured while listening at shared memory address:"
- + address);
- } catch (IllegalConnectorArgumentsException ex) {
- Jdebug.theDebugger.signal(appID,
- MESSAGE,
- "Illegal argument error occurred while listening " +
- "at shared memory address: " + address);
- }
-
- }
- };
-
- thread.start();
-
- }
-
- public Object clone() {return new ListenShmem();}
-
-} // ListenShmem
-
-
-/*
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.3 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+import com.sun.jdi.connect.ListeningConnector;
+import java.util.Map;
+import com.sun.jdi.connect.Connector;
+import jde.debugger.Jdebug;
+import com.sun.jdi.VirtualMachine;
+import jde.debugger.DebuggeeProcess;
+import java.io.IOException;
+import jde.debugger.Debug;
+import com.sun.jdi.connect.IllegalConnectorArgumentsException;
+
+
+/**
+ * Listens in shared memory for a debuggee vm requesting debug
+ * services.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * listen_shmem app_id name
+ * </pre>
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.3 $
+ */
+public class ListenShmem extends DebugSessionCommand {
+
+ protected void doCommand() throws JDEException {
+
+ if (args.size() < 1)
+ throw new JDEException("Missing name");
+
+ final String address = args.remove(0).toString();
+
+ String connectSpec = "com.sun.jdi.SharedMemoryListen";
+
+ final ListeningConnector connector = (ListeningConnector)
getConnector(connectSpec);
+
+ if (connector == null)
+ throw new JDEException("No such connector is available: "+connectSpec);
+
+ Thread thread = new Thread("Listen on shared memory channel.") {
+
+ public void run() {
+
+ try {
+ Map argumentMap = connector.defaultArguments();
+
+ Connector.Argument nameArg =
+ (Connector.Argument)argumentMap.get("name");
+ nameArg.setValue(address);
+
+ jde.signalCommandResult(procID, cmdID);
+ jde.signal(procID, MESSAGE,
+ "Listening at shared memory address: " + address);
+ connector.startListening(argumentMap);
+ VirtualMachine vm = connector.accept(argumentMap);
+ connector.stopListening(argumentMap);
+
+ // note that new App might raise a jdeexception.
+ DebuggeeProcess proc = new DebuggeeProcess(procID, vm);
+
+
+ if (procRegistry.processExists(procID)) {
+ proc.shutdown();
+ jde.signal(procID, MESSAGE, "An application with the same ID already
exists.");
+ }
+
+ procRegistry.addProcess(procID, proc);
+
+
+
+ jde.signal(procID, MESSAGE, "Attached VM (shmem) " + vm.description());
+
+
+ } catch (IOException ex) {
+ Debug.printIf(ex);
+ jde.signal(procID, MESSAGE,
+ "I/O error occured while listening at shared memory address:"
+ + address);
+ } catch (IllegalConnectorArgumentsException ex) {
+ jde.signal(procID, MESSAGE,
+ "Illegal argument error occurred while listening " +
+ "at shared memory address: " + address);
+ }
+
+ }
+ };
+
+ thread.start();
+
+ }
+
+ public Object clone() {return new ListenShmem();}
+
+} // ListenShmem
+
+
+/*
* $Log: ListenShmem.java,v $
- * Revision 1.1 2000/08/13 13:49:12 michaels
- * Initial checkin
- *
- * Revision 1.2 2000/04/10 05:44:54 paulk
- * Corrected spelling error in message.
- *
- * Revision 1.1 2000/01/30 12:42:19 paulk
- * Defines command to attach debugger to an existing application through
- * shared memory.
- *
- */
-
-// End of ListenShmem.java
+ * Revision 1.3 2001/03/24 05:42:37 paulk
+ * Updated to reflect reorganization of debugger code.
+ *
+ * Revision 1.2 2000/04/10 05:44:54 paulk
+ * Corrected spelling error in message.
+ *
+ * Revision 1.1 2000/01/30 12:42:19 paulk
+ * Defines command to attach debugger to an existing application through
+ * shared memory.
+ *
+ */
+
+// End of ListenShmem.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/ListenSocket.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/command/ListenSocket.java,v
retrieving revision 1.1
diff -u -r1.1 ListenSocket.java
--- xemacs-packages/jde/java/src/jde/debugger/command/ListenSocket.java 2000/08/13
13:49:12 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/command/ListenSocket.java 2001/08/15
05:27:48
@@ -1,116 +1,116 @@
-/*
- * Copyright (c) 2000 Paul Kinnucan
- *
- * $Revision: 1.1 $
- */
-
-package jde.debugger.command;
-import jde.debugger.JDEException;
-import com.sun.jdi.connect.ListeningConnector;
-import java.util.Map;
-import com.sun.jdi.connect.Connector;
-import com.sun.jdi.VirtualMachine;
-import jde.debugger.Application;
-import com.sun.jdi.connect.IllegalConnectorArgumentsException;
-import jde.debugger.Jdebug;
-import java.io.IOException;
-import jde.debugger.Debug;
-
-
-/**
- * Listens on a socket for a debuggee application
- * requesting debug services.
- * <p>
- *
- * <b>Syntax:</b>
- * <pre>
- * listen_socket app_id port
- * </pre>
- *
- * @author Paul Kinnucan
- * @version $Revision: 1.1 $
- */
-public class ListenSocket extends DebugSessionCommand {
-
- public ListenSocket() {
-
- }
-
- protected void doCommand() throws JDEException {
-
- if (args.size() < 1)
- throw new JDEException("Missing name");
-
- final String address = args.remove(0).toString();
-
- String connectSpec = "com.sun.jdi.SocketListen";
-
- final ListeningConnector connector = (ListeningConnector) getConnector(connectSpec);
-
- if (connector == null)
- throw new JDEException("No such connector is available: "+connectSpec);
-
- Thread thread = new Thread("Listen on socket.") {
-
- public void run() {
- try {
-
- Map argumentMap = connector.defaultArguments();
-
- Connector.Argument portArg =
- (Connector.Argument)argumentMap.get("port");
- portArg.setValue(address);
-
- Jdebug.theDebugger.signalCommandResult(appID, cmdID);
- Jdebug.theDebugger.signal(appID, MESSAGE, "Listening at socket address: "
+ address);
- connector.startListening(argumentMap);
- VirtualMachine vm = connector.accept(argumentMap);
- connector.stopListening(argumentMap);
-
- // note that new App might raise a jdeexception.
- Application app = new Application(Jdebug.theDebugger, appID, vm);
-
-
- if (Jdebug.theDebugger.appExists(appID)) {
- app.shutdown();
- app.signal(MESSAGE, "Error: An application with the same ID exists.");
- }
-
- Jdebug.theDebugger.addApplication(appID, app);
-
-
- app.signal(MESSAGE, "Attached VM (socket) " + vm.description());
-
-
- } catch (IOException ex) {
- Debug.printIf(ex);
- Jdebug.theDebugger.signal(appID, MESSAGE, "Error occured listening on
socket.");
- } catch(IllegalConnectorArgumentsException ex) {
- Jdebug.theDebugger.signal(appID, MESSAGE,
- "Illegal connector arguments for connector '"+connector);
- }
- }
- };
-
- thread.start();
-
- }
-
- public Object clone() {return new ListenSocket();}
-
-
-} // ListenSocket
-
-
-/*
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.2 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+import com.sun.jdi.connect.ListeningConnector;
+import java.util.Map;
+import com.sun.jdi.connect.Connector;
+import com.sun.jdi.VirtualMachine;
+import jde.debugger.DebuggeeProcess;
+import com.sun.jdi.connect.IllegalConnectorArgumentsException;
+import jde.debugger.Jdebug;
+import java.io.IOException;
+import jde.debugger.Debug;
+
+
+/**
+ * Listens on a socket for a debuggee application
+ * requesting debug services.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * listen_socket app_id port
+ * </pre>
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.2 $
+ */
+public class ListenSocket extends DebugSessionCommand {
+
+ public ListenSocket() {
+
+ }
+
+ protected void doCommand() throws JDEException {
+
+ if (args.size() < 1)
+ throw new JDEException("Missing name");
+
+ final String address = args.remove(0).toString();
+
+ String connectSpec = "com.sun.jdi.SocketListen";
+
+ final ListeningConnector connector = (ListeningConnector)
getConnector(connectSpec);
+
+ if (connector == null)
+ throw new JDEException("No such connector is available: "+connectSpec);
+
+ Thread thread = new Thread("Listen on socket.") {
+
+ public void run() {
+ try {
+
+ Map argumentMap = connector.defaultArguments();
+
+ Connector.Argument portArg =
+ (Connector.Argument)argumentMap.get("port");
+ portArg.setValue(address);
+
+ jde.signalCommandResult(procID, cmdID);
+ jde.signal(procID, MESSAGE, "Listening at socket address: " + address);
+ connector.startListening(argumentMap);
+ VirtualMachine vm = connector.accept(argumentMap);
+ connector.stopListening(argumentMap);
+
+ // note that new process might raise a jdeexception.
+ DebuggeeProcess proc = new DebuggeeProcess(procID, vm);
+
+
+ if (procRegistry.processExists(procID)) {
+ proc.shutdown();
+ jde.signal(procID, MESSAGE, "Error: An application with the same ID
exists.");
+ }
+
+ procRegistry.addProcess(procID, proc);
+
+
+ jde.signal(procID, MESSAGE, "Attached VM (socket) " + vm.description());
+
+
+ } catch (IOException ex) {
+ Debug.printIf(ex);
+ jde.signal(procID, MESSAGE, "Error occured listening on socket.");
+ } catch(IllegalConnectorArgumentsException ex) {
+ jde.signal(procID, MESSAGE,
+ "Illegal connector arguments for connector '"+connector);
+ }
+ }
+ };
+
+ thread.start();
+
+ }
+
+ public Object clone() {return new ListenSocket();}
+
+
+} // ListenSocket
+
+
+/*
* $Log: ListenSocket.java,v $
- * Revision 1.1 2000/08/13 13:49:12 michaels
- * Initial checkin
- *
- * Revision 1.1 2000/01/30 12:45:18 paulk
- * Defines command to listen on a socket for a debuggee application
- * requiring debugger services.
- *
- */
-
-// End of ListenSocket.java
+ * Revision 1.2 2001/03/24 05:42:37 paulk
+ * Updated to reflect reorganization of debugger code.
+ *
+ * Revision 1.1 2000/01/30 12:45:18 paulk
+ * Defines command to listen on a socket for a debuggee application
+ * requiring debugger services.
+ *
+ */
+
+// End of ListenSocket.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/Quit.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/command/Quit.java,v
retrieving revision 1.1
diff -u -r1.1 Quit.java
--- xemacs-packages/jde/java/src/jde/debugger/command/Quit.java 2000/08/13 13:49:12 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/command/Quit.java 2001/08/15 05:27:48
@@ -1,51 +1,51 @@
-/*
- * Copyright (c) 2000 Paul Kinnucan
- *
- * $Revision: 1.1 $
- */
-
-package jde.debugger.command;
-import jde.debugger.JDEException;
-import jde.debugger.Jdebug;
-
-
-/**
- * Kills the debugger.
- * <p>
- *
- * <b>Syntax:</b>
- * <pre>
- * quit
- * </pre>
- *
- * @author Paul Kinnucan
- * @version $Revision: 1.1 $
- */
-public class Quit extends DebugSessionCommand {
-
- protected void doCommand() throws JDEException {
- try {
- Jdebug.theDebugger.shutdown();
- } catch (Exception ex) {
- // do nothing
- }
- Jdebug.theDebugger.signalCommandResult(Jdebug.debuggerID, cmdID);
- System.exit(0);
- }
-
- public Object clone() {return new Quit();}
-
-} // Quit
-
-
-/*
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.2 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+import jde.debugger.Jdebug;
+
+
+/**
+ * Kills the debugger.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * quit
+ * </pre>
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.2 $
+ */
+public class Quit extends DebugSessionCommand {
+
+ protected void doCommand() throws JDEException {
+ try {
+ procRegistry.shutdownProcesses();
+ } catch (Exception ex) {
+ // do nothing
+ }
+ jde.signalCommandResult(Jdebug.debuggerID, cmdID);
+ System.exit(0);
+ }
+
+ public Object clone() {return new Quit();}
+
+} // Quit
+
+
+/*
* $Log: Quit.java,v $
- * Revision 1.1 2000/08/13 13:49:12 michaels
- * Initial checkin
- *
- * Revision 1.1 2000/01/31 12:47:01 paulk
- * Quit debugger.
- *
- */
-
-// End of Quit.java
+ * Revision 1.2 2001/03/24 05:42:37 paulk
+ * Updated to reflect reorganization of debugger code.
+ *
+ * Revision 1.1 2000/01/31 12:47:01 paulk
+ * Quit debugger.
+ *
+ */
+
+// End of Quit.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/Resume.java
===================================================================
RCS file: Resume.java
diff -N Resume.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ Resume.java Tue Aug 14 22:27:48 2001
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.1 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+import java.util.Iterator;
+import jde.debugger.Etc;
+import com.sun.jdi.ObjectReference;
+import com.sun.jdi.ThreadReference;
+import com.sun.jdi.ThreadGroupReference;
+
+
+/**
+ * 'resume' command.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * resume [threadID]*
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> threadIDs can be retrieved using the get_threads command
+ * <li> if the list is omitted, the entire VM is resumed
+ * <li> threadIDs can refer to either threads or thereadgroups.
+ * </ul>
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.1 $
+ *
+ */
+public class Resume extends DebugProcessCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ public void doCommand() throws JDEException {
+ // see if there are arguments (should be the thread id). if so, we
+ // resume the thread ids passed. else, resume the whole vm.
+ if (args.size() > 0) {
+ Iterator it = args.iterator();
+ while (it.hasNext()) {
+ Long uniqueID = Etc.safeGetLong(it.next(), "thread(group)");
+
+ ObjectReference oRef = (ObjectReference)proc.getStore().get(uniqueID);
+ if (oRef == null) {
+ throw new JDEException("Invalid ThreadID, or the thread/threadgroup is
dead");
+ } else if (oRef instanceof ThreadReference) {
+ ((ThreadReference)oRef).resume();
+ } else if (oRef instanceof ThreadGroupReference) {
+ ((ThreadGroupReference)oRef).resume();
+ } else {
+ throw new JDEException("The object is not a thread or a threadgroup");
+ }
+ }
+ jde.signalCommandResult(procID, cmdID);
+ } else {
+ try {
+ proc.getVM().resume();
+ jde.signalCommandResult(procID, cmdID);
+ } catch (Exception ex) {
+ throw new JDEException("Unable to resume the application");
+ }
+ }
+ }
+
+ public Object clone() {return new Resume();}
+
+} // Resume
+
+/*
+ * $Log: Resume.java,v $
+ * Revision 1.1 2001/03/24 13:35:25 paulk
+ * Initial revision.
+ *
+ *
+ */
+
+// End of Resume.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/Run.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/command/Run.java,v
retrieving revision 1.1
diff -u -r1.1 Run.java
--- xemacs-packages/jde/java/src/jde/debugger/command/Run.java 2000/08/13 13:49:13 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/command/Run.java 2001/08/15 05:27:48
@@ -1,54 +1,54 @@
-/*
- * Copyright (c) 2000 Paul Kinnucan
- *
- * $Revision: 1.1 $
- */
-
-package jde.debugger.command;
-import jde.debugger.JDEException;
-
-
-/**
- * Runs an application.
- * <p>
- *
- * <b>Syntax:</b>
- * <pre>
- * run
- * </pre>
- *
- * @author Paul Kinnucan
- * @version $Revision: 1.1 $
- */
-public class Run extends DebugApplicationCommand {
-
- /**
- *
- * @exception jde.debugger.JDEException <description>
- */
- public void doCommand() throws JDEException {
-
- try {
- app.getVM().resume();
- } catch (Exception ex) {
- throw new JDEException("Unspecified Error occured: "+ex.toString());
- }
- app.signalCommandResult(cmdID);
-
- }
-
- public Object clone() {return new Run();}
-
-} // Run
-
-/*
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.2 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+
+
+/**
+ * Runs an application.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * run
+ * </pre>
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.2 $
+ */
+public class Run extends DebugProcessCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ public void doCommand() throws JDEException {
+
+ try {
+ proc.getVM().resume();
+ } catch (Exception ex) {
+ throw new JDEException("Unspecified Error occured: "+ex.toString());
+ }
+ jde.signalCommandResult(procID, cmdID);
+
+ }
+
+ public Object clone() {return new Run();}
+
+} // Run
+
+/*
* $Log: Run.java,v $
- * Revision 1.1 2000/08/13 13:49:13 michaels
- * Initial checkin
- *
- * Revision 1.1 2000/01/31 12:48:02 paulk
- * Start or continue application.
- *
- */
-
-// End of Run.java
+ * Revision 1.2 2001/03/24 05:42:37 paulk
+ * Updated to reflect reorganization of debugger code.
+ *
+ * Revision 1.1 2000/01/31 12:48:02 paulk
+ * Start or continue application.
+ *
+ */
+
+// End of Run.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/Step.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/command/Step.java,v
retrieving revision 1.1
diff -u -r1.1 Step.java
--- xemacs-packages/jde/java/src/jde/debugger/command/Step.java 2001/02/12 06:25:36 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/command/Step.java 2001/08/15 05:27:48
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2000 Paul Kinnucan
+ * Copyright (c) 2000, 2001 Paul Kinnucan
*
- * $Revision: 1.1 $
+ * $Revision: 1.2 $
*/
package jde.debugger.command;
@@ -48,9 +48,9 @@
* @see jde.debugger.EventHandler#stepEvent(StepEvent)
*
* @author Paul Kinnucan
- * @version $Revision: 1.1 $
+ * @version $Revision: 1.2 $
*/
-public class Step extends DebugApplicationCommand {
+public class Step extends DebugProcessCommand {
/**
*
@@ -81,7 +81,7 @@
// find the thread on which to step
Long uniqueID = Etc.safeGetLong(args.remove(0), "thread ID");
- ThreadReference tRef = (ThreadReference) app.getStore().get(uniqueID);
+ ThreadReference tRef = (ThreadReference) proc.getStore().get(uniqueID);
// it should exist
if (tRef == null) {
@@ -98,7 +98,7 @@
clearPreviousStep(tRef);
// set a new request!
- EventRequestManager erm = app.getVM().eventRequestManager();
+ EventRequestManager erm = proc.getVM().eventRequestManager();
StepRequest request =
erm.createStepRequest(tRef, StepRequest.STEP_LINE, depth);
request.setSuspendPolicy(Etc.getSuspendPolicyFromArgs(args));
@@ -117,9 +117,9 @@
request.enable();
// and now resume the vm. the thread suspended is resumed now.
- app.getVM().resume();
+ proc.getVM().resume();
- app.signalCommandResult(cmdID);
+ jde.signalCommandResult(procID, cmdID);
}
@@ -128,8 +128,8 @@
* per thread
*/
private void clearPreviousStep(ThreadReference thread) {
- synchronized (app) {
- EventRequestManager mgr = app.getVM().eventRequestManager();
+ synchronized (proc) {
+ EventRequestManager mgr = proc.getVM().eventRequestManager();
List requests = mgr.stepRequests();
Iterator iter = requests.iterator();
while (iter.hasNext()) {
@@ -149,8 +149,8 @@
/*
* $Log: Step.java,v $
- * Revision 1.1 2001/02/12 06:25:36 paulk
- * Initial XEmacs version.
+ * Revision 1.2 2001/03/24 05:42:37 paulk
+ * Updated to reflect reorganization of debugger code.
*
* Revision 1.1 2000/08/14 02:40:40 paulk
* Initial revision.
Index: xemacs-packages/jde/java/src/jde/debugger/command/Suspend.java
===================================================================
RCS file: Suspend.java
diff -N Suspend.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ Suspend.java Tue Aug 14 22:27:48 2001
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.1 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+import java.util.Iterator;
+import jde.debugger.Etc;
+import com.sun.jdi.ObjectReference;
+import com.sun.jdi.ThreadReference;
+import com.sun.jdi.ThreadGroupReference;
+
+
+/**
+ * 'suspend' command.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * suspend [threadID]*
+ *
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> threadIDs can be retrieved using the get_threads command
+ * <li> if the list is omitted, the entire VM is suspended
+ * <li> threadIDs can refer to either threads or threadgroups.
+ * </ul>
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.1 $
+ *
+ */
+public class Suspend extends DebugProcessCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ public void doCommand() throws JDEException {
+ // see if there are arguments (should be the thread id). if so, we
+ // suspend the thread ids passed. else, suspend the whole vm.
+ if (args.size() > 0) {
+ Iterator it = args.iterator();
+ while (it.hasNext()) {
+
+ Long uniqueID = Etc.safeGetLong(it.next(), "thread(group)");
+
+ ObjectReference oRef = (ObjectReference)proc.getStore().get(uniqueID);
+ if (oRef == null) {
+ throw new JDEException("Invalid ThreadID, or the thread/threadgroup is
dead");
+ } else if (oRef instanceof ThreadReference) {
+ ((ThreadReference)oRef).suspend();
+ } else if (oRef instanceof ThreadGroupReference) {
+ ((ThreadGroupReference)oRef).suspend();
+ } else {
+ throw new JDEException("The object is not a thread or a threadgroup");
+ }
+ }
+ jde.signalCommandResult(procID, cmdID);
+ } else {
+ try {
+ proc.getVM().suspend();
+ jde.signalCommandResult(procID, cmdID);
+ } catch (Exception ex) {
+ throw new JDEException("Unable to suspend the application");
+ }
+ }
+ }
+
+ public Object clone() {return new Suspend();}
+
+} // Suspend
+
+/*
+ * $Log: Suspend.java,v $
+ * Revision 1.1 2001/03/24 13:35:25 paulk
+ * Initial revision.
+ *
+ *
+ */
+
+// End of Suspend.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/TraceClasses.java
===================================================================
RCS file: TraceClasses.java
diff -N TraceClasses.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ TraceClasses.java Tue Aug 14 22:27:48 2001
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.1 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+import java.util.List;
+import jde.debugger.Etc;
+import com.sun.jdi.request.EventRequestManager;
+import com.sun.jdi.request.ClassPrepareRequest;
+import java.util.Iterator;
+import com.sun.jdi.request.ClassUnloadRequest;
+
+
+/**
+ * 'trace_classes' command.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * trace_classes <u>type</u>
+ * [{@link Etc#getSuspendPolicyFromArgs(List) suspend-policy}]
+ * [{@link Etc#getClassFiltersFromArgs(List) class-filters}]
+ * [{@link Etc#getClassExFiltersFromArgs(List) class-exclusion-filters}]
+ * </pre>
+ *
+ * <b>Returns:</b>
+ * <pre>
+ * (jde-dbo-command-result cmd_id <u>requestID</u>)
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> <u>type</u> is either "preparation" or
"unloading"
+ * <li> use <u>requestID</u> to cancel the trace request.
+ * </ul>
+ *
+ * <p>
+ * @see EventHandler#classPrepareEvent(ClassPrepareEvent)
+ * @see EventHandler#classUnloadEvent(ClassUnloadEvent)
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.1 $
+ *
+ */
+public class TraceClasses extends DebugProcessCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ public void doCommand() throws JDEException {
+ if (args.size() < 1)
+ throw new JDEException("Insufficient arguments");
+
+ String type = args.remove(0).toString().toLowerCase();
+
+ if (!(type.equals("preparation") || type.equals("unloading")))
+ throw new JDEException("Invalid type");
+
+ Long requestID = null;
+
+ List classFilters = Etc.getClassFiltersFromArgs(args);
+ List classExFilters = Etc.getClassExFiltersFromArgs(args);
+
+ EventRequestManager em = proc.getVM().eventRequestManager();
+
+ if (type.equals("preparation")) {
+
+ ClassPrepareRequest cpr = em.createClassPrepareRequest();
+
+ cpr.setSuspendPolicy(Etc.getSuspendPolicyFromArgs(args));
+
+ if (classFilters != null) {
+ Iterator it = classFilters.iterator();
+ while (it.hasNext())
+ cpr.addClassFilter(it.next().toString());
+ }
+ if (classExFilters != null) {
+ Iterator it = classExFilters.iterator();
+ while (it.hasNext())
+ cpr.addClassExclusionFilter(it.next().toString());
+ }
+ requestID = addIdentifiableRequest(cpr);
+
+ } else if (type.equals("unloading")) {
+
+ ClassUnloadRequest cur = em.createClassUnloadRequest();
+
+ cur.setSuspendPolicy(Etc.getSuspendPolicyFromArgs(args));
+
+ if (classFilters != null) {
+ Iterator it = classFilters.iterator();
+ while (it.hasNext())
+ cur.addClassFilter(it.next().toString());
+ }
+ if (classExFilters != null) {
+ Iterator it = classExFilters.iterator();
+ while (it.hasNext())
+ cur.addClassExclusionFilter(it.next().toString());
+ }
+ requestID = addIdentifiableRequest(cur);
+ }
+ jde.signalCommandResult(procID, cmdID, requestID);
+ }
+
+ public Object clone() {return new TraceClasses();}
+
+} // TraceClasses
+
+/*
+ * $Log: TraceClasses.java,v $
+ * Revision 1.1 2001/03/24 13:35:25 paulk
+ * Initial revision.
+ *
+ *
+ */
+
+// End of TraceClasses.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/TraceExceptions.java
===================================================================
RCS file: TraceExceptions.java
diff -N TraceExceptions.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ TraceExceptions.java Tue Aug 14 22:27:48 2001
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.1 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+import jde.debugger.spec.EventRequestSpecList;
+import jde.debugger.spec.EventRequestSpec;
+import jde.debugger.Etc;
+
+
+
+/**
+ * 'trace_exceptions' command.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * trace_exceptions classPattern <u>type</u>
+ * [{@link Etc#getThreadFromArgs(List) thread-restriction}]
+ * [{@link Etc#getSuspendPolicyFromArgs(List) suspend-policy}]
+ * [{@link Etc#getClassFiltersFromArgs(List) class-filters}]
+ * [{@link Etc#getClassExFiltersFromArgs(List) class-exclusion-filters}]
+ * </pre>
+ *
+ * <b>Returns:</b>
+ * <pre>
+ * (jde-dbo-command-result cmd_id specID)
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> <u>type</u> can be "caught", "uncaught", or
"both"
+ * <li> specID is a 'long', and can be used in the 'clear'
+ * command
+ * </ul>
+ *
+ * <p>
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.1 $
+ *
+ */
+public class TraceExceptions extends DebugProcessCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ public void doCommand() throws JDEException {
+ if (args.size() < 2)
+ throw new JDEException("Insufficient arguments");
+
+ String classPattern = args.remove(0).toString();
+ String type = args.remove(0).toString().toLowerCase();
+
+ boolean caught = false;
+ boolean uncaught = false;
+ if (type.equals("both")) {
+ caught = true;
+ uncaught = true;
+ } else if (type.equals("caught")) {
+ caught = true;
+ } else if (type.equals("uncaught")) {
+ uncaught = true;
+ } else {
+ throw new JDEException("'"+type+"' not understood");
+ }
+
+ EventRequestSpecList eventRequests = proc.getEventRequestSpecs();
+ EventRequestSpec er = eventRequests.createExceptionIntercept(classPattern, caught,
uncaught);
+ er.setThread(Etc.getThreadFromArgs(args));
+ er.setSuspendPolicy(Etc.getSuspendPolicyFromArgs(args));
+ er.setClassFilters(Etc.getClassFiltersFromArgs(args));
+ er.setClassExFilters(Etc.getClassExFiltersFromArgs(args));
+ eventRequests.install(er);
+
+ jde.signalCommandResult(procID, cmdID, er.getID());
+
+ }
+
+ public Object clone() {return new TraceExceptions();}
+
+} // TraceExceptions
+
+/*
+ * $Log: TraceExceptions.java,v $
+ * Revision 1.1 2001/03/24 13:35:25 paulk
+ * Initial revision.
+ *
+ *
+ */
+
+// End of TraceExceptions.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/TraceMethods.java
===================================================================
RCS file: TraceMethods.java
diff -N TraceMethods.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ TraceMethods.java Tue Aug 14 22:27:48 2001
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.1 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+import jde.debugger.Etc;
+import com.sun.jdi.ObjectReference;
+import com.sun.jdi.ThreadReference;
+import java.util.List;
+import com.sun.jdi.request.EventRequestManager;
+import com.sun.jdi.request.MethodEntryRequest;
+import java.util.Iterator;
+import com.sun.jdi.request.MethodExitRequest;
+
+
+ /**
+ * 'trace_methods' command.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * trace_methods <u>type</u>
+ * [{@link Etc#getThreadFromArgs(List) thread-restriction}]
+ * [{@link Etc#getSuspendPolicyFromArgs(List) suspend-policy}]
+ * [{@link Etc#getClassFiltersFromArgs(List) class-filters}]
+ * [{@link Etc#getClassExFiltersFromArgs(List) class-exclusion-filters}]
+ * </pre>
+ *
+ * <b>Returns:</b>
+ * <pre>
+ * (jde-dbo-command-result cmd_id <u>requestID</u>)
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> <u>type</u> is either "entry" or
"exit"
+ * <li> Use <u>requestID</u> to cancel the trace request.
+ * </ul>
+ *
+ * <p>
+ * @see EventHandler#methodEntryEvent(MethodEntryEvent)
+ * @see EventHandler#methodExitEvent(MethodExitEvent)
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.1 $
+ *
+ */
+public class TraceMethods extends DebugProcessCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ public void doCommand() throws JDEException {
+ if (args.size() < 2)
+ throw new JDEException("Insufficient arguments");
+
+ String type = args.remove(0).toString().toLowerCase();
+ if (!(type.equals("entry") || type.equals("exit")))
+ throw new JDEException("Invalid type");
+
+ Object thread = Etc.getThreadFromArgs(args);
+ ObjectReference tRef = null;
+ if (thread == null) {
+ tRef = null;
+ } else if (thread instanceof Long) {
+ tRef = (ObjectReference)proc.getStore().get(thread);
+ if (tRef == null) {
+ throw new JDEException("No such thread exists");
+ } else if (!(tRef instanceof ThreadReference)) {
+ throw new JDEException("No such thread exists (anymore?)");
+ }
+ } else if (thread instanceof String) {
+ tRef = proc.getThread(thread.toString());
+ }
+
+ List classFilters = Etc.getClassFiltersFromArgs(args);
+ List classExFilters = Etc.getClassExFiltersFromArgs(args);
+
+ Long requestID = null;
+
+ EventRequestManager em = proc.getVM().eventRequestManager();
+
+ if (type.equals("entry")) {
+
+ MethodEntryRequest mer = em.createMethodEntryRequest();
+
+ if (tRef != null)
+ mer.addThreadFilter((ThreadReference)tRef);
+
+ mer.setSuspendPolicy(Etc.getSuspendPolicyFromArgs(args));
+
+ if (classFilters != null) {
+ Iterator it = classFilters.iterator();
+ while (it.hasNext())
+ mer.addClassFilter(it.next().toString());
+ }
+ if (classExFilters != null) {
+ Iterator it = classExFilters.iterator();
+ while (it.hasNext())
+ mer.addClassExclusionFilter(it.next().toString());
+ }
+ requestID = addIdentifiableRequest(mer);
+
+ } else if (type.equals("exit")) {
+
+ MethodExitRequest mer = em.createMethodExitRequest();
+
+ if (tRef != null)
+ mer.addThreadFilter((ThreadReference)tRef);
+
+ mer.setSuspendPolicy(Etc.getSuspendPolicyFromArgs(args));
+
+ if (classFilters != null) {
+ Iterator it = classFilters.iterator();
+ while (it.hasNext())
+ mer.addClassFilter(it.next().toString());
+ }
+ if (classExFilters != null) {
+ Iterator it = classExFilters.iterator();
+ while (it.hasNext())
+ mer.addClassExclusionFilter(it.next().toString());
+ }
+ requestID = addIdentifiableRequest(mer);
+ }
+ jde.signalCommandResult(procID, cmdID, requestID);
+ }
+
+ public Object clone() {return new TraceMethods();}
+
+} // TraceMethods
+
+/*
+ * $Log: TraceMethods.java,v $
+ * Revision 1.1 2001/03/24 13:35:26 paulk
+ * Initial revision.
+ *
+ *
+ */
+
+// End of TraceMethods.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/TraceThreads.java
===================================================================
RCS file: TraceThreads.java
diff -N TraceThreads.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ TraceThreads.java Tue Aug 14 22:27:48 2001
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.1 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+import jde.debugger.Etc;
+import com.sun.jdi.ObjectReference;
+import com.sun.jdi.ThreadReference;
+import jde.debugger.Rep;
+import jde.debugger.ObjectStore;
+import java.util.List;
+import com.sun.jdi.request.EventRequestManager;
+import com.sun.jdi.request.ThreadStartRequest;
+import com.sun.jdi.request.ThreadDeathRequest;
+
+
+/**
+ * 'trace_threads' command.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * trace_threads <u>type</u> [threadID]
+ * [{@link Etc#getSuspendPolicyFromArgs(List) suspend-policy}]
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> <u>type</u> can be either "start" or
"death"
+ * <li> If no threadID is specified, all the corresponding thread
+ * events are raised.
+ * </ul>
+ *
+ * <p>
+ * @see EventHandler#threadStartEvent(ThreadStartEvent)
+ * @see EventHandler#threadDeathEvent(ThreadDeathEvent)
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.1 $
+ *
+ */
+public class TraceThreads extends DebugProcessCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ public void doCommand() throws JDEException {
+ if (args.size() < 2)
+ throw new JDEException("Insufficient arguments");
+
+ String type = args.remove(0).toString().toLowerCase();
+
+ if (!(type.equals("start") || type.equals("death")))
+ throw new JDEException("Invalid type");
+
+ List classFilters = Etc.getClassFiltersFromArgs(args);
+ List classExFilters = Etc.getClassExFiltersFromArgs(args);
+
+ EventRequestManager em = proc.getVM().eventRequestManager();
+
+ Long requestID = null;
+ ObjectStore store = proc.getStore();
+
+ if (type.equals("start")) {
+
+ ThreadStartRequest ter = em.createThreadStartRequest();
+
+ ter.setSuspendPolicy(Etc.getSuspendPolicyFromArgs(args));
+
+ if (args.size() > 0) {
+ Long threadID = Etc.safeGetLong(args.remove(0), "thread ID");
+ ObjectReference tRef = store.get(threadID);
+ if (tRef == null) {
+ throw new JDEException("No such thread exists");
+ } else if (!(tRef instanceof ThreadReference)) {
+ throw new JDEException("No such thread exists (anymore?)");
+ }
+ ter.addThreadFilter((ThreadReference)tRef);
+ }
+
+ requestID = addIdentifiableRequest(ter);
+
+ } else if (type.equals("death")) {
+
+ ThreadDeathRequest ter = em.createThreadDeathRequest();
+
+ ter.setSuspendPolicy(Etc.getSuspendPolicyFromArgs(args));
+
+ if (args.size() > 0) {
+ Long threadID = Etc.safeGetLong(args.remove(0), "thread ID");
+ ObjectReference tRef = store.get(threadID);
+ if (tRef == null) {
+ throw new JDEException("No such thread exists");
+ } else if (!(tRef instanceof ThreadReference)) {
+ throw new JDEException("No such thread exists (anymore?)");
+ }
+ ter.addThreadFilter((ThreadReference)tRef);
+ }
+
+ requestID = addIdentifiableRequest(ter);
+ }
+ jde.signalCommandResult(procID, cmdID, requestID);
+ }
+
+
+
+ public Object clone() {return new TraceThreads();}
+
+} // TraceThreads
+
+/*
+ * $Log: TraceThreads.java,v $
+ * Revision 1.1 2001/03/24 13:35:26 paulk
+ * Initial revision.
+ *
+ *
+ */
+
+// End of TraceThreads.java
Index: xemacs-packages/jde/java/src/jde/debugger/command/Watch.java
===================================================================
RCS file: Watch.java
diff -N Watch.java
--- /dev/null Tue Aug 14 14:29:33 2001
+++ Watch.java Tue Aug 14 22:27:48 2001
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2000, 2001 Paul Kinnucan
+ *
+ * $Revision: 1.1 $
+ */
+
+package jde.debugger.command;
+import jde.debugger.JDEException;
+import jde.debugger.spec.WatchpointSpec;
+import jde.debugger.Etc;
+import jde.debugger.spec.EventRequestSpecList;
+
+
+/**
+ * 'watch' command.
+ * <p>
+ *
+ * <b>Syntax:</b>
+ * <pre>
+ * watch classPattern fieldName <u>type</u>
+ * [{@link Etc#getThreadFromArgs(List) thread-restriction}]
+ * [{@link Etc#getExprFromArgs(List) expression-restriction}]
+ * [{@link Etc#getObjectIDFromArgs(List) object-id-restriction}]
+ * [{@link Etc#getSuspendPolicyFromArgs(List) suspend-policy}]
+ * [{@link Etc#getClassFiltersFromArgs(List) class-filters}]
+ * [{@link Etc#getClassExFiltersFromArgs(List) class-exclusion-filters}]
+ * </pre>
+ *
+ * <b>Returns:</b>
+ * <pre>
+ * (jde-dbo-command-result cmd_id specID)
+ * </pre>
+ *
+ * <b>Comments:</b>
+ * <ul>
+ * <li> <u>type</u> can be "for_access" or
"for_modification"
+ * <li> 'classPattern' can be a string pattern of the type *.Test
+ * <li> objectID is used when, for example, when you already know the
+ * object id of the object, the access/modification of which's field
+ * you're interested in.
+ * <li> specID is a 'long', that can be used in 'clear' commands.
+ * </ul>
+ *
+ * <p>
+ * @see EventHandler#watchpointEvent(WatchpointEvent)
+ *
+ * @author Paul Kinnucan
+ * @version $Revision: 1.1 $
+ *
+ */
+public class Watch extends DebugProcessCommand {
+
+ /**
+ *
+ * @exception jde.debugger.JDEException <description>
+ */
+ public void doCommand() throws JDEException {
+
+ if (args.size() < 3)
+ throw new JDEException("Insufficient arguments");
+
+ String classPattern = args.remove(0).toString();
+ String methodName = args.remove(0).toString();
+ String typeString = args.remove(0).toString().toLowerCase();
+ EventRequestSpecList eventRequests = proc.getEventRequestSpecs();
+
+ WatchpointSpec er = null;
+ if (typeString.equals("for_access")) {
+ if (!proc.getVM().canWatchFieldAccess())
+ throw new JDEException("This VM implementation cannot watch field
accesses");
+ er = eventRequests.createAccessWatchpoint(classPattern, methodName);
+ } else if (typeString.equals("for_modification")) {
+ if (!proc.getVM().canWatchFieldModification())
+ throw new JDEException("This VM implementation cannot watch field
modifications");
+ er = eventRequests.createModificationWatchpoint(classPattern, methodName);
+ } else {
+ throw new JDEException("'"+typeString+"' not understood: use
either 'for_access' or 'for_modification'");
+ }
+ er.setThread(Etc.getThreadFromArgs(args));
+ er.setExpression(Etc.getExprFromArgs(args));
+ er.setObjectID(Etc.getObjectIDFromArgs(args));
+ er.setSuspendPolicy(Etc.getSuspendPolicyFromArgs(args));
+ er.setClassFilters(Etc.getClassFiltersFromArgs(args));
+ er.setClassExFilters(Etc.getClassExFiltersFromArgs(args));
+ eventRequests.install(er);
+
+ jde.signalCommandResult(procID, cmdID, er.getID());
+ }
+
+ public Object clone() {return new Watch();}
+
+} // Watch
+
+/*
+ * $Log: Watch.java,v $
+ * Revision 1.1 2001/03/24 13:35:26 paulk
+ * Initial revision.
+ *
+ *
+ */
+
+// End of Watch.java
Index: xemacs-packages/jde/java/src/jde/debugger/expr/ASCII_UCodeESC_CharStream.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/expr/ASCII_UCodeESC_CharStream.java,v
retrieving revision 1.1
diff -u -r1.1 ASCII_UCodeESC_CharStream.java
---
xemacs-packages/jde/java/src/jde/debugger/expr/ASCII_UCodeESC_CharStream.java 2000/08/13
13:36:57 1.1
+++
xemacs-packages/jde/java/src/jde/debugger/expr/ASCII_UCodeESC_CharStream.java 2001/08/15
05:27:48
@@ -1,498 +1,498 @@
-/* Generated By:JavaCC: Do not edit this line. ASCII_UCodeESC_CharStream.java Version
0.7pre6 */
-package jde.debugger.expr;
-
-/**
- * An implementation of interface CharStream, where the stream is assumed to
- * contain only ASCII characters (with java-like unicode escape processing).
- */
-
-public final class ASCII_UCodeESC_CharStream
-{
- public static final boolean staticFlag = false;
- static final int hexval(char c) throws java.io.IOException {
- switch(c)
- {
- case '0' :
- return 0;
- case '1' :
- return 1;
- case '2' :
- return 2;
- case '3' :
- return 3;
- case '4' :
- return 4;
- case '5' :
- return 5;
- case '6' :
- return 6;
- case '7' :
- return 7;
- case '8' :
- return 8;
- case '9' :
- return 9;
-
- case 'a' :
- case 'A' :
- return 10;
- case 'b' :
- case 'B' :
- return 11;
- case 'c' :
- case 'C' :
- return 12;
- case 'd' :
- case 'D' :
- return 13;
- case 'e' :
- case 'E' :
- return 14;
- case 'f' :
- case 'F' :
- return 15;
- }
-
- throw new java.io.IOException(); // Should never come here
- }
-
- public int bufpos = -1;
- int bufsize;
- int available;
- int tokenBegin;
- private int bufline[];
- private int bufcolumn[];
-
- private int column = 0;
- private int line = 1;
-
- private java.io.InputStream inputStream;
-
- private boolean prevCharIsCR = false;
- private boolean prevCharIsLF = false;
-
- private byte[] nextCharBuf;
- private char[] buffer;
- private int maxNextCharInd = 0;
- private int nextCharInd = -1;
- private int inBuf = 0;
-
- private final void ExpandBuff(boolean wrapAround)
- {
- char[] newbuffer = new char[bufsize + 2048];
- int newbufline[] = new int[bufsize + 2048];
- int newbufcolumn[] = new int[bufsize + 2048];
-
- try
- {
- if (wrapAround)
- {
- System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
- System.arraycopy(buffer, 0, newbuffer,
- bufsize - tokenBegin, bufpos);
- buffer = newbuffer;
-
- System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
- System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
- bufline = newbufline;
-
- System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize -
tokenBegin);
- System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
- bufcolumn = newbufcolumn;
-
- bufpos += (bufsize - tokenBegin);
- }
- else
- {
- System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
- buffer = newbuffer;
-
- System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
- bufline = newbufline;
-
- System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize -
tokenBegin);
- bufcolumn = newbufcolumn;
-
- bufpos -= tokenBegin;
- }
- }
- catch (Throwable t)
- {
- throw new Error(t.getMessage());
- }
-
- available = (bufsize += 2048);
- tokenBegin = 0;
- }
-
- private final void FillBuff() throws java.io.IOException
- {
- int i;
- if (maxNextCharInd == 4096)
- maxNextCharInd = nextCharInd = 0;
-
- try {
- if ((i = inputStream.read(nextCharBuf, maxNextCharInd,
- 4096 - maxNextCharInd)) == -1)
- {
- inputStream.close();
- throw new java.io.IOException();
- }
- else
- maxNextCharInd += i;
- return;
- }
- catch(java.io.IOException e) {
- if (bufpos != 0)
- {
- --bufpos;
- backup(0);
- }
- else
- {
- bufline[bufpos] = line;
- bufcolumn[bufpos] = column;
- }
- throw e;
- }
- }
-
- private final byte ReadByte() throws java.io.IOException
- {
- if (++nextCharInd >= maxNextCharInd)
- FillBuff();
-
- return nextCharBuf[nextCharInd];
- }
-
- public final char BeginToken() throws java.io.IOException
- {
- if (inBuf > 0)
- {
- --inBuf;
- return buffer[tokenBegin = (bufpos == bufsize - 1) ? (bufpos = 0)
- : ++bufpos];
- }
-
- tokenBegin = 0;
- bufpos = -1;
-
- return readChar();
- }
-
- private final void AdjustBuffSize()
- {
- if (available == bufsize)
- {
- if (tokenBegin > 2048)
- {
- bufpos = 0;
- available = tokenBegin;
- }
- else
- ExpandBuff(false);
- }
- else if (available > tokenBegin)
- available = bufsize;
- else if ((tokenBegin - available) < 2048)
- ExpandBuff(true);
- else
- available = tokenBegin;
- }
-
- private final void UpdateLineColumn(char c)
- {
- column++;
-
- if (prevCharIsLF)
- {
- prevCharIsLF = false;
- line += (column = 1);
- }
- else if (prevCharIsCR)
- {
- prevCharIsCR = false;
- if (c == '\n')
- {
- prevCharIsLF = true;
- }
- else
- line += (column = 1);
- }
-
- switch (c)
- {
- case '\r' :
- prevCharIsCR = true;
- break;
- case '\n' :
- prevCharIsLF = true;
- break;
- case '\t' :
- column--;
- column += (8 - (column & 07));
- break;
- default :
- break;
- }
-
- bufline[bufpos] = line;
- bufcolumn[bufpos] = column;
- }
-
- public final char readChar() throws java.io.IOException
- {
- if (inBuf > 0)
- {
- --inBuf;
- return buffer[(bufpos == bufsize - 1) ? (bufpos = 0) : ++bufpos];
- }
-
- char c;
-
- if (++bufpos == available)
- AdjustBuffSize();
-
- if (((buffer[bufpos] = c = (char)((char)0xff & ReadByte())) == '\\'))
- {
- UpdateLineColumn(c);
-
- int backSlashCnt = 1;
-
- for (;;) // Read all the backslashes
- {
- if (++bufpos == available)
- AdjustBuffSize();
-
- try
- {
- if ((buffer[bufpos] = c = (char)((char)0xff & ReadByte())) !=
'\\')
- {
- UpdateLineColumn(c);
- // found a non-backslash char.
- if ((c == 'u') && ((backSlashCnt & 1) == 1))
- {
- if (--bufpos < 0)
- bufpos = bufsize - 1;
-
- break;
- }
-
- backup(backSlashCnt);
- return '\\';
- }
- }
- catch(java.io.IOException e)
- {
- if (backSlashCnt > 1)
- backup(backSlashCnt);
-
- return '\\';
- }
-
- UpdateLineColumn(c);
- backSlashCnt++;
- }
-
- // Here, we have seen an odd number of backslash's followed by a 'u'
- try
- {
- while ((c = (char)((char)0xff & ReadByte())) == 'u')
- ++column;
-
- buffer[bufpos] = c = (char)(hexval(c) << 12 |
- hexval((char)((char)0xff & ReadByte()))
<< 8 |
- hexval((char)((char)0xff & ReadByte()))
<< 4 |
- hexval((char)((char)0xff & ReadByte())));
-
- column += 4;
- }
- catch(java.io.IOException e)
- {
- throw new Error("Invalid escape character at line " + line +
- " column " + column + ".");
- }
-
- if (backSlashCnt == 1)
- return c;
- else
- {
- backup(backSlashCnt - 1);
- return '\\';
- }
- }
- else
- {
- UpdateLineColumn(c);
- return (c);
- }
- }
-
- /**
- * @deprecated
- * @see #getEndColumn
- */
-
- public final int getColumn() {
- return bufcolumn[bufpos];
- }
-
- /**
- * @deprecated
- * @see #getEndLine
- */
-
- public final int getLine() {
- return bufline[bufpos];
- }
-
- public final int getEndColumn() {
- return bufcolumn[bufpos];
- }
-
- public final int getEndLine() {
- return bufline[bufpos];
- }
-
- public final int getBeginColumn() {
- return bufcolumn[tokenBegin];
- }
-
- public final int getBeginLine() {
- return bufline[tokenBegin];
- }
-
- public final void backup(int amount) {
-
- inBuf += amount;
- if ((bufpos -= amount) < 0)
- bufpos += bufsize;
- }
-
- public ASCII_UCodeESC_CharStream(java.io.InputStream dstream,
- int startline, int startcolumn, int buffersize)
- {
- inputStream = dstream;
- line = startline;
- column = startcolumn - 1;
-
- available = bufsize = buffersize;
- buffer = new char[buffersize];
- bufline = new int[buffersize];
- bufcolumn = new int[buffersize];
- nextCharBuf = new byte[4096];
- }
-
- public ASCII_UCodeESC_CharStream(java.io.InputStream dstream,
- int startline, int startcolumn)
- {
- this(dstream, startline, startcolumn, 4096);
- }
- public void ReInit(java.io.InputStream dstream,
- int startline, int startcolumn, int buffersize)
- {
- inputStream = dstream;
- line = startline;
- column = startcolumn - 1;
-
- if (buffer == null || buffersize != buffer.length)
- {
- available = bufsize = buffersize;
- buffer = new char[buffersize];
- bufline = new int[buffersize];
- bufcolumn = new int[buffersize];
- nextCharBuf = new byte[4096];
- }
- prevCharIsLF = prevCharIsCR = false;
- tokenBegin = inBuf = maxNextCharInd = 0;
- nextCharInd = bufpos = -1;
- }
-
- public void ReInit(java.io.InputStream dstream,
- int startline, int startcolumn)
- {
- ReInit(dstream, startline, startcolumn, 4096);
- }
-
- public final String GetImage()
- {
- if (bufpos >= tokenBegin)
- return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
- else
- return new String(buffer, tokenBegin, bufsize - tokenBegin) +
- new String(buffer, 0, bufpos + 1);
- }
-
- public final char[] GetSuffix(int len)
- {
- char[] ret = new char[len];
-
- if ((bufpos + 1) >= len)
- System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
- else
- {
- System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
- len - bufpos - 1);
- System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
- }
-
- return ret;
- }
-
- public void Done()
- {
- nextCharBuf = null;
- buffer = null;
- bufline = null;
- bufcolumn = null;
- }
-
- /**
- * Method to adjust line and column numbers for the start of a token.<BR>
- */
- public void adjustBeginLineColumn(int newLine, int newCol)
- {
- int start = tokenBegin;
- int len;
-
- if (bufpos >= tokenBegin)
- {
- len = bufpos - tokenBegin + inBuf + 1;
- }
- else
- {
- len = bufsize - tokenBegin + bufpos + 1 + inBuf;
- }
-
- int i = 0, j = 0, k = 0;
- int nextColDiff = 0, columnDiff = 0;
-
- while (i < len &&
- bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
- {
- bufline[j] = newLine;
- nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
- bufcolumn[j] = newCol + columnDiff;
- columnDiff = nextColDiff;
- i++;
- }
-
- if (i < len)
- {
- bufline[j] = newLine++;
- bufcolumn[j] = newCol + columnDiff;
-
- while (i++ < len)
- {
- if (bufline[j = start % bufsize] != bufline[++start % bufsize])
- bufline[j] = newLine++;
- else
- bufline[j] = newLine;
- }
- }
-
- line = bufline[j];
- column = bufcolumn[j];
- }
-
-}
+/* Generated By:JavaCC: Do not edit this line. ASCII_UCodeESC_CharStream.java Version
0.7pre6 */
+package jde.debugger.expr;
+
+/**
+ * An implementation of interface CharStream, where the stream is assumed to
+ * contain only ASCII characters (with java-like unicode escape processing).
+ */
+
+public final class ASCII_UCodeESC_CharStream
+{
+ public static final boolean staticFlag = false;
+ static final int hexval(char c) throws java.io.IOException {
+ switch(c)
+ {
+ case '0' :
+ return 0;
+ case '1' :
+ return 1;
+ case '2' :
+ return 2;
+ case '3' :
+ return 3;
+ case '4' :
+ return 4;
+ case '5' :
+ return 5;
+ case '6' :
+ return 6;
+ case '7' :
+ return 7;
+ case '8' :
+ return 8;
+ case '9' :
+ return 9;
+
+ case 'a' :
+ case 'A' :
+ return 10;
+ case 'b' :
+ case 'B' :
+ return 11;
+ case 'c' :
+ case 'C' :
+ return 12;
+ case 'd' :
+ case 'D' :
+ return 13;
+ case 'e' :
+ case 'E' :
+ return 14;
+ case 'f' :
+ case 'F' :
+ return 15;
+ }
+
+ throw new java.io.IOException(); // Should never come here
+ }
+
+ public int bufpos = -1;
+ int bufsize;
+ int available;
+ int tokenBegin;
+ private int bufline[];
+ private int bufcolumn[];
+
+ private int column = 0;
+ private int line = 1;
+
+ private java.io.InputStream inputStream;
+
+ private boolean prevCharIsCR = false;
+ private boolean prevCharIsLF = false;
+
+ private byte[] nextCharBuf;
+ private char[] buffer;
+ private int maxNextCharInd = 0;
+ private int nextCharInd = -1;
+ private int inBuf = 0;
+
+ private final void ExpandBuff(boolean wrapAround)
+ {
+ char[] newbuffer = new char[bufsize + 2048];
+ int newbufline[] = new int[bufsize + 2048];
+ int newbufcolumn[] = new int[bufsize + 2048];
+
+ try
+ {
+ if (wrapAround)
+ {
+ System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+ System.arraycopy(buffer, 0, newbuffer,
+ bufsize - tokenBegin, bufpos);
+ buffer = newbuffer;
+
+ System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+ System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
+ bufline = newbufline;
+
+ System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize -
tokenBegin);
+ System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
+ bufcolumn = newbufcolumn;
+
+ bufpos += (bufsize - tokenBegin);
+ }
+ else
+ {
+ System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+ buffer = newbuffer;
+
+ System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+ bufline = newbufline;
+
+ System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize -
tokenBegin);
+ bufcolumn = newbufcolumn;
+
+ bufpos -= tokenBegin;
+ }
+ }
+ catch (Throwable t)
+ {
+ throw new Error(t.getMessage());
+ }
+
+ available = (bufsize += 2048);
+ tokenBegin = 0;
+ }
+
+ private final void FillBuff() throws java.io.IOException
+ {
+ int i;
+ if (maxNextCharInd == 4096)
+ maxNextCharInd = nextCharInd = 0;
+
+ try {
+ if ((i = inputStream.read(nextCharBuf, maxNextCharInd,
+ 4096 - maxNextCharInd)) == -1)
+ {
+ inputStream.close();
+ throw new java.io.IOException();
+ }
+ else
+ maxNextCharInd += i;
+ return;
+ }
+ catch(java.io.IOException e) {
+ if (bufpos != 0)
+ {
+ --bufpos;
+ backup(0);
+ }
+ else
+ {
+ bufline[bufpos] = line;
+ bufcolumn[bufpos] = column;
+ }
+ throw e;
+ }
+ }
+
+ private final byte ReadByte() throws java.io.IOException
+ {
+ if (++nextCharInd >= maxNextCharInd)
+ FillBuff();
+
+ return nextCharBuf[nextCharInd];
+ }
+
+ public final char BeginToken() throws java.io.IOException
+ {
+ if (inBuf > 0)
+ {
+ --inBuf;
+ return buffer[tokenBegin = (bufpos == bufsize - 1) ? (bufpos = 0)
+ : ++bufpos];
+ }
+
+ tokenBegin = 0;
+ bufpos = -1;
+
+ return readChar();
+ }
+
+ private final void AdjustBuffSize()
+ {
+ if (available == bufsize)
+ {
+ if (tokenBegin > 2048)
+ {
+ bufpos = 0;
+ available = tokenBegin;
+ }
+ else
+ ExpandBuff(false);
+ }
+ else if (available > tokenBegin)
+ available = bufsize;
+ else if ((tokenBegin - available) < 2048)
+ ExpandBuff(true);
+ else
+ available = tokenBegin;
+ }
+
+ private final void UpdateLineColumn(char c)
+ {
+ column++;
+
+ if (prevCharIsLF)
+ {
+ prevCharIsLF = false;
+ line += (column = 1);
+ }
+ else if (prevCharIsCR)
+ {
+ prevCharIsCR = false;
+ if (c == '\n')
+ {
+ prevCharIsLF = true;
+ }
+ else
+ line += (column = 1);
+ }
+
+ switch (c)
+ {
+ case '\r' :
+ prevCharIsCR = true;
+ break;
+ case '\n' :
+ prevCharIsLF = true;
+ break;
+ case '\t' :
+ column--;
+ column += (8 - (column & 07));
+ break;
+ default :
+ break;
+ }
+
+ bufline[bufpos] = line;
+ bufcolumn[bufpos] = column;
+ }
+
+ public final char readChar() throws java.io.IOException
+ {
+ if (inBuf > 0)
+ {
+ --inBuf;
+ return buffer[(bufpos == bufsize - 1) ? (bufpos = 0) : ++bufpos];
+ }
+
+ char c;
+
+ if (++bufpos == available)
+ AdjustBuffSize();
+
+ if (((buffer[bufpos] = c = (char)((char)0xff & ReadByte())) == '\\'))
+ {
+ UpdateLineColumn(c);
+
+ int backSlashCnt = 1;
+
+ for (;;) // Read all the backslashes
+ {
+ if (++bufpos == available)
+ AdjustBuffSize();
+
+ try
+ {
+ if ((buffer[bufpos] = c = (char)((char)0xff & ReadByte())) !=
'\\')
+ {
+ UpdateLineColumn(c);
+ // found a non-backslash char.
+ if ((c == 'u') && ((backSlashCnt & 1) == 1))
+ {
+ if (--bufpos < 0)
+ bufpos = bufsize - 1;
+
+ break;
+ }
+
+ backup(backSlashCnt);
+ return '\\';
+ }
+ }
+ catch(java.io.IOException e)
+ {
+ if (backSlashCnt > 1)
+ backup(backSlashCnt);
+
+ return '\\';
+ }
+
+ UpdateLineColumn(c);
+ backSlashCnt++;
+ }
+
+ // Here, we have seen an odd number of backslash's followed by a
'u'
+ try
+ {
+ while ((c = (char)((char)0xff & ReadByte())) == 'u')
+ ++column;
+
+ buffer[bufpos] = c = (char)(hexval(c) << 12 |
+ hexval((char)((char)0xff & ReadByte()))
<< 8 |
+ hexval((char)((char)0xff & ReadByte()))
<< 4 |
+ hexval((char)((char)0xff & ReadByte())));
+
+ column += 4;
+ }
+ catch(java.io.IOException e)
+ {
+ throw new Error("Invalid escape character at line " + line +
+ " column " + column +
".");
+ }
+
+ if (backSlashCnt == 1)
+ return c;
+ else
+ {
+ backup(backSlashCnt - 1);
+ return '\\';
+ }
+ }
+ else
+ {
+ UpdateLineColumn(c);
+ return (c);
+ }
+ }
+
+ /**
+ * @deprecated
+ * @see #getEndColumn
+ */
+
+ public final int getColumn() {
+ return bufcolumn[bufpos];
+ }
+
+ /**
+ * @deprecated
+ * @see #getEndLine
+ */
+
+ public final int getLine() {
+ return bufline[bufpos];
+ }
+
+ public final int getEndColumn() {
+ return bufcolumn[bufpos];
+ }
+
+ public final int getEndLine() {
+ return bufline[bufpos];
+ }
+
+ public final int getBeginColumn() {
+ return bufcolumn[tokenBegin];
+ }
+
+ public final int getBeginLine() {
+ return bufline[tokenBegin];
+ }
+
+ public final void backup(int amount) {
+
+ inBuf += amount;
+ if ((bufpos -= amount) < 0)
+ bufpos += bufsize;
+ }
+
+ public ASCII_UCodeESC_CharStream(java.io.InputStream dstream,
+ int startline, int startcolumn, int buffersize)
+ {
+ inputStream = dstream;
+ line = startline;
+ column = startcolumn - 1;
+
+ available = bufsize = buffersize;
+ buffer = new char[buffersize];
+ bufline = new int[buffersize];
+ bufcolumn = new int[buffersize];
+ nextCharBuf = new byte[4096];
+ }
+
+ public ASCII_UCodeESC_CharStream(java.io.InputStream dstream,
+ int startline, int startcolumn)
+ {
+ this(dstream, startline, startcolumn, 4096);
+ }
+ public void ReInit(java.io.InputStream dstream,
+ int startline, int startcolumn, int buffersize)
+ {
+ inputStream = dstream;
+ line = startline;
+ column = startcolumn - 1;
+
+ if (buffer == null || buffersize != buffer.length)
+ {
+ available = bufsize = buffersize;
+ buffer = new char[buffersize];
+ bufline = new int[buffersize];
+ bufcolumn = new int[buffersize];
+ nextCharBuf = new byte[4096];
+ }
+ prevCharIsLF = prevCharIsCR = false;
+ tokenBegin = inBuf = maxNextCharInd = 0;
+ nextCharInd = bufpos = -1;
+ }
+
+ public void ReInit(java.io.InputStream dstream,
+ int startline, int startcolumn)
+ {
+ ReInit(dstream, startline, startcolumn, 4096);
+ }
+
+ public final String GetImage()
+ {
+ if (bufpos >= tokenBegin)
+ return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
+ else
+ return new String(buffer, tokenBegin, bufsize - tokenBegin) +
+ new String(buffer, 0, bufpos + 1);
+ }
+
+ public final char[] GetSuffix(int len)
+ {
+ char[] ret = new char[len];
+
+ if ((bufpos + 1) >= len)
+ System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
+ else
+ {
+ System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
+ len - bufpos - 1);
+ System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
+ }
+
+ return ret;
+ }
+
+ public void Done()
+ {
+ nextCharBuf = null;
+ buffer = null;
+ bufline = null;
+ bufcolumn = null;
+ }
+
+ /**
+ * Method to adjust line and column numbers for the start of a token.<BR>
+ */
+ public void adjustBeginLineColumn(int newLine, int newCol)
+ {
+ int start = tokenBegin;
+ int len;
+
+ if (bufpos >= tokenBegin)
+ {
+ len = bufpos - tokenBegin + inBuf + 1;
+ }
+ else
+ {
+ len = bufsize - tokenBegin + bufpos + 1 + inBuf;
+ }
+
+ int i = 0, j = 0, k = 0;
+ int nextColDiff = 0, columnDiff = 0;
+
+ while (i < len &&
+ bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
+ {
+ bufline[j] = newLine;
+ nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
+ bufcolumn[j] = newCol + columnDiff;
+ columnDiff = nextColDiff;
+ i++;
+ }
+
+ if (i < len)
+ {
+ bufline[j] = newLine++;
+ bufcolumn[j] = newCol + columnDiff;
+
+ while (i++ < len)
+ {
+ if (bufline[j = start % bufsize] != bufline[++start % bufsize])
+ bufline[j] = newLine++;
+ else
+ bufline[j] = newLine;
+ }
+ }
+
+ line = bufline[j];
+ column = bufcolumn[j];
+ }
+
+}
Index: xemacs-packages/jde/java/src/jde/debugger/expr/Expr.jj
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/expr/Expr.jj,v
retrieving revision 1.1
diff -u -r1.1 Expr.jj
--- xemacs-packages/jde/java/src/jde/debugger/expr/Expr.jj 2000/08/13 13:36:57 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/expr/Expr.jj 2001/08/15 05:27:49
@@ -1,722 +1,722 @@
-/*
- * @(#)Expr.jj 1.2 98/07/09
- *
- * Copyright 1995-1998 by Sun Microsystems, Inc.,
- * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
- * All rights reserved.
- *
- * This software is the confidential and proprietary information
- * of Sun Microsystems, Inc. ("Confidential Information"). You
- * shall not disclose such Confidential Information and shall use
- * it only in accordance with the terms of the license agreement
- * you entered into with Sun.
- */
-
-/**
- * Modified from java1.0.2.jj: a Java grammar and actions that
- * implement a front-end.
- *
- * Copyright (C) 1996, 1997 Sun Microsystems Inc.
- *
- * Author: Sriram Sankar
- * Date: 6/11/96
- */
-
-/**
- * Modified to parse and evaluate Java expressions use the Java
- * Debug Interface.
- *
- * Author: Robert Field
- */
-
-options {
- JAVA_UNICODE_ESCAPE = true;
- STATIC = false;
-}
-
-PARSER_BEGIN(ExpressionParser)
-
-package jde.debugger.expr;
-
-import com.sun.jdi.*;
-import java.util.Stack;
-import java.util.List;
-import java.util.ArrayList;
-
-public class ExpressionParser {
-
- Stack stack = new Stack();
- VirtualMachine vm = null;
- GetFrame frameGetter = null;
-
- LValue peek() {
- return (LValue)stack.peek();
- }
-
- LValue pop() {
- return (LValue)stack.pop();
- }
-
- void push(LValue lval) {
- stack.push(lval);
- }
-
- public interface GetFrame {
- StackFrame get() throws IncompatibleThreadStateException;
- }
-
- public static Value evaluate(String expr, VirtualMachine vm,
- GetFrame frameGetter) throws ParseException,
- InvocationException,
- InvalidTypeException,
- ClassNotLoadedException,
- IncompatibleThreadStateException {
- // TODO StringBufferInputStream is deprecated.
- java.io.InputStream in = new java.io.StringBufferInputStream(expr);
- ExpressionParser parser = new ExpressionParser(in);
- parser.vm = vm;
- parser.frameGetter = frameGetter;
- Value value = null;
- parser.Expression();
- return parser.pop().getValue();
- }
-
- public static void main(String args[]) {
- ExpressionParser parser;
- System.out.print("Java Expression Parser: ");
- if (args.length == 0) {
- System.out.println("Reading from standard input . . .");
- parser = new ExpressionParser(System.in);
- } else if (args.length == 1) {
- System.out.println("Reading from file " + args[0] + " . . .");
- try {
- parser = new ExpressionParser(new java.io.FileInputStream(args[0]));
- } catch (java.io.FileNotFoundException e) {
- System.out.println("Java Parser Version 1.0.2: File " +
- args[0] + " not found.");
- return;
- }
- } else {
- System.out.println("Usage is one of:");
- System.out.println(" java ExpressionParser < inputfile");
- System.out.println("OR");
- System.out.println(" java ExpressionParser inputfile");
- return;
- }
- try {
- parser.Expression();
- System.out.print("Java Expression Parser: ");
- System.out.println("Java program parsed successfully.");
- } catch (ParseException e) {
- System.out.print("Java Expression Parser: ");
- System.out.println("Encountered errors during parse.");
- }
- }
-
-}
-
-PARSER_END(ExpressionParser)
-
-
-SKIP : /* WHITE SPACE */
-{
- " "
-| "\t"
-| "\n"
-| "\r"
-| "\f"
-}
-
-SPECIAL_TOKEN : /* COMMENTS */
-{
- <SINGLE_LINE_COMMENT: "//" (~["\n","\r"])*
("\n"|"\r"|"\r\n")>
-| <FORMAL_COMMENT: "/**" (~["*"])* "*" ("*" |
(~["*","/"] (~["*"])* "*"))* "/">
-| <MULTI_LINE_COMMENT: "/*" (~["*"])* "*" ("*"
| (~["*","/"] (~["*"])* "*"))* "/">
-}
-
-TOKEN : /* RESERVED WORDS AND LITERALS */
-{
- < ABSTRACT: "abstract" >
-| < BOOLEAN: "boolean" >
-| < BREAK: "break" >
-| < BYTE: "byte" >
-| < CASE: "case" >
-| < CATCH: "catch" >
-| < CHAR: "char" >
-| < CLASS: "class" >
-| < CONST: "const" >
-| < CONTINUE: "continue" >
-| < _DEFAULT: "default" >
-| < DO: "do" >
-| < DOUBLE: "double" >
-| < ELSE: "else" >
-| < EXTENDS: "extends" >
-| < FALSE: "false" >
-| < FINAL: "final" >
-| < FINALLY: "finally" >
-| < FLOAT: "float" >
-| < FOR: "for" >
-| < GOTO: "goto" >
-| < IF: "if" >
-| < IMPLEMENTS: "implements" >
-| < IMPORT: "import" >
-| < INSTANCEOF: "instanceof" >
-| < INT: "int" >
-| < INTERFACE: "interface" >
-| < LONG: "long" >
-| < NATIVE: "native" >
-| < NEW: "new" >
-| < NULL: "null" >
-| < PACKAGE: "package">
-| < PRIVATE: "private" >
-| < PROTECTED: "protected" >
-| < PUBLIC: "public" >
-| < RETURN: "return" >
-| < SHORT: "short" >
-| < STATIC: "static" >
-| < SUPER: "super" >
-| < SWITCH: "switch" >
-| < SYNCHRONIZED: "synchronized" >
-| < THIS: "this" >
-| < THROW: "throw" >
-| < THROWS: "throws" >
-| < TRANSIENT: "transient" >
-| < TRUE: "true" >
-| < TRY: "try" >
-| < VOID: "void" >
-| < VOLATILE: "volatile" >
-| < WHILE: "while" >
-}
-
-TOKEN : /* LITERALS */
-{
- <
- INTEGER_LITERAL:
- <DECIMAL_LITERAL> (["l","L"])?
- | <HEX_LITERAL> (["l","L"])?
- | <OCTAL_LITERAL> (["l","L"])?
- >
-|
- < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])*
>
-|
- < #HEX_LITERAL: "0" ["x","X"]
(["0"-"9","a"-"f","A"-"F"])+
>
-|
- < #OCTAL_LITERAL: "0" (["0"-"7"])* >
-|
- < FLOATING_POINT_LITERAL:
- (["0"-"9"])+ "." (["0"-"9"])*
(<EXPONENT>)? (["f","F","d","D"])?
- | "." (["0"-"9"])+ (<EXPONENT>)?
(["f","F","d","D"])?
- | (["0"-"9"])+ <EXPONENT>
(["f","F","d","D"])?
- | (["0"-"9"])+ (<EXPONENT>)?
["f","F","d","D"]
- >
-|
- < #EXPONENT: ["e","E"] (["+","-"])?
(["0"-"9"])+ >
-|
- < CHARACTER_LITERAL:
- "'"
- ( (~["'","\\","\n","\r"])
- | ("\\"
- (
["n","t","b","r","f","\\","'","\""]
- | ["0"-"7"] ( ["0"-"7"] )?
- | ["0"-"3"] ["0"-"7"]
["0"-"7"]
- )
- )
- )
- "'"
- >
-|
- < STRING_LITERAL:
- "\""
- ( (~["\"","\\","\n","\r"])
- | ("\\"
- (
["n","t","b","r","f","\\","'","\""]
- | ["0"-"7"] ( ["0"-"7"] )?
- | ["0"-"3"] ["0"-"7"]
["0"-"7"]
- )
- )
- )*
- "\""
- >
-}
-
-TOKEN : /* IDENTIFIERS */
-{
- < IDENTIFIER: <LETTER> (<LETTER>|<DIGIT>)* >
-|
- < #LETTER:
- [
- "\u0024",
- "\u0041"-"\u005a",
- "\u005f",
- "\u0061"-"\u007a",
- "\u00c0"-"\u00d6",
- "\u00d8"-"\u00f6",
- "\u00f8"-"\u00ff",
- "\u0100"-"\u1fff",
- "\u3040"-"\u318f",
- "\u3300"-"\u337f",
- "\u3400"-"\u3d2d",
- "\u4e00"-"\u9fff",
- "\uf900"-"\ufaff"
- ]
- >
-|
- < #DIGIT:
- [
- "\u0030"-"\u0039",
- "\u0660"-"\u0669",
- "\u06f0"-"\u06f9",
- "\u0966"-"\u096f",
- "\u09e6"-"\u09ef",
- "\u0a66"-"\u0a6f",
- "\u0ae6"-"\u0aef",
- "\u0b66"-"\u0b6f",
- "\u0be7"-"\u0bef",
- "\u0c66"-"\u0c6f",
- "\u0ce6"-"\u0cef",
- "\u0d66"-"\u0d6f",
- "\u0e50"-"\u0e59",
- "\u0ed0"-"\u0ed9",
- "\u1040"-"\u1049"
- ]
- >
-}
-
-TOKEN : /* SEPARATORS */
-{
- < LPAREN: "(" >
-| < RPAREN: ")" >
-| < LBRACE: "{" >
-| < RBRACE: "}" >
-| < LBRACKET: "[" >
-| < RBRACKET: "]" >
-| < SEMICOLON: ";" >
-| < COMMA: "," >
-| < DOT: "." >
-}
-
-TOKEN : /* OPERATORS */
-{
- < ASSIGN: "=" >
-| < GT: ">" >
-| < LT: "<" >
-| < BANG: "!" >
-| < TILDE: "~" >
-| < HOOK: "?" >
-| < COLON: ":" >
-| < EQ: "==" >
-| < LE: "<=" >
-| < GE: ">=" >
-| < NE: "!=" >
-| < SC_OR: "||" >
-| < SC_AND: "&&" >
-| < INCR: "++" >
-| < DECR: "--" >
-| < PLUS: "+" >
-| < MINUS: "-" >
-| < STAR: "*" >
-| < SLASH: "/" >
-| < BIT_AND: "&" >
-| < BIT_OR: "|" >
-| < XOR: "^" >
-| < REM: "%" >
-| < LSHIFT: "<<" >
-| < RSIGNEDSHIFT: ">>" >
-| < RUNSIGNEDSHIFT: ">>>" >
-| < PLUSASSIGN: "+=" >
-| < MINUSASSIGN: "-=" >
-| < STARASSIGN: "*=" >
-| < SLASHASSIGN: "/=" >
-| < ANDASSIGN: "&=" >
-| < ORASSIGN: "|=" >
-| < XORASSIGN: "^=" >
-| < REMASSIGN: "%=" >
-| < LSHIFTASSIGN: "<<=" >
-| < RSIGNEDSHIFTASSIGN: ">>=" >
-| < RUNSIGNEDSHIFTASSIGN: ">>>=" >
-}
-
-
-/*****************************************
- * THE JAVA LANGUAGE GRAMMAR STARTS HERE *
- *****************************************/
-
-/*
- * Type, name and expression syntax follows.
- */
-
-void Type() :
-{}
-{
- ( PrimitiveType() | Name() ) ( "[" "]" )*
-}
-
-void PrimitiveType() :
-{}
-{
- "boolean"
-|
- "char"
-|
- "byte"
-|
- "short"
-|
- "int"
-|
- "long"
-|
- "float"
-|
- "double"
-}
-
-
-String Name() :
-{StringBuffer sb = new StringBuffer();}
-{
- <IDENTIFIER> { sb.append(token); }
- ( LOOKAHEAD(2) "." <IDENTIFIER> { sb.append('.');
sb.append(token); }
- )*
- { return sb.toString(); }
-}
-
-void NameList() :
-{}
-{
- Name()
- ( "," Name()
- )*
-}
-
-
-/*
- * Expression syntax follows.
- */
-
-void Expression() :
-{}
-{
- LOOKAHEAD( PrimaryExpression() AssignmentOperator() )
- Assignment()
-|
- ConditionalExpression()
-}
-
-void Assignment() :
-{}
-{
- PrimaryExpression() AssignmentOperator() Expression()
- { LValue exprVal = pop(); pop().setValue(exprVal); push(exprVal);}
-}
-
-void AssignmentOperator() :
-{}
-{
- "=" | "*=" | "/=" | "%=" | "+=" |
"-=" | "<<=" | ">>=" | ">>>="
| "&=" | "^=" | "|="
-}
-
-void ConditionalExpression() :
-{}
-{
- ConditionalOrExpression()
- [ "?" Expression() ":" ConditionalExpression()
- { LValue falseBranch = pop(); LValue trueBranch = pop();
- Value cond = pop().interiorGetValue();
- if (cond instanceof BooleanValue) {
- push(((BooleanValue)cond).booleanValue()?
- trueBranch : falseBranch);
- } else {
- throw new ParseException("Condition must be boolean");
- }
- }
- ]
-}
-
-void ConditionalOrExpression() :
-{}
-{
- ConditionalAndExpression()
- ( "||" ConditionalAndExpression()
- { throw new ParseException("operation not yet
supported"); }
- )*
-}
-
-void ConditionalAndExpression() :
-{}
-{
- InclusiveOrExpression()
- ( "&&" InclusiveOrExpression()
- { throw new ParseException("operation not yet
supported"); }
- )*
-}
-
-void InclusiveOrExpression() :
-{}
-{
- ExclusiveOrExpression()
- ( "|" ExclusiveOrExpression()
- { throw new ParseException("operation not yet
supported"); }
- )*
-}
-
-void ExclusiveOrExpression() :
-{}
-{
- AndExpression()
- ( "^" AndExpression()
- { throw new ParseException("operation not yet
supported"); }
- )*
-}
-
-void AndExpression() :
-{}
-{
- EqualityExpression()
- ( "&" EqualityExpression()
- { throw new ParseException("operation not yet
supported"); }
- )*
-}
-
-void EqualityExpression() :
-{Token tok;}
-{
- InstanceOfExpression()
- ( ( tok = "==" | tok = "!=" ) InstanceOfExpression()
- { LValue left = pop();
- push( LValue.booleanOperation(vm, tok, pop(), left) ); }
- )*
-}
-
-void InstanceOfExpression() :
-{}
-{
- RelationalExpression()
- [ "instanceof" Type()
- { throw new ParseException("operation not yet
supported"); }
- ]
-}
-
-void RelationalExpression() :
-{Token tok;}
-{
- ShiftExpression()
- ( ( tok = "<" | tok = ">" | tok = "<=" |
tok = ">=" ) ShiftExpression()
- { LValue left = pop();
- push( LValue.booleanOperation(vm, tok, pop(), left) ); }
- )*
-}
-
-void ShiftExpression() :
-{}
-{
- AdditiveExpression()
- ( ( "<<" | ">>" | ">>>" )
AdditiveExpression()
- { throw new ParseException("operation not yet
supported"); }
- )*
-}
-
-void AdditiveExpression() :
-{Token tok;}
-{
- MultiplicativeExpression()
- ( ( tok = "+" | tok = "-" ) MultiplicativeExpression()
- { LValue left = pop();
- push( LValue.operation(vm, tok, pop(), left) ); }
- )*
-}
-
-void MultiplicativeExpression() :
-{Token tok;}
-{
- UnaryExpression()
- ( ( tok = "*" | tok = "/" | tok = "%" )
UnaryExpression()
- { LValue left = pop();
- push( LValue.operation(vm, tok, pop(), left) ); }
- )*
-}
-
-void UnaryExpression() :
-{}
-{
- ( "+" | "-" ) UnaryExpression()
- { throw new ParseException("operation not yet
supported"); }
-|
- PreIncrementExpression()
-|
- PreDecrementExpression()
-|
- UnaryExpressionNotPlusMinus()
-}
-
-void PreIncrementExpression() :
-{}
-{
- "++" PrimaryExpression()
- { throw new ParseException("operation not yet
supported"); }
-}
-
-void PreDecrementExpression() :
-{}
-{
- "--" PrimaryExpression()
- { throw new ParseException("operation not yet
supported"); }
-}
-
-void UnaryExpressionNotPlusMinus() :
-{}
-{
- ( "~" | "!" ) UnaryExpression()
- { throw new ParseException("operation not yet
supported"); }
-|
- LOOKAHEAD( CastLookahead() )
- CastExpression()
-|
- PostfixExpression()
-}
-
-// This production is to determine lookahead only. The LOOKAHEAD specifications
-// below are not used, but they are there just to indicate that we know about
-// this.
-void CastLookahead() :
-{}
-{
- LOOKAHEAD(2)
- "(" PrimitiveType()
-|
- LOOKAHEAD("(" Name() "[")
- "(" Name() "[" "]"
-|
- "(" Name() ")" ( "~" | "!" | "(" |
<IDENTIFIER> | "this" | "super" | "new" | Literal() )
-}
-
-void PostfixExpression() :
-{}
-{
- PrimaryExpression()
- [ "++" | "--"
- { throw new ParseException("operation not yet
supported"); }
- ]
-}
-
-void CastExpression() :
-{}
-{
- LOOKAHEAD(2)
- "(" PrimitiveType() ( "[" "]" )* ")"
UnaryExpression()
-|
- "(" Name() ( "[" "]" )* ")"
UnaryExpressionNotPlusMinus()
-}
-
-void PrimaryExpression() :
-{}
-{
- PrimaryPrefix() ( PrimarySuffix() )*
-}
-
-void PrimaryPrefix() :
-{String name;}
-{
- Literal()
-|
- name = Name()
- { push(LValue.makeName(vm, frameGetter, name)); }
-|
- "this"
- { push(LValue.makeThisObject(vm, frameGetter, token)); }
-|
- "super" "." <IDENTIFIER>
- { throw new ParseException("operation not yet
supported"); }
-|
- "(" Expression() ")"
-|
- AllocationExpression()
-}
-
-void PrimarySuffix() :
-{List argList;}
-{
- "[" Expression() "]"
- { LValue index = pop();
- push(pop().arrayElementLValue(index)); }
-|
- "." <IDENTIFIER>
- { push(pop().memberLValue(frameGetter, token.image)); }
-|
- argList = Arguments()
- { peek().invokeWith(argList); }
-}
-
-void Literal() :
-{}
-{
- <INTEGER_LITERAL>
- { push(LValue.makeInteger(vm, token)); }
-|
- <FLOATING_POINT_LITERAL>
- { push(LValue.makeFloat(vm, token)); }
-|
- <CHARACTER_LITERAL>
- { push(LValue.makeCharacter(vm, token)); }
-|
- <STRING_LITERAL>
- { push(LValue.makeString(vm, token)); }
-|
- BooleanLiteral()
- { push(LValue.makeBoolean(vm, token)); }
-|
- NullLiteral()
- { push(LValue.makeNull(vm, token)); }
-}
-
-void BooleanLiteral() :
-{}
-{
- "true"
-|
- "false"
-}
-
-void NullLiteral() :
-{}
-{
- "null"
-}
-
-List Arguments() :
-{List argList = new ArrayList();}
-{
- "(" [ ArgumentList(argList) ] ")"
- { return argList; }
-}
-
-void ArgumentList(List argList) :
-{}
-{
- Expression() {argList.add(pop().interiorGetValue());}
- ( "," Expression() {argList.add(pop().interiorGetValue());} )*
-}
-
-void AllocationExpression() :
-{List argList; String className;}
-{
- LOOKAHEAD(2)
- "new" PrimitiveType() ArrayDimensions()
-|
- "new" className = Name() ( argList = Arguments()
- { push(LValue.makeNewObject(vm, frameGetter, className,
argList)); }
- | ArrayDimensions()
- { throw new ParseException("operation not yet
supported"); }
- )
-}
-
-/*
- * The second LOOKAHEAD specification below is to parse to PrimarySuffix
- * if there is an expression between the "[...]".
- */
-void ArrayDimensions() :
-{}
-{
- ( LOOKAHEAD(2) "[" Expression() "]" )+ ( LOOKAHEAD(2) "["
"]" )*
-}
-
+/*
+ * @(#)Expr.jj 1.2 98/07/09
+ *
+ * Copyright 1995-1998 by Sun Microsystems, Inc.,
+ * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information
+ * of Sun Microsystems, Inc. ("Confidential Information"). You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Sun.
+ */
+
+/**
+ * Modified from java1.0.2.jj: a Java grammar and actions that
+ * implement a front-end.
+ *
+ * Copyright (C) 1996, 1997 Sun Microsystems Inc.
+ *
+ * Author: Sriram Sankar
+ * Date: 6/11/96
+ */
+
+/**
+ * Modified to parse and evaluate Java expressions use the Java
+ * Debug Interface.
+ *
+ * Author: Robert Field
+ */
+
+options {
+ JAVA_UNICODE_ESCAPE = true;
+ STATIC = false;
+}
+
+PARSER_BEGIN(ExpressionParser)
+
+package jde.debugger.expr;
+
+import com.sun.jdi.*;
+import java.util.Stack;
+import java.util.List;
+import java.util.ArrayList;
+
+public class ExpressionParser {
+
+ Stack stack = new Stack();
+ VirtualMachine vm = null;
+ GetFrame frameGetter = null;
+
+ LValue peek() {
+ return (LValue)stack.peek();
+ }
+
+ LValue pop() {
+ return (LValue)stack.pop();
+ }
+
+ void push(LValue lval) {
+ stack.push(lval);
+ }
+
+ public interface GetFrame {
+ StackFrame get() throws IncompatibleThreadStateException;
+ }
+
+ public static Value evaluate(String expr, VirtualMachine vm,
+ GetFrame frameGetter) throws ParseException,
+ InvocationException,
+ InvalidTypeException,
+ ClassNotLoadedException,
+ IncompatibleThreadStateException {
+ // TODO StringBufferInputStream is deprecated.
+ java.io.InputStream in = new java.io.StringBufferInputStream(expr);
+ ExpressionParser parser = new ExpressionParser(in);
+ parser.vm = vm;
+ parser.frameGetter = frameGetter;
+ Value value = null;
+ parser.Expression();
+ return parser.pop().getValue();
+ }
+
+ public static void main(String args[]) {
+ ExpressionParser parser;
+ System.out.print("Java Expression Parser: ");
+ if (args.length == 0) {
+ System.out.println("Reading from standard input . . .");
+ parser = new ExpressionParser(System.in);
+ } else if (args.length == 1) {
+ System.out.println("Reading from file " + args[0] + " . .
.");
+ try {
+ parser = new ExpressionParser(new java.io.FileInputStream(args[0]));
+ } catch (java.io.FileNotFoundException e) {
+ System.out.println("Java Parser Version 1.0.2: File " +
+ args[0] + " not found.");
+ return;
+ }
+ } else {
+ System.out.println("Usage is one of:");
+ System.out.println(" java ExpressionParser < inputfile");
+ System.out.println("OR");
+ System.out.println(" java ExpressionParser inputfile");
+ return;
+ }
+ try {
+ parser.Expression();
+ System.out.print("Java Expression Parser: ");
+ System.out.println("Java program parsed successfully.");
+ } catch (ParseException e) {
+ System.out.print("Java Expression Parser: ");
+ System.out.println("Encountered errors during parse.");
+ }
+ }
+
+}
+
+PARSER_END(ExpressionParser)
+
+
+SKIP : /* WHITE SPACE */
+{
+ " "
+| "\t"
+| "\n"
+| "\r"
+| "\f"
+}
+
+SPECIAL_TOKEN : /* COMMENTS */
+{
+ <SINGLE_LINE_COMMENT: "//" (~["\n","\r"])*
("\n"|"\r"|"\r\n")>
+| <FORMAL_COMMENT: "/**" (~["*"])* "*" ("*" |
(~["*","/"] (~["*"])* "*"))* "/">
+| <MULTI_LINE_COMMENT: "/*" (~["*"])* "*" ("*"
| (~["*","/"] (~["*"])* "*"))* "/">
+}
+
+TOKEN : /* RESERVED WORDS AND LITERALS */
+{
+ < ABSTRACT: "abstract" >
+| < BOOLEAN: "boolean" >
+| < BREAK: "break" >
+| < BYTE: "byte" >
+| < CASE: "case" >
+| < CATCH: "catch" >
+| < CHAR: "char" >
+| < CLASS: "class" >
+| < CONST: "const" >
+| < CONTINUE: "continue" >
+| < _DEFAULT: "default" >
+| < DO: "do" >
+| < DOUBLE: "double" >
+| < ELSE: "else" >
+| < EXTENDS: "extends" >
+| < FALSE: "false" >
+| < FINAL: "final" >
+| < FINALLY: "finally" >
+| < FLOAT: "float" >
+| < FOR: "for" >
+| < GOTO: "goto" >
+| < IF: "if" >
+| < IMPLEMENTS: "implements" >
+| < IMPORT: "import" >
+| < INSTANCEOF: "instanceof" >
+| < INT: "int" >
+| < INTERFACE: "interface" >
+| < LONG: "long" >
+| < NATIVE: "native" >
+| < NEW: "new" >
+| < NULL: "null" >
+| < PACKAGE: "package">
+| < PRIVATE: "private" >
+| < PROTECTED: "protected" >
+| < PUBLIC: "public" >
+| < RETURN: "return" >
+| < SHORT: "short" >
+| < STATIC: "static" >
+| < SUPER: "super" >
+| < SWITCH: "switch" >
+| < SYNCHRONIZED: "synchronized" >
+| < THIS: "this" >
+| < THROW: "throw" >
+| < THROWS: "throws" >
+| < TRANSIENT: "transient" >
+| < TRUE: "true" >
+| < TRY: "try" >
+| < VOID: "void" >
+| < VOLATILE: "volatile" >
+| < WHILE: "while" >
+}
+
+TOKEN : /* LITERALS */
+{
+ <
+ INTEGER_LITERAL:
+ <DECIMAL_LITERAL> (["l","L"])?
+ | <HEX_LITERAL> (["l","L"])?
+ | <OCTAL_LITERAL> (["l","L"])?
+ >
+|
+ < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])*
>
+|
+ < #HEX_LITERAL: "0" ["x","X"]
(["0"-"9","a"-"f","A"-"F"])+
>
+|
+ < #OCTAL_LITERAL: "0" (["0"-"7"])* >
+|
+ < FLOATING_POINT_LITERAL:
+ (["0"-"9"])+ "." (["0"-"9"])*
(<EXPONENT>)? (["f","F","d","D"])?
+ | "." (["0"-"9"])+ (<EXPONENT>)?
(["f","F","d","D"])?
+ | (["0"-"9"])+ <EXPONENT>
(["f","F","d","D"])?
+ | (["0"-"9"])+ (<EXPONENT>)?
["f","F","d","D"]
+ >
+|
+ < #EXPONENT: ["e","E"] (["+","-"])?
(["0"-"9"])+ >
+|
+ < CHARACTER_LITERAL:
+ "'"
+ ( (~["'","\\","\n","\r"])
+ | ("\\"
+ (
["n","t","b","r","f","\\","'","\""]
+ | ["0"-"7"] ( ["0"-"7"] )?
+ | ["0"-"3"] ["0"-"7"]
["0"-"7"]
+ )
+ )
+ )
+ "'"
+ >
+|
+ < STRING_LITERAL:
+ "\""
+ ( (~["\"","\\","\n","\r"])
+ | ("\\"
+ (
["n","t","b","r","f","\\","'","\""]
+ | ["0"-"7"] ( ["0"-"7"] )?
+ | ["0"-"3"] ["0"-"7"]
["0"-"7"]
+ )
+ )
+ )*
+ "\""
+ >
+}
+
+TOKEN : /* IDENTIFIERS */
+{
+ < IDENTIFIER: <LETTER> (<LETTER>|<DIGIT>)* >
+|
+ < #LETTER:
+ [
+ "\u0024",
+ "\u0041"-"\u005a",
+ "\u005f",
+ "\u0061"-"\u007a",
+ "\u00c0"-"\u00d6",
+ "\u00d8"-"\u00f6",
+ "\u00f8"-"\u00ff",
+ "\u0100"-"\u1fff",
+ "\u3040"-"\u318f",
+ "\u3300"-"\u337f",
+ "\u3400"-"\u3d2d",
+ "\u4e00"-"\u9fff",
+ "\uf900"-"\ufaff"
+ ]
+ >
+|
+ < #DIGIT:
+ [
+ "\u0030"-"\u0039",
+ "\u0660"-"\u0669",
+ "\u06f0"-"\u06f9",
+ "\u0966"-"\u096f",
+ "\u09e6"-"\u09ef",
+ "\u0a66"-"\u0a6f",
+ "\u0ae6"-"\u0aef",
+ "\u0b66"-"\u0b6f",
+ "\u0be7"-"\u0bef",
+ "\u0c66"-"\u0c6f",
+ "\u0ce6"-"\u0cef",
+ "\u0d66"-"\u0d6f",
+ "\u0e50"-"\u0e59",
+ "\u0ed0"-"\u0ed9",
+ "\u1040"-"\u1049"
+ ]
+ >
+}
+
+TOKEN : /* SEPARATORS */
+{
+ < LPAREN: "(" >
+| < RPAREN: ")" >
+| < LBRACE: "{" >
+| < RBRACE: "}" >
+| < LBRACKET: "[" >
+| < RBRACKET: "]" >
+| < SEMICOLON: ";" >
+| < COMMA: "," >
+| < DOT: "." >
+}
+
+TOKEN : /* OPERATORS */
+{
+ < ASSIGN: "=" >
+| < GT: ">" >
+| < LT: "<" >
+| < BANG: "!" >
+| < TILDE: "~" >
+| < HOOK: "?" >
+| < COLON: ":" >
+| < EQ: "==" >
+| < LE: "<=" >
+| < GE: ">=" >
+| < NE: "!=" >
+| < SC_OR: "||" >
+| < SC_AND: "&&" >
+| < INCR: "++" >
+| < DECR: "--" >
+| < PLUS: "+" >
+| < MINUS: "-" >
+| < STAR: "*" >
+| < SLASH: "/" >
+| < BIT_AND: "&" >
+| < BIT_OR: "|" >
+| < XOR: "^" >
+| < REM: "%" >
+| < LSHIFT: "<<" >
+| < RSIGNEDSHIFT: ">>" >
+| < RUNSIGNEDSHIFT: ">>>" >
+| < PLUSASSIGN: "+=" >
+| < MINUSASSIGN: "-=" >
+| < STARASSIGN: "*=" >
+| < SLASHASSIGN: "/=" >
+| < ANDASSIGN: "&=" >
+| < ORASSIGN: "|=" >
+| < XORASSIGN: "^=" >
+| < REMASSIGN: "%=" >
+| < LSHIFTASSIGN: "<<=" >
+| < RSIGNEDSHIFTASSIGN: ">>=" >
+| < RUNSIGNEDSHIFTASSIGN: ">>>=" >
+}
+
+
+/*****************************************
+ * THE JAVA LANGUAGE GRAMMAR STARTS HERE *
+ *****************************************/
+
+/*
+ * Type, name and expression syntax follows.
+ */
+
+void Type() :
+{}
+{
+ ( PrimitiveType() | Name() ) ( "[" "]" )*
+}
+
+void PrimitiveType() :
+{}
+{
+ "boolean"
+|
+ "char"
+|
+ "byte"
+|
+ "short"
+|
+ "int"
+|
+ "long"
+|
+ "float"
+|
+ "double"
+}
+
+
+String Name() :
+{StringBuffer sb = new StringBuffer();}
+{
+ <IDENTIFIER> { sb.append(token); }
+ ( LOOKAHEAD(2) "." <IDENTIFIER> { sb.append('.');
sb.append(token); }
+ )*
+ { return sb.toString(); }
+}
+
+void NameList() :
+{}
+{
+ Name()
+ ( "," Name()
+ )*
+}
+
+
+/*
+ * Expression syntax follows.
+ */
+
+void Expression() :
+{}
+{
+ LOOKAHEAD( PrimaryExpression() AssignmentOperator() )
+ Assignment()
+|
+ ConditionalExpression()
+}
+
+void Assignment() :
+{}
+{
+ PrimaryExpression() AssignmentOperator() Expression()
+ { LValue exprVal = pop(); pop().setValue(exprVal); push(exprVal);}
+}
+
+void AssignmentOperator() :
+{}
+{
+ "=" | "*=" | "/=" | "%=" | "+=" |
"-=" | "<<=" | ">>=" | ">>>="
| "&=" | "^=" | "|="
+}
+
+void ConditionalExpression() :
+{}
+{
+ ConditionalOrExpression()
+ [ "?" Expression() ":" ConditionalExpression()
+ { LValue falseBranch = pop(); LValue trueBranch = pop();
+ Value cond = pop().interiorGetValue();
+ if (cond instanceof BooleanValue) {
+ push(((BooleanValue)cond).booleanValue()?
+ trueBranch : falseBranch);
+ } else {
+ throw new ParseException("Condition must be
boolean");
+ }
+ }
+ ]
+}
+
+void ConditionalOrExpression() :
+{}
+{
+ ConditionalAndExpression()
+ ( "||" ConditionalAndExpression()
+ { throw new ParseException("operation not yet
supported"); }
+ )*
+}
+
+void ConditionalAndExpression() :
+{}
+{
+ InclusiveOrExpression()
+ ( "&&" InclusiveOrExpression()
+ { throw new ParseException("operation not yet
supported"); }
+ )*
+}
+
+void InclusiveOrExpression() :
+{}
+{
+ ExclusiveOrExpression()
+ ( "|" ExclusiveOrExpression()
+ { throw new ParseException("operation not yet
supported"); }
+ )*
+}
+
+void ExclusiveOrExpression() :
+{}
+{
+ AndExpression()
+ ( "^" AndExpression()
+ { throw new ParseException("operation not yet
supported"); }
+ )*
+}
+
+void AndExpression() :
+{}
+{
+ EqualityExpression()
+ ( "&" EqualityExpression()
+ { throw new ParseException("operation not yet
supported"); }
+ )*
+}
+
+void EqualityExpression() :
+{Token tok;}
+{
+ InstanceOfExpression()
+ ( ( tok = "==" | tok = "!=" ) InstanceOfExpression()
+ { LValue left = pop();
+ push( LValue.booleanOperation(vm, tok, pop(), left) ); }
+ )*
+}
+
+void InstanceOfExpression() :
+{}
+{
+ RelationalExpression()
+ [ "instanceof" Type()
+ { throw new ParseException("operation not yet
supported"); }
+ ]
+}
+
+void RelationalExpression() :
+{Token tok;}
+{
+ ShiftExpression()
+ ( ( tok = "<" | tok = ">" | tok = "<=" |
tok = ">=" ) ShiftExpression()
+ { LValue left = pop();
+ push( LValue.booleanOperation(vm, tok, pop(), left) ); }
+ )*
+}
+
+void ShiftExpression() :
+{}
+{
+ AdditiveExpression()
+ ( ( "<<" | ">>" | ">>>" )
AdditiveExpression()
+ { throw new ParseException("operation not yet
supported"); }
+ )*
+}
+
+void AdditiveExpression() :
+{Token tok;}
+{
+ MultiplicativeExpression()
+ ( ( tok = "+" | tok = "-" ) MultiplicativeExpression()
+ { LValue left = pop();
+ push( LValue.operation(vm, tok, pop(), left) ); }
+ )*
+}
+
+void MultiplicativeExpression() :
+{Token tok;}
+{
+ UnaryExpression()
+ ( ( tok = "*" | tok = "/" | tok = "%" )
UnaryExpression()
+ { LValue left = pop();
+ push( LValue.operation(vm, tok, pop(), left) ); }
+ )*
+}
+
+void UnaryExpression() :
+{}
+{
+ ( "+" | "-" ) UnaryExpression()
+ { throw new ParseException("operation not yet
supported"); }
+|
+ PreIncrementExpression()
+|
+ PreDecrementExpression()
+|
+ UnaryExpressionNotPlusMinus()
+}
+
+void PreIncrementExpression() :
+{}
+{
+ "++" PrimaryExpression()
+ { throw new ParseException("operation not yet
supported"); }
+}
+
+void PreDecrementExpression() :
+{}
+{
+ "--" PrimaryExpression()
+ { throw new ParseException("operation not yet
supported"); }
+}
+
+void UnaryExpressionNotPlusMinus() :
+{}
+{
+ ( "~" | "!" ) UnaryExpression()
+ { throw new ParseException("operation not yet
supported"); }
+|
+ LOOKAHEAD( CastLookahead() )
+ CastExpression()
+|
+ PostfixExpression()
+}
+
+// This production is to determine lookahead only. The LOOKAHEAD specifications
+// below are not used, but they are there just to indicate that we know about
+// this.
+void CastLookahead() :
+{}
+{
+ LOOKAHEAD(2)
+ "(" PrimitiveType()
+|
+ LOOKAHEAD("(" Name() "[")
+ "(" Name() "[" "]"
+|
+ "(" Name() ")" ( "~" | "!" | "(" |
<IDENTIFIER> | "this" | "super" | "new" | Literal()
)
+}
+
+void PostfixExpression() :
+{}
+{
+ PrimaryExpression()
+ [ "++" | "--"
+ { throw new ParseException("operation not yet
supported"); }
+ ]
+}
+
+void CastExpression() :
+{}
+{
+ LOOKAHEAD(2)
+ "(" PrimitiveType() ( "[" "]" )* ")"
UnaryExpression()
+|
+ "(" Name() ( "[" "]" )* ")"
UnaryExpressionNotPlusMinus()
+}
+
+void PrimaryExpression() :
+{}
+{
+ PrimaryPrefix() ( PrimarySuffix() )*
+}
+
+void PrimaryPrefix() :
+{String name;}
+{
+ Literal()
+|
+ name = Name()
+ { push(LValue.makeName(vm, frameGetter, name)); }
+|
+ "this"
+ { push(LValue.makeThisObject(vm, frameGetter, token)); }
+|
+ "super" "." <IDENTIFIER>
+ { throw new ParseException("operation not yet
supported"); }
+|
+ "(" Expression() ")"
+|
+ AllocationExpression()
+}
+
+void PrimarySuffix() :
+{List argList;}
+{
+ "[" Expression() "]"
+ { LValue index = pop();
+ push(pop().arrayElementLValue(index)); }
+|
+ "." <IDENTIFIER>
+ { push(pop().memberLValue(frameGetter, token.image)); }
+|
+ argList = Arguments()
+ { peek().invokeWith(argList); }
+}
+
+void Literal() :
+{}
+{
+ <INTEGER_LITERAL>
+ { push(LValue.makeInteger(vm, token)); }
+|
+ <FLOATING_POINT_LITERAL>
+ { push(LValue.makeFloat(vm, token)); }
+|
+ <CHARACTER_LITERAL>
+ { push(LValue.makeCharacter(vm, token)); }
+|
+ <STRING_LITERAL>
+ { push(LValue.makeString(vm, token)); }
+|
+ BooleanLiteral()
+ { push(LValue.makeBoolean(vm, token)); }
+|
+ NullLiteral()
+ { push(LValue.makeNull(vm, token)); }
+}
+
+void BooleanLiteral() :
+{}
+{
+ "true"
+|
+ "false"
+}
+
+void NullLiteral() :
+{}
+{
+ "null"
+}
+
+List Arguments() :
+{List argList = new ArrayList();}
+{
+ "(" [ ArgumentList(argList) ] ")"
+ { return argList; }
+}
+
+void ArgumentList(List argList) :
+{}
+{
+ Expression() {argList.add(pop().interiorGetValue());}
+ ( "," Expression() {argList.add(pop().interiorGetValue());} )*
+}
+
+void AllocationExpression() :
+{List argList; String className;}
+{
+ LOOKAHEAD(2)
+ "new" PrimitiveType() ArrayDimensions()
+|
+ "new" className = Name() ( argList = Arguments()
+ { push(LValue.makeNewObject(vm, frameGetter, className,
argList)); }
+ | ArrayDimensions()
+ { throw new ParseException("operation not yet
supported"); }
+ )
+}
+
+/*
+ * The second LOOKAHEAD specification below is to parse to PrimarySuffix
+ * if there is an expression between the "[...]".
+ */
+void ArrayDimensions() :
+{}
+{
+ ( LOOKAHEAD(2) "[" Expression() "]" )+ ( LOOKAHEAD(2) "["
"]" )*
+}
+
Index: xemacs-packages/jde/java/src/jde/debugger/expr/ExpressionParser.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/expr/ExpressionParser.java,v
retrieving revision 1.1
diff -u -r1.1 ExpressionParser.java
--- xemacs-packages/jde/java/src/jde/debugger/expr/ExpressionParser.java 2000/08/13
13:36:58 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/expr/ExpressionParser.java 2001/08/15
05:27:49
@@ -1,2722 +1,2722 @@
-/* Generated By:JavaCC: Do not edit this line. ExpressionParser.java */
-package jde.debugger.expr;
-
-import com.sun.jdi.*;
-import java.util.Stack;
-import java.util.List;
-import java.util.ArrayList;
-
-public class ExpressionParser implements ExpressionParserConstants {
-
- Stack stack = new Stack();
- VirtualMachine vm = null;
- GetFrame frameGetter = null;
-
- LValue peek() {
- return (LValue)stack.peek();
- }
-
- LValue pop() {
- return (LValue)stack.pop();
- }
-
- void push(LValue lval) {
- stack.push(lval);
- }
-
- public interface GetFrame {
- StackFrame get() throws IncompatibleThreadStateException;
- }
-
- public static Value evaluate(String expr, VirtualMachine vm,
- GetFrame frameGetter) throws ParseException,
- InvocationException,
- InvalidTypeException,
- ClassNotLoadedException,
- IncompatibleThreadStateException {
- java.io.InputStream in = new java.io.ByteArrayInputStream(expr.getBytes());
- ExpressionParser parser = new ExpressionParser(in);
- parser.vm = vm;
- parser.frameGetter = frameGetter;
- Value value = null;
- parser.Expression();
- return parser.pop().getValue();
- }
-
- public static void main(String args[]) {
- ExpressionParser parser;
- System.out.print("Java Expression Parser: ");
- if (args.length == 0) {
- System.out.println("Reading from standard input . . .");
- parser = new ExpressionParser(System.in);
- } else if (args.length == 1) {
- System.out.println("Reading from file " + args[0] + " . . .");
- try {
- parser = new ExpressionParser(new java.io.FileInputStream(args[0]));
- } catch (java.io.FileNotFoundException e) {
- System.out.println("Java Parser Version 1.0.2: File " +
- args[0] + " not found.");
- return;
- }
- } else {
- System.out.println("Usage is one of:");
- System.out.println(" java ExpressionParser < inputfile");
- System.out.println("OR");
- System.out.println(" java ExpressionParser inputfile");
- return;
- }
- try {
- parser.Expression();
- System.out.print("Java Expression Parser: ");
- System.out.println("Java program parsed successfully.");
- } catch (ParseException e) {
- System.out.print("Java Expression Parser: ");
- System.out.println("Encountered errors during parse.");
- }
- }
-
-/*****************************************
- * THE JAVA LANGUAGE GRAMMAR STARTS HERE *
- *****************************************/
-
-/*
- * Type, name and expression syntax follows.
- */
- final public void Type() throws ParseException {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case BOOLEAN:
- case BYTE:
- case CHAR:
- case DOUBLE:
- case FLOAT:
- case INT:
- case LONG:
- case SHORT:
- PrimitiveType();
- break;
- case IDENTIFIER:
- Name();
- break;
- default:
- jj_la1[0] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- label_1:
- while (true) {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case LBRACKET:
- ;
- break;
- default:
- jj_la1[1] = jj_gen;
- break label_1;
- }
- jj_consume_token(LBRACKET);
- jj_consume_token(RBRACKET);
- }
- }
-
- final public void PrimitiveType() throws ParseException {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case BOOLEAN:
- jj_consume_token(BOOLEAN);
- break;
- case CHAR:
- jj_consume_token(CHAR);
- break;
- case BYTE:
- jj_consume_token(BYTE);
- break;
- case SHORT:
- jj_consume_token(SHORT);
- break;
- case INT:
- jj_consume_token(INT);
- break;
- case LONG:
- jj_consume_token(LONG);
- break;
- case FLOAT:
- jj_consume_token(FLOAT);
- break;
- case DOUBLE:
- jj_consume_token(DOUBLE);
- break;
- default:
- jj_la1[2] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
-
- final public String Name() throws ParseException {
- StringBuffer sb = new StringBuffer();
- jj_consume_token(IDENTIFIER);
- sb.append(token);
- label_2:
- while (true) {
- if (jj_2_1(2)) {
- ;
- } else {
- break label_2;
- }
- jj_consume_token(DOT);
- jj_consume_token(IDENTIFIER);
- sb.append('.'); sb.append(token);
- }
- {if (true) return sb.toString();}
- throw new Error("Missing return statement in function");
- }
-
- final public void NameList() throws ParseException {
- Name();
- label_3:
- while (true) {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case COMMA:
- ;
- break;
- default:
- jj_la1[3] = jj_gen;
- break label_3;
- }
- jj_consume_token(COMMA);
- Name();
- }
- }
-
-/*
- * Expression syntax follows.
- */
- final public void Expression() throws ParseException {
- if (jj_2_2(2147483647)) {
- Assignment();
- } else {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case FALSE:
- case NEW:
- case NULL:
- case SUPER:
- case THIS:
- case TRUE:
- case INTEGER_LITERAL:
- case FLOATING_POINT_LITERAL:
- case CHARACTER_LITERAL:
- case STRING_LITERAL:
- case IDENTIFIER:
- case LPAREN:
- case BANG:
- case TILDE:
- case INCR:
- case DECR:
- case PLUS:
- case MINUS:
- ConditionalExpression();
- break;
- default:
- jj_la1[4] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
- }
-
- final public void Assignment() throws ParseException {
- PrimaryExpression();
- AssignmentOperator();
- Expression();
- LValue exprVal = pop(); pop().setValue(exprVal); push(exprVal);
- }
-
- final public void AssignmentOperator() throws ParseException {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case ASSIGN:
- jj_consume_token(ASSIGN);
- break;
- case STARASSIGN:
- jj_consume_token(STARASSIGN);
- break;
- case SLASHASSIGN:
- jj_consume_token(SLASHASSIGN);
- break;
- case REMASSIGN:
- jj_consume_token(REMASSIGN);
- break;
- case PLUSASSIGN:
- jj_consume_token(PLUSASSIGN);
- break;
- case MINUSASSIGN:
- jj_consume_token(MINUSASSIGN);
- break;
- case LSHIFTASSIGN:
- jj_consume_token(LSHIFTASSIGN);
- break;
- case RSIGNEDSHIFTASSIGN:
- jj_consume_token(RSIGNEDSHIFTASSIGN);
- break;
- case RUNSIGNEDSHIFTASSIGN:
- jj_consume_token(RUNSIGNEDSHIFTASSIGN);
- break;
- case ANDASSIGN:
- jj_consume_token(ANDASSIGN);
- break;
- case XORASSIGN:
- jj_consume_token(XORASSIGN);
- break;
- case ORASSIGN:
- jj_consume_token(ORASSIGN);
- break;
- default:
- jj_la1[5] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
-
- final public void ConditionalExpression() throws ParseException {
- ConditionalOrExpression();
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case HOOK:
- jj_consume_token(HOOK);
- Expression();
- jj_consume_token(COLON);
- ConditionalExpression();
- LValue falseBranch = pop(); LValue trueBranch = pop();
- Value cond = pop().interiorGetValue();
- if (cond instanceof BooleanValue) {
- push(((BooleanValue)cond).booleanValue()?
- trueBranch : falseBranch);
- } else {
- {if (true) throw new ParseException("Condition must be
boolean");}
- }
- break;
- default:
- jj_la1[6] = jj_gen;
- ;
- }
- }
-
- final public void ConditionalOrExpression() throws ParseException {
- ConditionalAndExpression();
- label_4:
- while (true) {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case SC_OR:
- ;
- break;
- default:
- jj_la1[7] = jj_gen;
- break label_4;
- }
- jj_consume_token(SC_OR);
- ConditionalAndExpression();
- {if (true) throw new ParseException("operation not yet supported");}
- }
- }
-
- final public void ConditionalAndExpression() throws ParseException {
- InclusiveOrExpression();
- label_5:
- while (true) {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case SC_AND:
- ;
- break;
- default:
- jj_la1[8] = jj_gen;
- break label_5;
- }
- jj_consume_token(SC_AND);
- InclusiveOrExpression();
- {if (true) throw new ParseException("operation not yet
supported");}
- }
- }
-
- final public void InclusiveOrExpression() throws ParseException {
- ExclusiveOrExpression();
- label_6:
- while (true) {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case BIT_OR:
- ;
- break;
- default:
- jj_la1[9] = jj_gen;
- break label_6;
- }
- jj_consume_token(BIT_OR);
- ExclusiveOrExpression();
- {if (true) throw new ParseException("operation not yet
supported");}
- }
- }
-
- final public void ExclusiveOrExpression() throws ParseException {
- AndExpression();
- label_7:
- while (true) {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case XOR:
- ;
- break;
- default:
- jj_la1[10] = jj_gen;
- break label_7;
- }
- jj_consume_token(XOR);
- AndExpression();
- {if (true) throw new ParseException("operation not yet
supported");}
- }
- }
-
- final public void AndExpression() throws ParseException {
- EqualityExpression();
- label_8:
- while (true) {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case BIT_AND:
- ;
- break;
- default:
- jj_la1[11] = jj_gen;
- break label_8;
- }
- jj_consume_token(BIT_AND);
- EqualityExpression();
- {if (true) throw new ParseException("operation not yet
supported");}
- }
- }
-
- final public void EqualityExpression() throws ParseException {
- Token tok;
- InstanceOfExpression();
- label_9:
- while (true) {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case EQ:
- case NE:
- ;
- break;
- default:
- jj_la1[12] = jj_gen;
- break label_9;
- }
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case EQ:
- tok = jj_consume_token(EQ);
- break;
- case NE:
- tok = jj_consume_token(NE);
- break;
- default:
- jj_la1[13] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- InstanceOfExpression();
- LValue left = pop();
- push( LValue.booleanOperation(vm, tok, pop(), left) );
- }
- }
-
- final public void InstanceOfExpression() throws ParseException {
- RelationalExpression();
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case INSTANCEOF:
- jj_consume_token(INSTANCEOF);
- Type();
- {if (true) throw new ParseException("operation not yet
supported");}
- break;
- default:
- jj_la1[14] = jj_gen;
- ;
- }
- }
-
- final public void RelationalExpression() throws ParseException {
- Token tok;
- ShiftExpression();
- label_10:
- while (true) {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case GT:
- case LT:
- case LE:
- case GE:
- ;
- break;
- default:
- jj_la1[15] = jj_gen;
- break label_10;
- }
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case LT:
- tok = jj_consume_token(LT);
- break;
- case GT:
- tok = jj_consume_token(GT);
- break;
- case LE:
- tok = jj_consume_token(LE);
- break;
- case GE:
- tok = jj_consume_token(GE);
- break;
- default:
- jj_la1[16] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- ShiftExpression();
- LValue left = pop();
- push( LValue.booleanOperation(vm, tok, pop(), left) );
- }
- }
-
- final public void ShiftExpression() throws ParseException {
- AdditiveExpression();
- label_11:
- while (true) {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case LSHIFT:
- case RSIGNEDSHIFT:
- case RUNSIGNEDSHIFT:
- ;
- break;
- default:
- jj_la1[17] = jj_gen;
- break label_11;
- }
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case LSHIFT:
- jj_consume_token(LSHIFT);
- break;
- case RSIGNEDSHIFT:
- jj_consume_token(RSIGNEDSHIFT);
- break;
- case RUNSIGNEDSHIFT:
- jj_consume_token(RUNSIGNEDSHIFT);
- break;
- default:
- jj_la1[18] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- AdditiveExpression();
- {if (true) throw new ParseException("operation not yet
supported");}
- }
- }
-
- final public void AdditiveExpression() throws ParseException {
- Token tok;
- MultiplicativeExpression();
- label_12:
- while (true) {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case PLUS:
- case MINUS:
- ;
- break;
- default:
- jj_la1[19] = jj_gen;
- break label_12;
- }
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case PLUS:
- tok = jj_consume_token(PLUS);
- break;
- case MINUS:
- tok = jj_consume_token(MINUS);
- break;
- default:
- jj_la1[20] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- MultiplicativeExpression();
- LValue left = pop();
- push( LValue.operation(vm, tok, pop(), left) );
- }
- }
-
- final public void MultiplicativeExpression() throws ParseException {
- Token tok;
- UnaryExpression();
- label_13:
- while (true) {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case STAR:
- case SLASH:
- case REM:
- ;
- break;
- default:
- jj_la1[21] = jj_gen;
- break label_13;
- }
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case STAR:
- tok = jj_consume_token(STAR);
- break;
- case SLASH:
- tok = jj_consume_token(SLASH);
- break;
- case REM:
- tok = jj_consume_token(REM);
- break;
- default:
- jj_la1[22] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- UnaryExpression();
- LValue left = pop();
- push( LValue.operation(vm, tok, pop(), left) );
- }
- }
-
- final public void UnaryExpression() throws ParseException {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case PLUS:
- case MINUS:
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case PLUS:
- jj_consume_token(PLUS);
- break;
- case MINUS:
- jj_consume_token(MINUS);
- break;
- default:
- jj_la1[23] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- UnaryExpression();
- {if (true) throw new ParseException("operation not yet
supported");}
- break;
- case INCR:
- PreIncrementExpression();
- break;
- case DECR:
- PreDecrementExpression();
- break;
- case FALSE:
- case NEW:
- case NULL:
- case SUPER:
- case THIS:
- case TRUE:
- case INTEGER_LITERAL:
- case FLOATING_POINT_LITERAL:
- case CHARACTER_LITERAL:
- case STRING_LITERAL:
- case IDENTIFIER:
- case LPAREN:
- case BANG:
- case TILDE:
- UnaryExpressionNotPlusMinus();
- break;
- default:
- jj_la1[24] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
-
- final public void PreIncrementExpression() throws ParseException {
- jj_consume_token(INCR);
- PrimaryExpression();
- {if (true) throw new ParseException("operation not yet
supported");}
- }
-
- final public void PreDecrementExpression() throws ParseException {
- jj_consume_token(DECR);
- PrimaryExpression();
- {if (true) throw new ParseException("operation not yet
supported");}
- }
-
- final public void UnaryExpressionNotPlusMinus() throws ParseException {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case BANG:
- case TILDE:
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case TILDE:
- jj_consume_token(TILDE);
- break;
- case BANG:
- jj_consume_token(BANG);
- break;
- default:
- jj_la1[25] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- UnaryExpression();
- {if (true) throw new ParseException("operation not yet
supported");}
- break;
- default:
- jj_la1[26] = jj_gen;
- if (jj_2_3(2147483647)) {
- CastExpression();
- } else {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case FALSE:
- case NEW:
- case NULL:
- case SUPER:
- case THIS:
- case TRUE:
- case INTEGER_LITERAL:
- case FLOATING_POINT_LITERAL:
- case CHARACTER_LITERAL:
- case STRING_LITERAL:
- case IDENTIFIER:
- case LPAREN:
- PostfixExpression();
- break;
- default:
- jj_la1[27] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
- }
- }
-
-// This production is to determine lookahead only. The LOOKAHEAD specifications
-// below are not used, but they are there just to indicate that we know about
-// this.
- final public void CastLookahead() throws ParseException {
- if (jj_2_4(2)) {
- jj_consume_token(LPAREN);
- PrimitiveType();
- } else if (jj_2_5(2147483647)) {
- jj_consume_token(LPAREN);
- Name();
- jj_consume_token(LBRACKET);
- jj_consume_token(RBRACKET);
- } else {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case LPAREN:
- jj_consume_token(LPAREN);
- Name();
- jj_consume_token(RPAREN);
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case TILDE:
- jj_consume_token(TILDE);
- break;
- case BANG:
- jj_consume_token(BANG);
- break;
- case LPAREN:
- jj_consume_token(LPAREN);
- break;
- case IDENTIFIER:
- jj_consume_token(IDENTIFIER);
- break;
- case THIS:
- jj_consume_token(THIS);
- break;
- case SUPER:
- jj_consume_token(SUPER);
- break;
- case NEW:
- jj_consume_token(NEW);
- break;
- case FALSE:
- case NULL:
- case TRUE:
- case INTEGER_LITERAL:
- case FLOATING_POINT_LITERAL:
- case CHARACTER_LITERAL:
- case STRING_LITERAL:
- Literal();
- break;
- default:
- jj_la1[28] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- break;
- default:
- jj_la1[29] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
- }
-
- final public void PostfixExpression() throws ParseException {
- PrimaryExpression();
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case INCR:
- case DECR:
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case INCR:
- jj_consume_token(INCR);
- break;
- case DECR:
- jj_consume_token(DECR);
- {if (true) throw new ParseException("operation not yet
supported");}
- break;
- default:
- jj_la1[30] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- break;
- default:
- jj_la1[31] = jj_gen;
- ;
- }
- }
-
- final public void CastExpression() throws ParseException {
- if (jj_2_6(2)) {
- jj_consume_token(LPAREN);
- PrimitiveType();
- label_14:
- while (true) {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case LBRACKET:
- ;
- break;
- default:
- jj_la1[32] = jj_gen;
- break label_14;
- }
- jj_consume_token(LBRACKET);
- jj_consume_token(RBRACKET);
- }
- jj_consume_token(RPAREN);
- UnaryExpression();
- } else {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case LPAREN:
- jj_consume_token(LPAREN);
- Name();
- label_15:
- while (true) {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case LBRACKET:
- ;
- break;
- default:
- jj_la1[33] = jj_gen;
- break label_15;
- }
- jj_consume_token(LBRACKET);
- jj_consume_token(RBRACKET);
- }
- jj_consume_token(RPAREN);
- UnaryExpressionNotPlusMinus();
- break;
- default:
- jj_la1[34] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
- }
-
- final public void PrimaryExpression() throws ParseException {
- PrimaryPrefix();
- label_16:
- while (true) {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case LPAREN:
- case LBRACKET:
- case DOT:
- ;
- break;
- default:
- jj_la1[35] = jj_gen;
- break label_16;
- }
- PrimarySuffix();
- }
- }
-
- final public void PrimaryPrefix() throws ParseException {
- String name;
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case FALSE:
- case NULL:
- case TRUE:
- case INTEGER_LITERAL:
- case FLOATING_POINT_LITERAL:
- case CHARACTER_LITERAL:
- case STRING_LITERAL:
- Literal();
- break;
- case IDENTIFIER:
- name = Name();
- push(LValue.makeName(vm, frameGetter, name));
- break;
- case THIS:
- jj_consume_token(THIS);
- push(LValue.makeThisObject(vm, frameGetter, token));
- break;
- case SUPER:
- jj_consume_token(SUPER);
- jj_consume_token(DOT);
- jj_consume_token(IDENTIFIER);
- {if (true) throw new ParseException("operation not yet supported");}
- break;
- case LPAREN:
- jj_consume_token(LPAREN);
- Expression();
- jj_consume_token(RPAREN);
- break;
- case NEW:
- AllocationExpression();
- break;
- default:
- jj_la1[36] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
-
- final public void PrimarySuffix() throws ParseException {
- List argList;
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case LBRACKET:
- jj_consume_token(LBRACKET);
- Expression();
- jj_consume_token(RBRACKET);
- LValue index = pop();
- push(pop().arrayElementLValue(index));
- break;
- case DOT:
- jj_consume_token(DOT);
- jj_consume_token(IDENTIFIER);
- push(pop().memberLValue(frameGetter, token.image));
- break;
- case LPAREN:
- argList = Arguments();
- peek().invokeWith(argList);
- break;
- default:
- jj_la1[37] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
-
- final public void Literal() throws ParseException {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case INTEGER_LITERAL:
- jj_consume_token(INTEGER_LITERAL);
- push(LValue.makeInteger(vm, token));
- break;
- case FLOATING_POINT_LITERAL:
- jj_consume_token(FLOATING_POINT_LITERAL);
- push(LValue.makeFloat(vm, token));
- break;
- case CHARACTER_LITERAL:
- jj_consume_token(CHARACTER_LITERAL);
- push(LValue.makeCharacter(vm, token));
- break;
- case STRING_LITERAL:
- jj_consume_token(STRING_LITERAL);
- push(LValue.makeString(vm, token));
- break;
- case FALSE:
- case TRUE:
- BooleanLiteral();
- push(LValue.makeBoolean(vm, token));
- break;
- case NULL:
- NullLiteral();
- push(LValue.makeNull(vm, token));
- break;
- default:
- jj_la1[38] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
-
- final public void BooleanLiteral() throws ParseException {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case TRUE:
- jj_consume_token(TRUE);
- break;
- case FALSE:
- jj_consume_token(FALSE);
- break;
- default:
- jj_la1[39] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
-
- final public void NullLiteral() throws ParseException {
- jj_consume_token(NULL);
- }
-
- final public List Arguments() throws ParseException {
- List argList = new ArrayList();
- jj_consume_token(LPAREN);
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case FALSE:
- case NEW:
- case NULL:
- case SUPER:
- case THIS:
- case TRUE:
- case INTEGER_LITERAL:
- case FLOATING_POINT_LITERAL:
- case CHARACTER_LITERAL:
- case STRING_LITERAL:
- case IDENTIFIER:
- case LPAREN:
- case BANG:
- case TILDE:
- case INCR:
- case DECR:
- case PLUS:
- case MINUS:
- ArgumentList(argList);
- break;
- default:
- jj_la1[40] = jj_gen;
- ;
- }
- jj_consume_token(RPAREN);
- {if (true) return argList;}
- throw new Error("Missing return statement in function");
- }
-
- final public void ArgumentList(List argList) throws ParseException {
- Expression();
- argList.add(pop().interiorGetValue());
- label_17:
- while (true) {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case COMMA:
- ;
- break;
- default:
- jj_la1[41] = jj_gen;
- break label_17;
- }
- jj_consume_token(COMMA);
- Expression();
- argList.add(pop().interiorGetValue());
- }
- }
-
- final public void AllocationExpression() throws ParseException {
- List argList; String className;
- if (jj_2_7(2)) {
- jj_consume_token(NEW);
- PrimitiveType();
- ArrayDimensions();
- } else {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case NEW:
- jj_consume_token(NEW);
- className = Name();
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case LPAREN:
- argList = Arguments();
- push(LValue.makeNewObject(vm, frameGetter, className,
argList));
- break;
- case LBRACKET:
- ArrayDimensions();
- {if (true) throw new ParseException("operation not yet
supported");}
- break;
- default:
- jj_la1[42] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- break;
- default:
- jj_la1[43] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
- }
-
-/*
- * The second LOOKAHEAD specification below is to parse to PrimarySuffix
- * if there is an expression between the "[...]".
- */
- final public void ArrayDimensions() throws ParseException {
- label_18:
- while (true) {
- jj_consume_token(LBRACKET);
- Expression();
- jj_consume_token(RBRACKET);
- if (jj_2_8(2)) {
- ;
- } else {
- break label_18;
- }
- }
- label_19:
- while (true) {
- if (jj_2_9(2)) {
- ;
- } else {
- break label_19;
- }
- jj_consume_token(LBRACKET);
- jj_consume_token(RBRACKET);
- }
- }
-
- final private boolean jj_2_1(int xla) {
- jj_la = xla; jj_lastpos = jj_scanpos = token;
- boolean retval = !jj_3_1();
- jj_save(0, xla);
- return retval;
- }
-
- final private boolean jj_2_2(int xla) {
- jj_la = xla; jj_lastpos = jj_scanpos = token;
- boolean retval = !jj_3_2();
- jj_save(1, xla);
- return retval;
- }
-
- final private boolean jj_2_3(int xla) {
- jj_la = xla; jj_lastpos = jj_scanpos = token;
- boolean retval = !jj_3_3();
- jj_save(2, xla);
- return retval;
- }
-
- final private boolean jj_2_4(int xla) {
- jj_la = xla; jj_lastpos = jj_scanpos = token;
- boolean retval = !jj_3_4();
- jj_save(3, xla);
- return retval;
- }
-
- final private boolean jj_2_5(int xla) {
- jj_la = xla; jj_lastpos = jj_scanpos = token;
- boolean retval = !jj_3_5();
- jj_save(4, xla);
- return retval;
- }
-
- final private boolean jj_2_6(int xla) {
- jj_la = xla; jj_lastpos = jj_scanpos = token;
- boolean retval = !jj_3_6();
- jj_save(5, xla);
- return retval;
- }
-
- final private boolean jj_2_7(int xla) {
- jj_la = xla; jj_lastpos = jj_scanpos = token;
- boolean retval = !jj_3_7();
- jj_save(6, xla);
- return retval;
- }
-
- final private boolean jj_2_8(int xla) {
- jj_la = xla; jj_lastpos = jj_scanpos = token;
- boolean retval = !jj_3_8();
- jj_save(7, xla);
- return retval;
- }
-
- final private boolean jj_2_9(int xla) {
- jj_la = xla; jj_lastpos = jj_scanpos = token;
- boolean retval = !jj_3_9();
- jj_save(8, xla);
- return retval;
- }
-
- final private boolean jj_3R_154() {
- if (jj_scan_token(INCR)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_151() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_154()) {
- jj_scanpos = xsp;
- if (jj_3R_155()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_148() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3_6()) {
- jj_scanpos = xsp;
- if (jj_3R_150()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3_6() {
- if (jj_scan_token(LPAREN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_23()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_3R_152()) { jj_scanpos = xsp; break; }
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- }
- if (jj_scan_token(RPAREN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_115()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_25() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_50()) {
- jj_scanpos = xsp;
- if (jj_3R_51()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_50() {
- if (jj_3R_67()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3_5() {
- if (jj_scan_token(LPAREN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_24()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_scan_token(LBRACKET)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_149() {
- if (jj_3R_20()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_151()) jj_scanpos = xsp;
- else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_41() {
- if (jj_scan_token(LPAREN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_24()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_scan_token(RPAREN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_59()) {
- jj_scanpos = xsp;
- if (jj_3R_60()) {
- jj_scanpos = xsp;
- if (jj_3R_61()) {
- jj_scanpos = xsp;
- if (jj_3R_62()) {
- jj_scanpos = xsp;
- if (jj_3R_63()) {
- jj_scanpos = xsp;
- if (jj_3R_64()) {
- jj_scanpos = xsp;
- if (jj_3R_65()) {
- jj_scanpos = xsp;
- if (jj_3R_66()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_40() {
- if (jj_scan_token(LPAREN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_24()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_scan_token(LBRACKET)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_scan_token(RBRACKET)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_123() {
- if (jj_scan_token(LBRACKET)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_scan_token(RBRACKET)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3_1() {
- if (jj_scan_token(DOT)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_scan_token(IDENTIFIER)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3_4() {
- if (jj_scan_token(LPAREN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_23()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_22() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3_4()) {
- jj_scanpos = xsp;
- if (jj_3R_40()) {
- jj_scanpos = xsp;
- if (jj_3R_41()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3_3() {
- if (jj_3R_22()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_24() {
- if (jj_scan_token(IDENTIFIER)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_3_1()) { jj_scanpos = xsp; break; }
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- }
- return false;
- }
-
- final private boolean jj_3R_147() {
- if (jj_scan_token(BANG)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_142() {
- if (jj_3R_149()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_122() {
- if (jj_3R_24()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_49() {
- if (jj_scan_token(DOUBLE)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_141() {
- if (jj_3R_148()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_48() {
- if (jj_scan_token(FLOAT)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_146() {
- if (jj_scan_token(TILDE)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_47() {
- if (jj_scan_token(LONG)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_140() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_146()) {
- jj_scanpos = xsp;
- if (jj_3R_147()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_115()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_136() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_140()) {
- jj_scanpos = xsp;
- if (jj_3R_141()) {
- jj_scanpos = xsp;
- if (jj_3R_142()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_46() {
- if (jj_scan_token(INT)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_145() {
- if (jj_scan_token(REM)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_45() {
- if (jj_scan_token(SHORT)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_44() {
- if (jj_scan_token(BYTE)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_135() {
- if (jj_scan_token(DECR)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_20()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_43() {
- if (jj_scan_token(CHAR)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_23() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_42()) {
- jj_scanpos = xsp;
- if (jj_3R_43()) {
- jj_scanpos = xsp;
- if (jj_3R_44()) {
- jj_scanpos = xsp;
- if (jj_3R_45()) {
- jj_scanpos = xsp;
- if (jj_3R_46()) {
- jj_scanpos = xsp;
- if (jj_3R_47()) {
- jj_scanpos = xsp;
- if (jj_3R_48()) {
- jj_scanpos = xsp;
- if (jj_3R_49()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_42() {
- if (jj_scan_token(BOOLEAN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3_9() {
- if (jj_scan_token(LBRACKET)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_scan_token(RBRACKET)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_121() {
- if (jj_3R_23()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_144() {
- if (jj_scan_token(SLASH)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_134() {
- if (jj_scan_token(INCR)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_20()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_114() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_121()) {
- jj_scanpos = xsp;
- if (jj_3R_122()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- while (true) {
- xsp = jj_scanpos;
- if (jj_3R_123()) { jj_scanpos = xsp; break; }
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- }
- return false;
- }
-
- final private boolean jj_3R_120() {
- if (jj_scan_token(GE)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_133() {
- if (jj_scan_token(MINUS)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_127() {
- if (jj_3R_136()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_126() {
- if (jj_3R_135()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_139() {
- if (jj_scan_token(MINUS)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_125() {
- if (jj_3R_134()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_132() {
- if (jj_scan_token(PLUS)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_143() {
- if (jj_scan_token(STAR)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_124() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_132()) {
- jj_scanpos = xsp;
- if (jj_3R_133()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_115()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_115() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_124()) {
- jj_scanpos = xsp;
- if (jj_3R_125()) {
- jj_scanpos = xsp;
- if (jj_3R_126()) {
- jj_scanpos = xsp;
- if (jj_3R_127()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_137() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_143()) {
- jj_scanpos = xsp;
- if (jj_3R_144()) {
- jj_scanpos = xsp;
- if (jj_3R_145()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_115()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_131() {
- if (jj_scan_token(RUNSIGNEDSHIFT)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_119() {
- if (jj_scan_token(LE)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_138() {
- if (jj_scan_token(PLUS)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_112() {
- if (jj_3R_115()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_3R_137()) { jj_scanpos = xsp; break; }
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- }
- return false;
- }
-
- final private boolean jj_3R_88() {
- if (jj_3R_86()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_130() {
- if (jj_scan_token(RSIGNEDSHIFT)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_128() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_138()) {
- jj_scanpos = xsp;
- if (jj_3R_139()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_112()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_87() {
- if (jj_3R_82()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_118() {
- if (jj_scan_token(GT)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_129() {
- if (jj_scan_token(LSHIFT)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_116() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_129()) {
- jj_scanpos = xsp;
- if (jj_3R_130()) {
- jj_scanpos = xsp;
- if (jj_3R_131()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_108()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_108() {
- if (jj_3R_112()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_3R_128()) { jj_scanpos = xsp; break; }
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- }
- return false;
- }
-
- final private boolean jj_3_8() {
- if (jj_scan_token(LBRACKET)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_25()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_scan_token(RBRACKET)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_86() {
- Token xsp;
- if (jj_3_8()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- while (true) {
- xsp = jj_scanpos;
- if (jj_3_8()) { jj_scanpos = xsp; break; }
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- }
- while (true) {
- xsp = jj_scanpos;
- if (jj_3_9()) { jj_scanpos = xsp; break; }
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- }
- return false;
- }
-
- final private boolean jj_3R_117() {
- if (jj_scan_token(LT)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_106() {
- if (jj_3R_108()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_3R_116()) { jj_scanpos = xsp; break; }
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- }
- return false;
- }
-
- final private boolean jj_3R_113() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_117()) {
- jj_scanpos = xsp;
- if (jj_3R_118()) {
- jj_scanpos = xsp;
- if (jj_3R_119()) {
- jj_scanpos = xsp;
- if (jj_3R_120()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_106()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_111() {
- if (jj_scan_token(NE)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_109() {
- if (jj_scan_token(INSTANCEOF)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_114()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_104() {
- if (jj_3R_106()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_3R_113()) { jj_scanpos = xsp; break; }
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- }
- return false;
- }
-
- final private boolean jj_3R_81() {
- if (jj_scan_token(NEW)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_24()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_87()) {
- jj_scanpos = xsp;
- if (jj_3R_88()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3_7() {
- if (jj_scan_token(NEW)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_23()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_86()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_70() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3_7()) {
- jj_scanpos = xsp;
- if (jj_3R_81()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_97() {
- if (jj_scan_token(COMMA)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_25()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_39() {
- if (jj_scan_token(ORASSIGN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_110() {
- if (jj_scan_token(EQ)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_102() {
- if (jj_3R_104()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_109()) jj_scanpos = xsp;
- else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_107() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_110()) {
- jj_scanpos = xsp;
- if (jj_3R_111()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_102()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_94() {
- if (jj_3R_25()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_3R_97()) { jj_scanpos = xsp; break; }
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- }
- return false;
- }
-
- final private boolean jj_3R_89() {
- if (jj_3R_94()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_38() {
- if (jj_scan_token(XORASSIGN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_82() {
- if (jj_scan_token(LPAREN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_89()) jj_scanpos = xsp;
- else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_scan_token(RPAREN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_105() {
- if (jj_scan_token(BIT_AND)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_100()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_100() {
- if (jj_3R_102()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_3R_107()) { jj_scanpos = xsp; break; }
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- }
- return false;
- }
-
- final private boolean jj_3R_37() {
- if (jj_scan_token(ANDASSIGN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_85() {
- if (jj_scan_token(NULL)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_103() {
- if (jj_scan_token(XOR)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_98()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_98() {
- if (jj_3R_100()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_3R_105()) { jj_scanpos = xsp; break; }
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- }
- return false;
- }
-
- final private boolean jj_3R_92() {
- if (jj_scan_token(FALSE)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_36() {
- if (jj_scan_token(RUNSIGNEDSHIFTASSIGN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_91() {
- if (jj_scan_token(TRUE)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_84() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_91()) {
- jj_scanpos = xsp;
- if (jj_3R_92()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_101() {
- if (jj_scan_token(BIT_OR)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_95()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_95() {
- if (jj_3R_98()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_3R_103()) { jj_scanpos = xsp; break; }
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- }
- return false;
- }
-
- final private boolean jj_3R_35() {
- if (jj_scan_token(RSIGNEDSHIFTASSIGN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_80() {
- if (jj_3R_85()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_66() {
- if (jj_3R_69()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_79() {
- if (jj_3R_84()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_78() {
- if (jj_scan_token(STRING_LITERAL)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_99() {
- if (jj_scan_token(SC_AND)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_90()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_90() {
- if (jj_3R_95()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_3R_101()) { jj_scanpos = xsp; break; }
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- }
- return false;
- }
-
- final private boolean jj_3R_34() {
- if (jj_scan_token(LSHIFTASSIGN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_65() {
- if (jj_scan_token(NEW)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_77() {
- if (jj_scan_token(CHARACTER_LITERAL)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_76() {
- if (jj_scan_token(FLOATING_POINT_LITERAL)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_33() {
- if (jj_scan_token(MINUSASSIGN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_69() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_75()) {
- jj_scanpos = xsp;
- if (jj_3R_76()) {
- jj_scanpos = xsp;
- if (jj_3R_77()) {
- jj_scanpos = xsp;
- if (jj_3R_78()) {
- jj_scanpos = xsp;
- if (jj_3R_79()) {
- jj_scanpos = xsp;
- if (jj_3R_80()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_75() {
- if (jj_scan_token(INTEGER_LITERAL)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_96() {
- if (jj_scan_token(SC_OR)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_83()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_83() {
- if (jj_3R_90()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_3R_99()) { jj_scanpos = xsp; break; }
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- }
- return false;
- }
-
- final private boolean jj_3R_64() {
- if (jj_scan_token(SUPER)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_32() {
- if (jj_scan_token(PLUSASSIGN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_73() {
- if (jj_3R_82()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_72() {
- if (jj_scan_token(DOT)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_scan_token(IDENTIFIER)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_74() {
- if (jj_3R_83()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_3R_96()) { jj_scanpos = xsp; break; }
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- }
- return false;
- }
-
- final private boolean jj_3R_63() {
- if (jj_scan_token(THIS)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_31() {
- if (jj_scan_token(REMASSIGN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_58() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_71()) {
- jj_scanpos = xsp;
- if (jj_3R_72()) {
- jj_scanpos = xsp;
- if (jj_3R_73()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_71() {
- if (jj_scan_token(LBRACKET)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_25()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_scan_token(RBRACKET)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_93() {
- if (jj_scan_token(HOOK)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_25()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_scan_token(COLON)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_68()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_57() {
- if (jj_3R_70()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_30() {
- if (jj_scan_token(SLASHASSIGN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_27() {
- if (jj_3R_58()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_56() {
- if (jj_scan_token(LPAREN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_25()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_scan_token(RPAREN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_152() {
- if (jj_scan_token(LBRACKET)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_scan_token(RBRACKET)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_55() {
- if (jj_scan_token(SUPER)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_scan_token(DOT)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_scan_token(IDENTIFIER)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_29() {
- if (jj_scan_token(STARASSIGN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_68() {
- if (jj_3R_74()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_93()) jj_scanpos = xsp;
- else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_54() {
- if (jj_scan_token(THIS)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_62() {
- if (jj_scan_token(IDENTIFIER)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_53() {
- if (jj_3R_24()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_153() {
- if (jj_scan_token(LBRACKET)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_scan_token(RBRACKET)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_26() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_52()) {
- jj_scanpos = xsp;
- if (jj_3R_53()) {
- jj_scanpos = xsp;
- if (jj_3R_54()) {
- jj_scanpos = xsp;
- if (jj_3R_55()) {
- jj_scanpos = xsp;
- if (jj_3R_56()) {
- jj_scanpos = xsp;
- if (jj_3R_57()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_52() {
- if (jj_3R_69()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_21() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_28()) {
- jj_scanpos = xsp;
- if (jj_3R_29()) {
- jj_scanpos = xsp;
- if (jj_3R_30()) {
- jj_scanpos = xsp;
- if (jj_3R_31()) {
- jj_scanpos = xsp;
- if (jj_3R_32()) {
- jj_scanpos = xsp;
- if (jj_3R_33()) {
- jj_scanpos = xsp;
- if (jj_3R_34()) {
- jj_scanpos = xsp;
- if (jj_3R_35()) {
- jj_scanpos = xsp;
- if (jj_3R_36()) {
- jj_scanpos = xsp;
- if (jj_3R_37()) {
- jj_scanpos = xsp;
- if (jj_3R_38()) {
- jj_scanpos = xsp;
- if (jj_3R_39()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_28() {
- if (jj_scan_token(ASSIGN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_61() {
- if (jj_scan_token(LPAREN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3_2() {
- if (jj_3R_20()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_21()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_20() {
- if (jj_3R_26()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_3R_27()) { jj_scanpos = xsp; break; }
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- }
- return false;
- }
-
- final private boolean jj_3R_60() {
- if (jj_scan_token(BANG)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_155() {
- if (jj_scan_token(DECR)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_67() {
- if (jj_3R_20()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_21()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_25()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_150() {
- if (jj_scan_token(LPAREN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_24()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_3R_153()) { jj_scanpos = xsp; break; }
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- }
- if (jj_scan_token(RPAREN)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- if (jj_3R_136()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_59() {
- if (jj_scan_token(TILDE)) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- final private boolean jj_3R_51() {
- if (jj_3R_68()) return true;
- if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
- return false;
- }
-
- public ExpressionParserTokenManager token_source;
- ASCII_UCodeESC_CharStream jj_input_stream;
- public Token token, jj_nt;
- private int jj_ntk;
- private Token jj_scanpos, jj_lastpos;
- private int jj_la;
- public boolean lookingAhead = false;
- private boolean jj_semLA;
- private int jj_gen;
- final private int[] jj_la1 = new int[44];
- final private int[] jj_la1_0 =
{0x8209400,0x0,0x8209400,0x0,0x1000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000000,0x0,0x0,0x1000000,0x1000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000000,0x0,0x1000000,0x1000000,0x1000000,0x0,0x0,0x0,};
- final private int[] jj_la1_1 =
{0x2014,0x0,0x2014,0x0,0x884480c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x884480c0,0x0,0x0,0x884480c0,0x884480c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x884480c0,0x0,0x88400080,0x400000,0x884480c0,0x0,0x0,0x40,};
- final private int[] jj_la1_2 =
{0x8,0x400,0x0,0x2000,0xf00c004e,0x8000,0x100000,0x4000000,0x8000000,0x0,0x0,0x0,0x2400000,0x2400000,0x0,0x1830000,0x1830000,0x0,0x0,0xc0000000,0xc0000000,0x0,0x0,0xc0000000,0xf00c004e,0xc0000,0xc0000,0x4e,0xc004e,0x40,0x30000000,0x30000000,0x400,0x400,0x40,0x4440,0x4e,0x4440,0x6,0x0,0xf00c004e,0x2000,0x440,0x0,};
- final private int[] jj_la1_3 =
{0x0,0x0,0x0,0x0,0x0,0xffe00,0x0,0x0,0x0,0x8,0x10,0x4,0x0,0x0,0x0,0x0,0x0,0x1c0,0x1c0,0x0,0x0,0x23,0x23,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,};
- final private JJExpressionParserCalls[] jj_2_rtns = new JJExpressionParserCalls[9];
- private boolean jj_rescan = false;
- private int jj_gc = 0;
-
- public ExpressionParser(java.io.InputStream stream) {
- jj_input_stream = new ASCII_UCodeESC_CharStream(stream, 1, 1);
- token_source = new ExpressionParserTokenManager(jj_input_stream);
- token = new Token();
- jj_ntk = -1;
- jj_gen = 0;
- for (int i = 0; i < 44; i++) jj_la1[i] = -1;
- for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new
JJExpressionParserCalls();
- }
-
- public void ReInit(java.io.InputStream stream) {
- jj_input_stream.ReInit(stream, 1, 1);
- token_source.ReInit(jj_input_stream);
- token = new Token();
- jj_ntk = -1;
- jj_gen = 0;
- for (int i = 0; i < 44; i++) jj_la1[i] = -1;
- for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new
JJExpressionParserCalls();
- }
-
- public ExpressionParser(ExpressionParserTokenManager tm) {
- token_source = tm;
- token = new Token();
- jj_ntk = -1;
- jj_gen = 0;
- for (int i = 0; i < 44; i++) jj_la1[i] = -1;
- for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new
JJExpressionParserCalls();
- }
-
- public void ReInit(ExpressionParserTokenManager tm) {
- token_source = tm;
- token = new Token();
- jj_ntk = -1;
- jj_gen = 0;
- for (int i = 0; i < 44; i++) jj_la1[i] = -1;
- for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new
JJExpressionParserCalls();
- }
-
- final private Token jj_consume_token(int kind) throws ParseException {
- Token oldToken;
- if ((oldToken = token).next != null) token = token.next;
- else token = token.next = token_source.getNextToken();
- jj_ntk = -1;
- if (token.kind == kind) {
- jj_gen++;
- if (++jj_gc > 100) {
- jj_gc = 0;
- for (int i = 0; i < jj_2_rtns.length; i++) {
- JJExpressionParserCalls c = jj_2_rtns[i];
- while (c != null) {
- if (c.gen < jj_gen) c.first = null;
- c = c.next;
- }
- }
- }
- return token;
- }
- token = oldToken;
- jj_kind = kind;
- throw generateParseException();
- }
-
- final private boolean jj_scan_token(int kind) {
- if (jj_scanpos == jj_lastpos) {
- jj_la--;
- if (jj_scanpos.next == null) {
- jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
- } else {
- jj_lastpos = jj_scanpos = jj_scanpos.next;
- }
- } else {
- jj_scanpos = jj_scanpos.next;
- }
- if (jj_rescan) {
- int i = 0; Token tok = token;
- while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
- if (tok != null) jj_add_error_token(kind, i);
- }
- return (jj_scanpos.kind != kind);
- }
-
- final public Token getNextToken() {
- if (token.next != null) token = token.next;
- else token = token.next = token_source.getNextToken();
- jj_ntk = -1;
- jj_gen++;
- return token;
- }
-
- final public Token getToken(int index) {
- Token t = lookingAhead ? jj_scanpos : token;
- for (int i = 0; i < index; i++) {
- if (t.next != null) t = t.next;
- else t = t.next = token_source.getNextToken();
- }
- return t;
- }
-
- final private int jj_ntk() {
- if ((jj_nt=token.next) == null)
- return (jj_ntk = (token.next=token_source.getNextToken()).kind);
- else
- return (jj_ntk = jj_nt.kind);
- }
-
- private java.util.Vector jj_expentries = new java.util.Vector();
- private int[] jj_expentry;
- private int jj_kind = -1;
- private int[] jj_lasttokens = new int[100];
- private int jj_endpos;
-
- private void jj_add_error_token(int kind, int pos) {
- if (pos >= 100) return;
- if (pos == jj_endpos + 1) {
- jj_lasttokens[jj_endpos++] = kind;
- } else if (jj_endpos != 0) {
- jj_expentry = new int[jj_endpos];
- for (int i = 0; i < jj_endpos; i++) {
- jj_expentry[i] = jj_lasttokens[i];
- }
- boolean exists = false;
- for (java.util.Enumeration enum = jj_expentries.elements();
enum.hasMoreElements();) {
- int[] oldentry = (int[])(enum.nextElement());
- if (oldentry.length == jj_expentry.length) {
- exists = true;
- for (int i = 0; i < jj_expentry.length; i++) {
- if (oldentry[i] != jj_expentry[i]) {
- exists = false;
- break;
- }
- }
- if (exists) break;
- }
- }
- if (!exists) jj_expentries.addElement(jj_expentry);
- if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
- }
- }
-
- final public ParseException generateParseException() {
- jj_expentries.removeAllElements();
- boolean[] la1tokens = new boolean[116];
- for (int i = 0; i < 116; i++) {
- la1tokens[i] = false;
- }
- if (jj_kind >= 0) {
- la1tokens[jj_kind] = true;
- jj_kind = -1;
- }
- for (int i = 0; i < 44; i++) {
- if (jj_la1[i] == jj_gen) {
- for (int j = 0; j < 32; j++) {
- if ((jj_la1_0[i] & (1<<j)) != 0) {
- la1tokens[j] = true;
- }
- if ((jj_la1_1[i] & (1<<j)) != 0) {
- la1tokens[32+j] = true;
- }
- if ((jj_la1_2[i] & (1<<j)) != 0) {
- la1tokens[64+j] = true;
- }
- if ((jj_la1_3[i] & (1<<j)) != 0) {
- la1tokens[96+j] = true;
- }
- }
- }
- }
- for (int i = 0; i < 116; i++) {
- if (la1tokens[i]) {
- jj_expentry = new int[1];
- jj_expentry[0] = i;
- jj_expentries.addElement(jj_expentry);
- }
- }
- jj_endpos = 0;
- jj_rescan_token();
- jj_add_error_token(0, 0);
- int[][] exptokseq = new int[jj_expentries.size()][];
- for (int i = 0; i < jj_expentries.size(); i++) {
- exptokseq[i] = (int[])jj_expentries.elementAt(i);
- }
- return new ParseException(token, exptokseq, tokenImage);
- }
-
- final public void enable_tracing() {
- }
-
- final public void disable_tracing() {
- }
-
- final private void jj_rescan_token() {
- jj_rescan = true;
- for (int i = 0; i < 9; i++) {
- JJExpressionParserCalls p = jj_2_rtns[i];
- do {
- if (p.gen > jj_gen) {
- jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
- switch (i) {
- case 0: jj_3_1(); break;
- case 1: jj_3_2(); break;
- case 2: jj_3_3(); break;
- case 3: jj_3_4(); break;
- case 4: jj_3_5(); break;
- case 5: jj_3_6(); break;
- case 6: jj_3_7(); break;
- case 7: jj_3_8(); break;
- case 8: jj_3_9(); break;
- }
- }
- p = p.next;
- } while (p != null);
- }
- jj_rescan = false;
- }
-
- final private void jj_save(int index, int xla) {
- JJExpressionParserCalls p = jj_2_rtns[index];
- while (p.gen > jj_gen) {
- if (p.next == null) { p = p.next = new JJExpressionParserCalls(); break; }
- p = p.next;
- }
- p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
- }
-
-}
-
-final class JJExpressionParserCalls {
- int gen;
- Token first;
- int arg;
- JJExpressionParserCalls next;
-}
+/* Generated By:JavaCC: Do not edit this line. ExpressionParser.java */
+package jde.debugger.expr;
+
+import com.sun.jdi.*;
+import java.util.Stack;
+import java.util.List;
+import java.util.ArrayList;
+
+public class ExpressionParser implements ExpressionParserConstants {
+
+ Stack stack = new Stack();
+ VirtualMachine vm = null;
+ GetFrame frameGetter = null;
+
+ LValue peek() {
+ return (LValue)stack.peek();
+ }
+
+ LValue pop() {
+ return (LValue)stack.pop();
+ }
+
+ void push(LValue lval) {
+ stack.push(lval);
+ }
+
+ public interface GetFrame {
+ StackFrame get() throws IncompatibleThreadStateException;
+ }
+
+ public static Value evaluate(String expr, VirtualMachine vm,
+ GetFrame frameGetter) throws ParseException,
+ InvocationException,
+ InvalidTypeException,
+ ClassNotLoadedException,
+ IncompatibleThreadStateException {
+ java.io.InputStream in = new java.io.ByteArrayInputStream(expr.getBytes());
+ ExpressionParser parser = new ExpressionParser(in);
+ parser.vm = vm;
+ parser.frameGetter = frameGetter;
+ Value value = null;
+ parser.Expression();
+ return parser.pop().getValue();
+ }
+
+ public static void main(String args[]) {
+ ExpressionParser parser;
+ System.out.print("Java Expression Parser: ");
+ if (args.length == 0) {
+ System.out.println("Reading from standard input . . .");
+ parser = new ExpressionParser(System.in);
+ } else if (args.length == 1) {
+ System.out.println("Reading from file " + args[0] + " . .
.");
+ try {
+ parser = new ExpressionParser(new java.io.FileInputStream(args[0]));
+ } catch (java.io.FileNotFoundException e) {
+ System.out.println("Java Parser Version 1.0.2: File " +
+ args[0] + " not found.");
+ return;
+ }
+ } else {
+ System.out.println("Usage is one of:");
+ System.out.println(" java ExpressionParser < inputfile");
+ System.out.println("OR");
+ System.out.println(" java ExpressionParser inputfile");
+ return;
+ }
+ try {
+ parser.Expression();
+ System.out.print("Java Expression Parser: ");
+ System.out.println("Java program parsed successfully.");
+ } catch (ParseException e) {
+ System.out.print("Java Expression Parser: ");
+ System.out.println("Encountered errors during parse.");
+ }
+ }
+
+/*****************************************
+ * THE JAVA LANGUAGE GRAMMAR STARTS HERE *
+ *****************************************/
+
+/*
+ * Type, name and expression syntax follows.
+ */
+ final public void Type() throws ParseException {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case BOOLEAN:
+ case BYTE:
+ case CHAR:
+ case DOUBLE:
+ case FLOAT:
+ case INT:
+ case LONG:
+ case SHORT:
+ PrimitiveType();
+ break;
+ case IDENTIFIER:
+ Name();
+ break;
+ default:
+ jj_la1[0] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ label_1:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case LBRACKET:
+ ;
+ break;
+ default:
+ jj_la1[1] = jj_gen;
+ break label_1;
+ }
+ jj_consume_token(LBRACKET);
+ jj_consume_token(RBRACKET);
+ }
+ }
+
+ final public void PrimitiveType() throws ParseException {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case BOOLEAN:
+ jj_consume_token(BOOLEAN);
+ break;
+ case CHAR:
+ jj_consume_token(CHAR);
+ break;
+ case BYTE:
+ jj_consume_token(BYTE);
+ break;
+ case SHORT:
+ jj_consume_token(SHORT);
+ break;
+ case INT:
+ jj_consume_token(INT);
+ break;
+ case LONG:
+ jj_consume_token(LONG);
+ break;
+ case FLOAT:
+ jj_consume_token(FLOAT);
+ break;
+ case DOUBLE:
+ jj_consume_token(DOUBLE);
+ break;
+ default:
+ jj_la1[2] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+
+ final public String Name() throws ParseException {
+ StringBuffer sb = new StringBuffer();
+ jj_consume_token(IDENTIFIER);
+ sb.append(token);
+ label_2:
+ while (true) {
+ if (jj_2_1(2)) {
+ ;
+ } else {
+ break label_2;
+ }
+ jj_consume_token(DOT);
+ jj_consume_token(IDENTIFIER);
+ sb.append('.'); sb.append(token);
+ }
+ {if (true) return sb.toString();}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public void NameList() throws ParseException {
+ Name();
+ label_3:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case COMMA:
+ ;
+ break;
+ default:
+ jj_la1[3] = jj_gen;
+ break label_3;
+ }
+ jj_consume_token(COMMA);
+ Name();
+ }
+ }
+
+/*
+ * Expression syntax follows.
+ */
+ final public void Expression() throws ParseException {
+ if (jj_2_2(2147483647)) {
+ Assignment();
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case FALSE:
+ case NEW:
+ case NULL:
+ case SUPER:
+ case THIS:
+ case TRUE:
+ case INTEGER_LITERAL:
+ case FLOATING_POINT_LITERAL:
+ case CHARACTER_LITERAL:
+ case STRING_LITERAL:
+ case IDENTIFIER:
+ case LPAREN:
+ case BANG:
+ case TILDE:
+ case INCR:
+ case DECR:
+ case PLUS:
+ case MINUS:
+ ConditionalExpression();
+ break;
+ default:
+ jj_la1[4] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+ }
+
+ final public void Assignment() throws ParseException {
+ PrimaryExpression();
+ AssignmentOperator();
+ Expression();
+ LValue exprVal = pop(); pop().setValue(exprVal); push(exprVal);
+ }
+
+ final public void AssignmentOperator() throws ParseException {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case ASSIGN:
+ jj_consume_token(ASSIGN);
+ break;
+ case STARASSIGN:
+ jj_consume_token(STARASSIGN);
+ break;
+ case SLASHASSIGN:
+ jj_consume_token(SLASHASSIGN);
+ break;
+ case REMASSIGN:
+ jj_consume_token(REMASSIGN);
+ break;
+ case PLUSASSIGN:
+ jj_consume_token(PLUSASSIGN);
+ break;
+ case MINUSASSIGN:
+ jj_consume_token(MINUSASSIGN);
+ break;
+ case LSHIFTASSIGN:
+ jj_consume_token(LSHIFTASSIGN);
+ break;
+ case RSIGNEDSHIFTASSIGN:
+ jj_consume_token(RSIGNEDSHIFTASSIGN);
+ break;
+ case RUNSIGNEDSHIFTASSIGN:
+ jj_consume_token(RUNSIGNEDSHIFTASSIGN);
+ break;
+ case ANDASSIGN:
+ jj_consume_token(ANDASSIGN);
+ break;
+ case XORASSIGN:
+ jj_consume_token(XORASSIGN);
+ break;
+ case ORASSIGN:
+ jj_consume_token(ORASSIGN);
+ break;
+ default:
+ jj_la1[5] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+
+ final public void ConditionalExpression() throws ParseException {
+ ConditionalOrExpression();
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case HOOK:
+ jj_consume_token(HOOK);
+ Expression();
+ jj_consume_token(COLON);
+ ConditionalExpression();
+ LValue falseBranch = pop(); LValue trueBranch = pop();
+ Value cond = pop().interiorGetValue();
+ if (cond instanceof BooleanValue) {
+ push(((BooleanValue)cond).booleanValue()?
+ trueBranch : falseBranch);
+ } else {
+ {if (true) throw new ParseException("Condition must be
boolean");}
+ }
+ break;
+ default:
+ jj_la1[6] = jj_gen;
+ ;
+ }
+ }
+
+ final public void ConditionalOrExpression() throws ParseException {
+ ConditionalAndExpression();
+ label_4:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case SC_OR:
+ ;
+ break;
+ default:
+ jj_la1[7] = jj_gen;
+ break label_4;
+ }
+ jj_consume_token(SC_OR);
+ ConditionalAndExpression();
+ {if (true) throw new ParseException("operation not yet supported");}
+ }
+ }
+
+ final public void ConditionalAndExpression() throws ParseException {
+ InclusiveOrExpression();
+ label_5:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case SC_AND:
+ ;
+ break;
+ default:
+ jj_la1[8] = jj_gen;
+ break label_5;
+ }
+ jj_consume_token(SC_AND);
+ InclusiveOrExpression();
+ {if (true) throw new ParseException("operation not yet
supported");}
+ }
+ }
+
+ final public void InclusiveOrExpression() throws ParseException {
+ ExclusiveOrExpression();
+ label_6:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case BIT_OR:
+ ;
+ break;
+ default:
+ jj_la1[9] = jj_gen;
+ break label_6;
+ }
+ jj_consume_token(BIT_OR);
+ ExclusiveOrExpression();
+ {if (true) throw new ParseException("operation not yet
supported");}
+ }
+ }
+
+ final public void ExclusiveOrExpression() throws ParseException {
+ AndExpression();
+ label_7:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case XOR:
+ ;
+ break;
+ default:
+ jj_la1[10] = jj_gen;
+ break label_7;
+ }
+ jj_consume_token(XOR);
+ AndExpression();
+ {if (true) throw new ParseException("operation not yet
supported");}
+ }
+ }
+
+ final public void AndExpression() throws ParseException {
+ EqualityExpression();
+ label_8:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case BIT_AND:
+ ;
+ break;
+ default:
+ jj_la1[11] = jj_gen;
+ break label_8;
+ }
+ jj_consume_token(BIT_AND);
+ EqualityExpression();
+ {if (true) throw new ParseException("operation not yet
supported");}
+ }
+ }
+
+ final public void EqualityExpression() throws ParseException {
+ Token tok;
+ InstanceOfExpression();
+ label_9:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case EQ:
+ case NE:
+ ;
+ break;
+ default:
+ jj_la1[12] = jj_gen;
+ break label_9;
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case EQ:
+ tok = jj_consume_token(EQ);
+ break;
+ case NE:
+ tok = jj_consume_token(NE);
+ break;
+ default:
+ jj_la1[13] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ InstanceOfExpression();
+ LValue left = pop();
+ push( LValue.booleanOperation(vm, tok, pop(), left) );
+ }
+ }
+
+ final public void InstanceOfExpression() throws ParseException {
+ RelationalExpression();
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case INSTANCEOF:
+ jj_consume_token(INSTANCEOF);
+ Type();
+ {if (true) throw new ParseException("operation not yet
supported");}
+ break;
+ default:
+ jj_la1[14] = jj_gen;
+ ;
+ }
+ }
+
+ final public void RelationalExpression() throws ParseException {
+ Token tok;
+ ShiftExpression();
+ label_10:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case GT:
+ case LT:
+ case LE:
+ case GE:
+ ;
+ break;
+ default:
+ jj_la1[15] = jj_gen;
+ break label_10;
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case LT:
+ tok = jj_consume_token(LT);
+ break;
+ case GT:
+ tok = jj_consume_token(GT);
+ break;
+ case LE:
+ tok = jj_consume_token(LE);
+ break;
+ case GE:
+ tok = jj_consume_token(GE);
+ break;
+ default:
+ jj_la1[16] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ ShiftExpression();
+ LValue left = pop();
+ push( LValue.booleanOperation(vm, tok, pop(), left) );
+ }
+ }
+
+ final public void ShiftExpression() throws ParseException {
+ AdditiveExpression();
+ label_11:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case LSHIFT:
+ case RSIGNEDSHIFT:
+ case RUNSIGNEDSHIFT:
+ ;
+ break;
+ default:
+ jj_la1[17] = jj_gen;
+ break label_11;
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case LSHIFT:
+ jj_consume_token(LSHIFT);
+ break;
+ case RSIGNEDSHIFT:
+ jj_consume_token(RSIGNEDSHIFT);
+ break;
+ case RUNSIGNEDSHIFT:
+ jj_consume_token(RUNSIGNEDSHIFT);
+ break;
+ default:
+ jj_la1[18] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ AdditiveExpression();
+ {if (true) throw new ParseException("operation not yet
supported");}
+ }
+ }
+
+ final public void AdditiveExpression() throws ParseException {
+ Token tok;
+ MultiplicativeExpression();
+ label_12:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case MINUS:
+ ;
+ break;
+ default:
+ jj_la1[19] = jj_gen;
+ break label_12;
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ tok = jj_consume_token(PLUS);
+ break;
+ case MINUS:
+ tok = jj_consume_token(MINUS);
+ break;
+ default:
+ jj_la1[20] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ MultiplicativeExpression();
+ LValue left = pop();
+ push( LValue.operation(vm, tok, pop(), left) );
+ }
+ }
+
+ final public void MultiplicativeExpression() throws ParseException {
+ Token tok;
+ UnaryExpression();
+ label_13:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case STAR:
+ case SLASH:
+ case REM:
+ ;
+ break;
+ default:
+ jj_la1[21] = jj_gen;
+ break label_13;
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case STAR:
+ tok = jj_consume_token(STAR);
+ break;
+ case SLASH:
+ tok = jj_consume_token(SLASH);
+ break;
+ case REM:
+ tok = jj_consume_token(REM);
+ break;
+ default:
+ jj_la1[22] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ UnaryExpression();
+ LValue left = pop();
+ push( LValue.operation(vm, tok, pop(), left) );
+ }
+ }
+
+ final public void UnaryExpression() throws ParseException {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case MINUS:
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ jj_consume_token(PLUS);
+ break;
+ case MINUS:
+ jj_consume_token(MINUS);
+ break;
+ default:
+ jj_la1[23] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ UnaryExpression();
+ {if (true) throw new ParseException("operation not yet
supported");}
+ break;
+ case INCR:
+ PreIncrementExpression();
+ break;
+ case DECR:
+ PreDecrementExpression();
+ break;
+ case FALSE:
+ case NEW:
+ case NULL:
+ case SUPER:
+ case THIS:
+ case TRUE:
+ case INTEGER_LITERAL:
+ case FLOATING_POINT_LITERAL:
+ case CHARACTER_LITERAL:
+ case STRING_LITERAL:
+ case IDENTIFIER:
+ case LPAREN:
+ case BANG:
+ case TILDE:
+ UnaryExpressionNotPlusMinus();
+ break;
+ default:
+ jj_la1[24] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+
+ final public void PreIncrementExpression() throws ParseException {
+ jj_consume_token(INCR);
+ PrimaryExpression();
+ {if (true) throw new ParseException("operation not yet
supported");}
+ }
+
+ final public void PreDecrementExpression() throws ParseException {
+ jj_consume_token(DECR);
+ PrimaryExpression();
+ {if (true) throw new ParseException("operation not yet
supported");}
+ }
+
+ final public void UnaryExpressionNotPlusMinus() throws ParseException {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case BANG:
+ case TILDE:
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case TILDE:
+ jj_consume_token(TILDE);
+ break;
+ case BANG:
+ jj_consume_token(BANG);
+ break;
+ default:
+ jj_la1[25] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ UnaryExpression();
+ {if (true) throw new ParseException("operation not yet
supported");}
+ break;
+ default:
+ jj_la1[26] = jj_gen;
+ if (jj_2_3(2147483647)) {
+ CastExpression();
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case FALSE:
+ case NEW:
+ case NULL:
+ case SUPER:
+ case THIS:
+ case TRUE:
+ case INTEGER_LITERAL:
+ case FLOATING_POINT_LITERAL:
+ case CHARACTER_LITERAL:
+ case STRING_LITERAL:
+ case IDENTIFIER:
+ case LPAREN:
+ PostfixExpression();
+ break;
+ default:
+ jj_la1[27] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+ }
+ }
+
+// This production is to determine lookahead only. The LOOKAHEAD specifications
+// below are not used, but they are there just to indicate that we know about
+// this.
+ final public void CastLookahead() throws ParseException {
+ if (jj_2_4(2)) {
+ jj_consume_token(LPAREN);
+ PrimitiveType();
+ } else if (jj_2_5(2147483647)) {
+ jj_consume_token(LPAREN);
+ Name();
+ jj_consume_token(LBRACKET);
+ jj_consume_token(RBRACKET);
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case LPAREN:
+ jj_consume_token(LPAREN);
+ Name();
+ jj_consume_token(RPAREN);
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case TILDE:
+ jj_consume_token(TILDE);
+ break;
+ case BANG:
+ jj_consume_token(BANG);
+ break;
+ case LPAREN:
+ jj_consume_token(LPAREN);
+ break;
+ case IDENTIFIER:
+ jj_consume_token(IDENTIFIER);
+ break;
+ case THIS:
+ jj_consume_token(THIS);
+ break;
+ case SUPER:
+ jj_consume_token(SUPER);
+ break;
+ case NEW:
+ jj_consume_token(NEW);
+ break;
+ case FALSE:
+ case NULL:
+ case TRUE:
+ case INTEGER_LITERAL:
+ case FLOATING_POINT_LITERAL:
+ case CHARACTER_LITERAL:
+ case STRING_LITERAL:
+ Literal();
+ break;
+ default:
+ jj_la1[28] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ break;
+ default:
+ jj_la1[29] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+ }
+
+ final public void PostfixExpression() throws ParseException {
+ PrimaryExpression();
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case INCR:
+ case DECR:
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case INCR:
+ jj_consume_token(INCR);
+ break;
+ case DECR:
+ jj_consume_token(DECR);
+ {if (true) throw new ParseException("operation not yet
supported");}
+ break;
+ default:
+ jj_la1[30] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ break;
+ default:
+ jj_la1[31] = jj_gen;
+ ;
+ }
+ }
+
+ final public void CastExpression() throws ParseException {
+ if (jj_2_6(2)) {
+ jj_consume_token(LPAREN);
+ PrimitiveType();
+ label_14:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case LBRACKET:
+ ;
+ break;
+ default:
+ jj_la1[32] = jj_gen;
+ break label_14;
+ }
+ jj_consume_token(LBRACKET);
+ jj_consume_token(RBRACKET);
+ }
+ jj_consume_token(RPAREN);
+ UnaryExpression();
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case LPAREN:
+ jj_consume_token(LPAREN);
+ Name();
+ label_15:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case LBRACKET:
+ ;
+ break;
+ default:
+ jj_la1[33] = jj_gen;
+ break label_15;
+ }
+ jj_consume_token(LBRACKET);
+ jj_consume_token(RBRACKET);
+ }
+ jj_consume_token(RPAREN);
+ UnaryExpressionNotPlusMinus();
+ break;
+ default:
+ jj_la1[34] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+ }
+
+ final public void PrimaryExpression() throws ParseException {
+ PrimaryPrefix();
+ label_16:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case LPAREN:
+ case LBRACKET:
+ case DOT:
+ ;
+ break;
+ default:
+ jj_la1[35] = jj_gen;
+ break label_16;
+ }
+ PrimarySuffix();
+ }
+ }
+
+ final public void PrimaryPrefix() throws ParseException {
+ String name;
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case FALSE:
+ case NULL:
+ case TRUE:
+ case INTEGER_LITERAL:
+ case FLOATING_POINT_LITERAL:
+ case CHARACTER_LITERAL:
+ case STRING_LITERAL:
+ Literal();
+ break;
+ case IDENTIFIER:
+ name = Name();
+ push(LValue.makeName(vm, frameGetter, name));
+ break;
+ case THIS:
+ jj_consume_token(THIS);
+ push(LValue.makeThisObject(vm, frameGetter, token));
+ break;
+ case SUPER:
+ jj_consume_token(SUPER);
+ jj_consume_token(DOT);
+ jj_consume_token(IDENTIFIER);
+ {if (true) throw new ParseException("operation not yet supported");}
+ break;
+ case LPAREN:
+ jj_consume_token(LPAREN);
+ Expression();
+ jj_consume_token(RPAREN);
+ break;
+ case NEW:
+ AllocationExpression();
+ break;
+ default:
+ jj_la1[36] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+
+ final public void PrimarySuffix() throws ParseException {
+ List argList;
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case LBRACKET:
+ jj_consume_token(LBRACKET);
+ Expression();
+ jj_consume_token(RBRACKET);
+ LValue index = pop();
+ push(pop().arrayElementLValue(index));
+ break;
+ case DOT:
+ jj_consume_token(DOT);
+ jj_consume_token(IDENTIFIER);
+ push(pop().memberLValue(frameGetter, token.image));
+ break;
+ case LPAREN:
+ argList = Arguments();
+ peek().invokeWith(argList);
+ break;
+ default:
+ jj_la1[37] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+
+ final public void Literal() throws ParseException {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case INTEGER_LITERAL:
+ jj_consume_token(INTEGER_LITERAL);
+ push(LValue.makeInteger(vm, token));
+ break;
+ case FLOATING_POINT_LITERAL:
+ jj_consume_token(FLOATING_POINT_LITERAL);
+ push(LValue.makeFloat(vm, token));
+ break;
+ case CHARACTER_LITERAL:
+ jj_consume_token(CHARACTER_LITERAL);
+ push(LValue.makeCharacter(vm, token));
+ break;
+ case STRING_LITERAL:
+ jj_consume_token(STRING_LITERAL);
+ push(LValue.makeString(vm, token));
+ break;
+ case FALSE:
+ case TRUE:
+ BooleanLiteral();
+ push(LValue.makeBoolean(vm, token));
+ break;
+ case NULL:
+ NullLiteral();
+ push(LValue.makeNull(vm, token));
+ break;
+ default:
+ jj_la1[38] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+
+ final public void BooleanLiteral() throws ParseException {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case TRUE:
+ jj_consume_token(TRUE);
+ break;
+ case FALSE:
+ jj_consume_token(FALSE);
+ break;
+ default:
+ jj_la1[39] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+
+ final public void NullLiteral() throws ParseException {
+ jj_consume_token(NULL);
+ }
+
+ final public List Arguments() throws ParseException {
+ List argList = new ArrayList();
+ jj_consume_token(LPAREN);
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case FALSE:
+ case NEW:
+ case NULL:
+ case SUPER:
+ case THIS:
+ case TRUE:
+ case INTEGER_LITERAL:
+ case FLOATING_POINT_LITERAL:
+ case CHARACTER_LITERAL:
+ case STRING_LITERAL:
+ case IDENTIFIER:
+ case LPAREN:
+ case BANG:
+ case TILDE:
+ case INCR:
+ case DECR:
+ case PLUS:
+ case MINUS:
+ ArgumentList(argList);
+ break;
+ default:
+ jj_la1[40] = jj_gen;
+ ;
+ }
+ jj_consume_token(RPAREN);
+ {if (true) return argList;}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public void ArgumentList(List argList) throws ParseException {
+ Expression();
+ argList.add(pop().interiorGetValue());
+ label_17:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case COMMA:
+ ;
+ break;
+ default:
+ jj_la1[41] = jj_gen;
+ break label_17;
+ }
+ jj_consume_token(COMMA);
+ Expression();
+ argList.add(pop().interiorGetValue());
+ }
+ }
+
+ final public void AllocationExpression() throws ParseException {
+ List argList; String className;
+ if (jj_2_7(2)) {
+ jj_consume_token(NEW);
+ PrimitiveType();
+ ArrayDimensions();
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case NEW:
+ jj_consume_token(NEW);
+ className = Name();
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case LPAREN:
+ argList = Arguments();
+ push(LValue.makeNewObject(vm, frameGetter, className,
argList));
+ break;
+ case LBRACKET:
+ ArrayDimensions();
+ {if (true) throw new ParseException("operation not yet
supported");}
+ break;
+ default:
+ jj_la1[42] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ break;
+ default:
+ jj_la1[43] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+ }
+
+/*
+ * The second LOOKAHEAD specification below is to parse to PrimarySuffix
+ * if there is an expression between the "[...]".
+ */
+ final public void ArrayDimensions() throws ParseException {
+ label_18:
+ while (true) {
+ jj_consume_token(LBRACKET);
+ Expression();
+ jj_consume_token(RBRACKET);
+ if (jj_2_8(2)) {
+ ;
+ } else {
+ break label_18;
+ }
+ }
+ label_19:
+ while (true) {
+ if (jj_2_9(2)) {
+ ;
+ } else {
+ break label_19;
+ }
+ jj_consume_token(LBRACKET);
+ jj_consume_token(RBRACKET);
+ }
+ }
+
+ final private boolean jj_2_1(int xla) {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ boolean retval = !jj_3_1();
+ jj_save(0, xla);
+ return retval;
+ }
+
+ final private boolean jj_2_2(int xla) {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ boolean retval = !jj_3_2();
+ jj_save(1, xla);
+ return retval;
+ }
+
+ final private boolean jj_2_3(int xla) {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ boolean retval = !jj_3_3();
+ jj_save(2, xla);
+ return retval;
+ }
+
+ final private boolean jj_2_4(int xla) {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ boolean retval = !jj_3_4();
+ jj_save(3, xla);
+ return retval;
+ }
+
+ final private boolean jj_2_5(int xla) {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ boolean retval = !jj_3_5();
+ jj_save(4, xla);
+ return retval;
+ }
+
+ final private boolean jj_2_6(int xla) {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ boolean retval = !jj_3_6();
+ jj_save(5, xla);
+ return retval;
+ }
+
+ final private boolean jj_2_7(int xla) {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ boolean retval = !jj_3_7();
+ jj_save(6, xla);
+ return retval;
+ }
+
+ final private boolean jj_2_8(int xla) {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ boolean retval = !jj_3_8();
+ jj_save(7, xla);
+ return retval;
+ }
+
+ final private boolean jj_2_9(int xla) {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ boolean retval = !jj_3_9();
+ jj_save(8, xla);
+ return retval;
+ }
+
+ final private boolean jj_3R_154() {
+ if (jj_scan_token(INCR)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_151() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_154()) {
+ jj_scanpos = xsp;
+ if (jj_3R_155()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_148() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3_6()) {
+ jj_scanpos = xsp;
+ if (jj_3R_150()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3_6() {
+ if (jj_scan_token(LPAREN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_23()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_152()) { jj_scanpos = xsp; break; }
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ }
+ if (jj_scan_token(RPAREN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_115()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_25() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_50()) {
+ jj_scanpos = xsp;
+ if (jj_3R_51()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_50() {
+ if (jj_3R_67()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3_5() {
+ if (jj_scan_token(LPAREN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_24()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_scan_token(LBRACKET)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_149() {
+ if (jj_3R_20()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_151()) jj_scanpos = xsp;
+ else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_41() {
+ if (jj_scan_token(LPAREN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_24()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_scan_token(RPAREN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_59()) {
+ jj_scanpos = xsp;
+ if (jj_3R_60()) {
+ jj_scanpos = xsp;
+ if (jj_3R_61()) {
+ jj_scanpos = xsp;
+ if (jj_3R_62()) {
+ jj_scanpos = xsp;
+ if (jj_3R_63()) {
+ jj_scanpos = xsp;
+ if (jj_3R_64()) {
+ jj_scanpos = xsp;
+ if (jj_3R_65()) {
+ jj_scanpos = xsp;
+ if (jj_3R_66()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_40() {
+ if (jj_scan_token(LPAREN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_24()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_scan_token(LBRACKET)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_scan_token(RBRACKET)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_123() {
+ if (jj_scan_token(LBRACKET)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_scan_token(RBRACKET)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3_1() {
+ if (jj_scan_token(DOT)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_scan_token(IDENTIFIER)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3_4() {
+ if (jj_scan_token(LPAREN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_23()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_22() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3_4()) {
+ jj_scanpos = xsp;
+ if (jj_3R_40()) {
+ jj_scanpos = xsp;
+ if (jj_3R_41()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3_3() {
+ if (jj_3R_22()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_24() {
+ if (jj_scan_token(IDENTIFIER)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3_1()) { jj_scanpos = xsp; break; }
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ }
+ return false;
+ }
+
+ final private boolean jj_3R_147() {
+ if (jj_scan_token(BANG)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_142() {
+ if (jj_3R_149()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_122() {
+ if (jj_3R_24()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_49() {
+ if (jj_scan_token(DOUBLE)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_141() {
+ if (jj_3R_148()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_48() {
+ if (jj_scan_token(FLOAT)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_146() {
+ if (jj_scan_token(TILDE)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_47() {
+ if (jj_scan_token(LONG)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_140() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_146()) {
+ jj_scanpos = xsp;
+ if (jj_3R_147()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_115()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_136() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_140()) {
+ jj_scanpos = xsp;
+ if (jj_3R_141()) {
+ jj_scanpos = xsp;
+ if (jj_3R_142()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_46() {
+ if (jj_scan_token(INT)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_145() {
+ if (jj_scan_token(REM)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_45() {
+ if (jj_scan_token(SHORT)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_44() {
+ if (jj_scan_token(BYTE)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_135() {
+ if (jj_scan_token(DECR)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_20()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_43() {
+ if (jj_scan_token(CHAR)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_23() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_42()) {
+ jj_scanpos = xsp;
+ if (jj_3R_43()) {
+ jj_scanpos = xsp;
+ if (jj_3R_44()) {
+ jj_scanpos = xsp;
+ if (jj_3R_45()) {
+ jj_scanpos = xsp;
+ if (jj_3R_46()) {
+ jj_scanpos = xsp;
+ if (jj_3R_47()) {
+ jj_scanpos = xsp;
+ if (jj_3R_48()) {
+ jj_scanpos = xsp;
+ if (jj_3R_49()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_42() {
+ if (jj_scan_token(BOOLEAN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3_9() {
+ if (jj_scan_token(LBRACKET)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_scan_token(RBRACKET)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_121() {
+ if (jj_3R_23()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_144() {
+ if (jj_scan_token(SLASH)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_134() {
+ if (jj_scan_token(INCR)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_20()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_114() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_121()) {
+ jj_scanpos = xsp;
+ if (jj_3R_122()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_123()) { jj_scanpos = xsp; break; }
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ }
+ return false;
+ }
+
+ final private boolean jj_3R_120() {
+ if (jj_scan_token(GE)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_133() {
+ if (jj_scan_token(MINUS)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_127() {
+ if (jj_3R_136()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_126() {
+ if (jj_3R_135()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_139() {
+ if (jj_scan_token(MINUS)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_125() {
+ if (jj_3R_134()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_132() {
+ if (jj_scan_token(PLUS)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_143() {
+ if (jj_scan_token(STAR)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_124() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_132()) {
+ jj_scanpos = xsp;
+ if (jj_3R_133()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_115()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_115() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_124()) {
+ jj_scanpos = xsp;
+ if (jj_3R_125()) {
+ jj_scanpos = xsp;
+ if (jj_3R_126()) {
+ jj_scanpos = xsp;
+ if (jj_3R_127()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_137() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_143()) {
+ jj_scanpos = xsp;
+ if (jj_3R_144()) {
+ jj_scanpos = xsp;
+ if (jj_3R_145()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_115()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_131() {
+ if (jj_scan_token(RUNSIGNEDSHIFT)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_119() {
+ if (jj_scan_token(LE)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_138() {
+ if (jj_scan_token(PLUS)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_112() {
+ if (jj_3R_115()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_137()) { jj_scanpos = xsp; break; }
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ }
+ return false;
+ }
+
+ final private boolean jj_3R_88() {
+ if (jj_3R_86()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_130() {
+ if (jj_scan_token(RSIGNEDSHIFT)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_128() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_138()) {
+ jj_scanpos = xsp;
+ if (jj_3R_139()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_112()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_87() {
+ if (jj_3R_82()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_118() {
+ if (jj_scan_token(GT)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_129() {
+ if (jj_scan_token(LSHIFT)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_116() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_129()) {
+ jj_scanpos = xsp;
+ if (jj_3R_130()) {
+ jj_scanpos = xsp;
+ if (jj_3R_131()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_108()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_108() {
+ if (jj_3R_112()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_128()) { jj_scanpos = xsp; break; }
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ }
+ return false;
+ }
+
+ final private boolean jj_3_8() {
+ if (jj_scan_token(LBRACKET)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_25()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_scan_token(RBRACKET)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_86() {
+ Token xsp;
+ if (jj_3_8()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3_8()) { jj_scanpos = xsp; break; }
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ }
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3_9()) { jj_scanpos = xsp; break; }
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ }
+ return false;
+ }
+
+ final private boolean jj_3R_117() {
+ if (jj_scan_token(LT)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_106() {
+ if (jj_3R_108()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_116()) { jj_scanpos = xsp; break; }
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ }
+ return false;
+ }
+
+ final private boolean jj_3R_113() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_117()) {
+ jj_scanpos = xsp;
+ if (jj_3R_118()) {
+ jj_scanpos = xsp;
+ if (jj_3R_119()) {
+ jj_scanpos = xsp;
+ if (jj_3R_120()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_106()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_111() {
+ if (jj_scan_token(NE)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_109() {
+ if (jj_scan_token(INSTANCEOF)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_114()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_104() {
+ if (jj_3R_106()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_113()) { jj_scanpos = xsp; break; }
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ }
+ return false;
+ }
+
+ final private boolean jj_3R_81() {
+ if (jj_scan_token(NEW)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_24()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_87()) {
+ jj_scanpos = xsp;
+ if (jj_3R_88()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3_7() {
+ if (jj_scan_token(NEW)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_23()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_86()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_70() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3_7()) {
+ jj_scanpos = xsp;
+ if (jj_3R_81()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_97() {
+ if (jj_scan_token(COMMA)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_25()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_39() {
+ if (jj_scan_token(ORASSIGN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_110() {
+ if (jj_scan_token(EQ)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_102() {
+ if (jj_3R_104()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_109()) jj_scanpos = xsp;
+ else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_107() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_110()) {
+ jj_scanpos = xsp;
+ if (jj_3R_111()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_102()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_94() {
+ if (jj_3R_25()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_97()) { jj_scanpos = xsp; break; }
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ }
+ return false;
+ }
+
+ final private boolean jj_3R_89() {
+ if (jj_3R_94()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_38() {
+ if (jj_scan_token(XORASSIGN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_82() {
+ if (jj_scan_token(LPAREN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_89()) jj_scanpos = xsp;
+ else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_scan_token(RPAREN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_105() {
+ if (jj_scan_token(BIT_AND)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_100()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_100() {
+ if (jj_3R_102()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_107()) { jj_scanpos = xsp; break; }
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ }
+ return false;
+ }
+
+ final private boolean jj_3R_37() {
+ if (jj_scan_token(ANDASSIGN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_85() {
+ if (jj_scan_token(NULL)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_103() {
+ if (jj_scan_token(XOR)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_98()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_98() {
+ if (jj_3R_100()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_105()) { jj_scanpos = xsp; break; }
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ }
+ return false;
+ }
+
+ final private boolean jj_3R_92() {
+ if (jj_scan_token(FALSE)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_36() {
+ if (jj_scan_token(RUNSIGNEDSHIFTASSIGN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_91() {
+ if (jj_scan_token(TRUE)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_84() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_91()) {
+ jj_scanpos = xsp;
+ if (jj_3R_92()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_101() {
+ if (jj_scan_token(BIT_OR)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_95()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_95() {
+ if (jj_3R_98()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_103()) { jj_scanpos = xsp; break; }
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ }
+ return false;
+ }
+
+ final private boolean jj_3R_35() {
+ if (jj_scan_token(RSIGNEDSHIFTASSIGN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_80() {
+ if (jj_3R_85()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_66() {
+ if (jj_3R_69()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_79() {
+ if (jj_3R_84()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_78() {
+ if (jj_scan_token(STRING_LITERAL)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_99() {
+ if (jj_scan_token(SC_AND)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_90()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_90() {
+ if (jj_3R_95()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_101()) { jj_scanpos = xsp; break; }
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ }
+ return false;
+ }
+
+ final private boolean jj_3R_34() {
+ if (jj_scan_token(LSHIFTASSIGN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_65() {
+ if (jj_scan_token(NEW)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_77() {
+ if (jj_scan_token(CHARACTER_LITERAL)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_76() {
+ if (jj_scan_token(FLOATING_POINT_LITERAL)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_33() {
+ if (jj_scan_token(MINUSASSIGN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_69() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_75()) {
+ jj_scanpos = xsp;
+ if (jj_3R_76()) {
+ jj_scanpos = xsp;
+ if (jj_3R_77()) {
+ jj_scanpos = xsp;
+ if (jj_3R_78()) {
+ jj_scanpos = xsp;
+ if (jj_3R_79()) {
+ jj_scanpos = xsp;
+ if (jj_3R_80()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_75() {
+ if (jj_scan_token(INTEGER_LITERAL)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_96() {
+ if (jj_scan_token(SC_OR)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_83()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_83() {
+ if (jj_3R_90()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_99()) { jj_scanpos = xsp; break; }
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ }
+ return false;
+ }
+
+ final private boolean jj_3R_64() {
+ if (jj_scan_token(SUPER)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_32() {
+ if (jj_scan_token(PLUSASSIGN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_73() {
+ if (jj_3R_82()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_72() {
+ if (jj_scan_token(DOT)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_scan_token(IDENTIFIER)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_74() {
+ if (jj_3R_83()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_96()) { jj_scanpos = xsp; break; }
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ }
+ return false;
+ }
+
+ final private boolean jj_3R_63() {
+ if (jj_scan_token(THIS)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_31() {
+ if (jj_scan_token(REMASSIGN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_58() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_71()) {
+ jj_scanpos = xsp;
+ if (jj_3R_72()) {
+ jj_scanpos = xsp;
+ if (jj_3R_73()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_71() {
+ if (jj_scan_token(LBRACKET)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_25()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_scan_token(RBRACKET)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_93() {
+ if (jj_scan_token(HOOK)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_25()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_scan_token(COLON)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_68()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_57() {
+ if (jj_3R_70()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_30() {
+ if (jj_scan_token(SLASHASSIGN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_27() {
+ if (jj_3R_58()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_56() {
+ if (jj_scan_token(LPAREN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_25()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_scan_token(RPAREN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_152() {
+ if (jj_scan_token(LBRACKET)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_scan_token(RBRACKET)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_55() {
+ if (jj_scan_token(SUPER)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_scan_token(DOT)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_scan_token(IDENTIFIER)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_29() {
+ if (jj_scan_token(STARASSIGN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_68() {
+ if (jj_3R_74()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_93()) jj_scanpos = xsp;
+ else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_54() {
+ if (jj_scan_token(THIS)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_62() {
+ if (jj_scan_token(IDENTIFIER)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_53() {
+ if (jj_3R_24()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_153() {
+ if (jj_scan_token(LBRACKET)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_scan_token(RBRACKET)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_26() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_52()) {
+ jj_scanpos = xsp;
+ if (jj_3R_53()) {
+ jj_scanpos = xsp;
+ if (jj_3R_54()) {
+ jj_scanpos = xsp;
+ if (jj_3R_55()) {
+ jj_scanpos = xsp;
+ if (jj_3R_56()) {
+ jj_scanpos = xsp;
+ if (jj_3R_57()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_52() {
+ if (jj_3R_69()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_21() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_28()) {
+ jj_scanpos = xsp;
+ if (jj_3R_29()) {
+ jj_scanpos = xsp;
+ if (jj_3R_30()) {
+ jj_scanpos = xsp;
+ if (jj_3R_31()) {
+ jj_scanpos = xsp;
+ if (jj_3R_32()) {
+ jj_scanpos = xsp;
+ if (jj_3R_33()) {
+ jj_scanpos = xsp;
+ if (jj_3R_34()) {
+ jj_scanpos = xsp;
+ if (jj_3R_35()) {
+ jj_scanpos = xsp;
+ if (jj_3R_36()) {
+ jj_scanpos = xsp;
+ if (jj_3R_37()) {
+ jj_scanpos = xsp;
+ if (jj_3R_38()) {
+ jj_scanpos = xsp;
+ if (jj_3R_39()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ } else if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_28() {
+ if (jj_scan_token(ASSIGN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_61() {
+ if (jj_scan_token(LPAREN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3_2() {
+ if (jj_3R_20()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_21()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_20() {
+ if (jj_3R_26()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_27()) { jj_scanpos = xsp; break; }
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ }
+ return false;
+ }
+
+ final private boolean jj_3R_60() {
+ if (jj_scan_token(BANG)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_155() {
+ if (jj_scan_token(DECR)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_67() {
+ if (jj_3R_20()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_21()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_25()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_150() {
+ if (jj_scan_token(LPAREN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_24()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_153()) { jj_scanpos = xsp; break; }
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ }
+ if (jj_scan_token(RPAREN)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ if (jj_3R_136()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_59() {
+ if (jj_scan_token(TILDE)) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ final private boolean jj_3R_51() {
+ if (jj_3R_68()) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) return false;
+ return false;
+ }
+
+ public ExpressionParserTokenManager token_source;
+ ASCII_UCodeESC_CharStream jj_input_stream;
+ public Token token, jj_nt;
+ private int jj_ntk;
+ private Token jj_scanpos, jj_lastpos;
+ private int jj_la;
+ public boolean lookingAhead = false;
+ private boolean jj_semLA;
+ private int jj_gen;
+ final private int[] jj_la1 = new int[44];
+ final private int[] jj_la1_0 =
{0x8209400,0x0,0x8209400,0x0,0x1000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000000,0x0,0x0,0x1000000,0x1000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000000,0x0,0x1000000,0x1000000,0x1000000,0x0,0x0,0x0,};
+ final private int[] jj_la1_1 =
{0x2014,0x0,0x2014,0x0,0x884480c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x884480c0,0x0,0x0,0x884480c0,0x884480c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x884480c0,0x0,0x88400080,0x400000,0x884480c0,0x0,0x0,0x40,};
+ final private int[] jj_la1_2 =
{0x8,0x400,0x0,0x2000,0xf00c004e,0x8000,0x100000,0x4000000,0x8000000,0x0,0x0,0x0,0x2400000,0x2400000,0x0,0x1830000,0x1830000,0x0,0x0,0xc0000000,0xc0000000,0x0,0x0,0xc0000000,0xf00c004e,0xc0000,0xc0000,0x4e,0xc004e,0x40,0x30000000,0x30000000,0x400,0x400,0x40,0x4440,0x4e,0x4440,0x6,0x0,0xf00c004e,0x2000,0x440,0x0,};
+ final private int[] jj_la1_3 =
{0x0,0x0,0x0,0x0,0x0,0xffe00,0x0,0x0,0x0,0x8,0x10,0x4,0x0,0x0,0x0,0x0,0x0,0x1c0,0x1c0,0x0,0x0,0x23,0x23,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,};
+ final private JJExpressionParserCalls[] jj_2_rtns = new JJExpressionParserCalls[9];
+ private boolean jj_rescan = false;
+ private int jj_gc = 0;
+
+ public ExpressionParser(java.io.InputStream stream) {
+ jj_input_stream = new ASCII_UCodeESC_CharStream(stream, 1, 1);
+ token_source = new ExpressionParserTokenManager(jj_input_stream);
+ token = new Token();
+ jj_ntk = -1;
+ jj_gen = 0;
+ for (int i = 0; i < 44; i++) jj_la1[i] = -1;
+ for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new
JJExpressionParserCalls();
+ }
+
+ public void ReInit(java.io.InputStream stream) {
+ jj_input_stream.ReInit(stream, 1, 1);
+ token_source.ReInit(jj_input_stream);
+ token = new Token();
+ jj_ntk = -1;
+ jj_gen = 0;
+ for (int i = 0; i < 44; i++) jj_la1[i] = -1;
+ for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new
JJExpressionParserCalls();
+ }
+
+ public ExpressionParser(ExpressionParserTokenManager tm) {
+ token_source = tm;
+ token = new Token();
+ jj_ntk = -1;
+ jj_gen = 0;
+ for (int i = 0; i < 44; i++) jj_la1[i] = -1;
+ for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new
JJExpressionParserCalls();
+ }
+
+ public void ReInit(ExpressionParserTokenManager tm) {
+ token_source = tm;
+ token = new Token();
+ jj_ntk = -1;
+ jj_gen = 0;
+ for (int i = 0; i < 44; i++) jj_la1[i] = -1;
+ for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new
JJExpressionParserCalls();
+ }
+
+ final private Token jj_consume_token(int kind) throws ParseException {
+ Token oldToken;
+ if ((oldToken = token).next != null) token = token.next;
+ else token = token.next = token_source.getNextToken();
+ jj_ntk = -1;
+ if (token.kind == kind) {
+ jj_gen++;
+ if (++jj_gc > 100) {
+ jj_gc = 0;
+ for (int i = 0; i < jj_2_rtns.length; i++) {
+ JJExpressionParserCalls c = jj_2_rtns[i];
+ while (c != null) {
+ if (c.gen < jj_gen) c.first = null;
+ c = c.next;
+ }
+ }
+ }
+ return token;
+ }
+ token = oldToken;
+ jj_kind = kind;
+ throw generateParseException();
+ }
+
+ final private boolean jj_scan_token(int kind) {
+ if (jj_scanpos == jj_lastpos) {
+ jj_la--;
+ if (jj_scanpos.next == null) {
+ jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
+ } else {
+ jj_lastpos = jj_scanpos = jj_scanpos.next;
+ }
+ } else {
+ jj_scanpos = jj_scanpos.next;
+ }
+ if (jj_rescan) {
+ int i = 0; Token tok = token;
+ while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
+ if (tok != null) jj_add_error_token(kind, i);
+ }
+ return (jj_scanpos.kind != kind);
+ }
+
+ final public Token getNextToken() {
+ if (token.next != null) token = token.next;
+ else token = token.next = token_source.getNextToken();
+ jj_ntk = -1;
+ jj_gen++;
+ return token;
+ }
+
+ final public Token getToken(int index) {
+ Token t = lookingAhead ? jj_scanpos : token;
+ for (int i = 0; i < index; i++) {
+ if (t.next != null) t = t.next;
+ else t = t.next = token_source.getNextToken();
+ }
+ return t;
+ }
+
+ final private int jj_ntk() {
+ if ((jj_nt=token.next) == null)
+ return (jj_ntk = (token.next=token_source.getNextToken()).kind);
+ else
+ return (jj_ntk = jj_nt.kind);
+ }
+
+ private java.util.Vector jj_expentries = new java.util.Vector();
+ private int[] jj_expentry;
+ private int jj_kind = -1;
+ private int[] jj_lasttokens = new int[100];
+ private int jj_endpos;
+
+ private void jj_add_error_token(int kind, int pos) {
+ if (pos >= 100) return;
+ if (pos == jj_endpos + 1) {
+ jj_lasttokens[jj_endpos++] = kind;
+ } else if (jj_endpos != 0) {
+ jj_expentry = new int[jj_endpos];
+ for (int i = 0; i < jj_endpos; i++) {
+ jj_expentry[i] = jj_lasttokens[i];
+ }
+ boolean exists = false;
+ for (java.util.Enumeration enum = jj_expentries.elements();
enum.hasMoreElements();) {
+ int[] oldentry = (int[])(enum.nextElement());
+ if (oldentry.length == jj_expentry.length) {
+ exists = true;
+ for (int i = 0; i < jj_expentry.length; i++) {
+ if (oldentry[i] != jj_expentry[i]) {
+ exists = false;
+ break;
+ }
+ }
+ if (exists) break;
+ }
+ }
+ if (!exists) jj_expentries.addElement(jj_expentry);
+ if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
+ }
+ }
+
+ final public ParseException generateParseException() {
+ jj_expentries.removeAllElements();
+ boolean[] la1tokens = new boolean[116];
+ for (int i = 0; i < 116; i++) {
+ la1tokens[i] = false;
+ }
+ if (jj_kind >= 0) {
+ la1tokens[jj_kind] = true;
+ jj_kind = -1;
+ }
+ for (int i = 0; i < 44; i++) {
+ if (jj_la1[i] == jj_gen) {
+ for (int j = 0; j < 32; j++) {
+ if ((jj_la1_0[i] & (1<<j)) != 0) {
+ la1tokens[j] = true;
+ }
+ if ((jj_la1_1[i] & (1<<j)) != 0) {
+ la1tokens[32+j] = true;
+ }
+ if ((jj_la1_2[i] & (1<<j)) != 0) {
+ la1tokens[64+j] = true;
+ }
+ if ((jj_la1_3[i] & (1<<j)) != 0) {
+ la1tokens[96+j] = true;
+ }
+ }
+ }
+ }
+ for (int i = 0; i < 116; i++) {
+ if (la1tokens[i]) {
+ jj_expentry = new int[1];
+ jj_expentry[0] = i;
+ jj_expentries.addElement(jj_expentry);
+ }
+ }
+ jj_endpos = 0;
+ jj_rescan_token();
+ jj_add_error_token(0, 0);
+ int[][] exptokseq = new int[jj_expentries.size()][];
+ for (int i = 0; i < jj_expentries.size(); i++) {
+ exptokseq[i] = (int[])jj_expentries.elementAt(i);
+ }
+ return new ParseException(token, exptokseq, tokenImage);
+ }
+
+ final public void enable_tracing() {
+ }
+
+ final public void disable_tracing() {
+ }
+
+ final private void jj_rescan_token() {
+ jj_rescan = true;
+ for (int i = 0; i < 9; i++) {
+ JJExpressionParserCalls p = jj_2_rtns[i];
+ do {
+ if (p.gen > jj_gen) {
+ jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
+ switch (i) {
+ case 0: jj_3_1(); break;
+ case 1: jj_3_2(); break;
+ case 2: jj_3_3(); break;
+ case 3: jj_3_4(); break;
+ case 4: jj_3_5(); break;
+ case 5: jj_3_6(); break;
+ case 6: jj_3_7(); break;
+ case 7: jj_3_8(); break;
+ case 8: jj_3_9(); break;
+ }
+ }
+ p = p.next;
+ } while (p != null);
+ }
+ jj_rescan = false;
+ }
+
+ final private void jj_save(int index, int xla) {
+ JJExpressionParserCalls p = jj_2_rtns[index];
+ while (p.gen > jj_gen) {
+ if (p.next == null) { p = p.next = new JJExpressionParserCalls(); break; }
+ p = p.next;
+ }
+ p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
+ }
+
+}
+
+final class JJExpressionParserCalls {
+ int gen;
+ Token first;
+ int arg;
+ JJExpressionParserCalls next;
+}
Index: xemacs-packages/jde/java/src/jde/debugger/expr/ExpressionParserConstants.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/expr/ExpressionParserConstants.java,v
retrieving revision 1.1
diff -u -r1.1 ExpressionParserConstants.java
---
xemacs-packages/jde/java/src/jde/debugger/expr/ExpressionParserConstants.java 2000/08/13
13:36:58 1.1
+++
xemacs-packages/jde/java/src/jde/debugger/expr/ExpressionParserConstants.java 2001/08/15
05:27:49
@@ -1,239 +1,239 @@
-/* Generated By:JavaCC: Do not edit this line. ExpressionParserConstants.java */
-package jde.debugger.expr;
-
-public interface ExpressionParserConstants {
-
- int EOF = 0;
- int SINGLE_LINE_COMMENT = 6;
- int FORMAL_COMMENT = 7;
- int MULTI_LINE_COMMENT = 8;
- int ABSTRACT = 9;
- int BOOLEAN = 10;
- int BREAK = 11;
- int BYTE = 12;
- int CASE = 13;
- int CATCH = 14;
- int CHAR = 15;
- int CLASS = 16;
- int CONST = 17;
- int CONTINUE = 18;
- int _DEFAULT = 19;
- int DO = 20;
- int DOUBLE = 21;
- int ELSE = 22;
- int EXTENDS = 23;
- int FALSE = 24;
- int FINAL = 25;
- int FINALLY = 26;
- int FLOAT = 27;
- int FOR = 28;
- int GOTO = 29;
- int IF = 30;
- int IMPLEMENTS = 31;
- int IMPORT = 32;
- int INSTANCEOF = 33;
- int INT = 34;
- int INTERFACE = 35;
- int LONG = 36;
- int NATIVE = 37;
- int NEW = 38;
- int NULL = 39;
- int PACKAGE = 40;
- int PRIVATE = 41;
- int PROTECTED = 42;
- int PUBLIC = 43;
- int RETURN = 44;
- int SHORT = 45;
- int STATIC = 46;
- int SUPER = 47;
- int SWITCH = 48;
- int SYNCHRONIZED = 49;
- int THIS = 50;
- int THROW = 51;
- int THROWS = 52;
- int TRANSIENT = 53;
- int TRUE = 54;
- int TRY = 55;
- int VOID = 56;
- int VOLATILE = 57;
- int WHILE = 58;
- int INTEGER_LITERAL = 59;
- int DECIMAL_LITERAL = 60;
- int HEX_LITERAL = 61;
- int OCTAL_LITERAL = 62;
- int FLOATING_POINT_LITERAL = 63;
- int EXPONENT = 64;
- int CHARACTER_LITERAL = 65;
- int STRING_LITERAL = 66;
- int IDENTIFIER = 67;
- int LETTER = 68;
- int DIGIT = 69;
- int LPAREN = 70;
- int RPAREN = 71;
- int LBRACE = 72;
- int RBRACE = 73;
- int LBRACKET = 74;
- int RBRACKET = 75;
- int SEMICOLON = 76;
- int COMMA = 77;
- int DOT = 78;
- int ASSIGN = 79;
- int GT = 80;
- int LT = 81;
- int BANG = 82;
- int TILDE = 83;
- int HOOK = 84;
- int COLON = 85;
- int EQ = 86;
- int LE = 87;
- int GE = 88;
- int NE = 89;
- int SC_OR = 90;
- int SC_AND = 91;
- int INCR = 92;
- int DECR = 93;
- int PLUS = 94;
- int MINUS = 95;
- int STAR = 96;
- int SLASH = 97;
- int BIT_AND = 98;
- int BIT_OR = 99;
- int XOR = 100;
- int REM = 101;
- int LSHIFT = 102;
- int RSIGNEDSHIFT = 103;
- int RUNSIGNEDSHIFT = 104;
- int PLUSASSIGN = 105;
- int MINUSASSIGN = 106;
- int STARASSIGN = 107;
- int SLASHASSIGN = 108;
- int ANDASSIGN = 109;
- int ORASSIGN = 110;
- int XORASSIGN = 111;
- int REMASSIGN = 112;
- int LSHIFTASSIGN = 113;
- int RSIGNEDSHIFTASSIGN = 114;
- int RUNSIGNEDSHIFTASSIGN = 115;
-
- int DEFAULT = 0;
-
- String[] tokenImage = {
- "<EOF>",
- "\" \"",
- "\"\\t\"",
- "\"\\n\"",
- "\"\\r\"",
- "\"\\f\"",
- "<SINGLE_LINE_COMMENT>",
- "<FORMAL_COMMENT>",
- "<MULTI_LINE_COMMENT>",
- "\"abstract\"",
- "\"boolean\"",
- "\"break\"",
- "\"byte\"",
- "\"case\"",
- "\"catch\"",
- "\"char\"",
- "\"class\"",
- "\"const\"",
- "\"continue\"",
- "\"default\"",
- "\"do\"",
- "\"double\"",
- "\"else\"",
- "\"extends\"",
- "\"false\"",
- "\"final\"",
- "\"finally\"",
- "\"float\"",
- "\"for\"",
- "\"goto\"",
- "\"if\"",
- "\"implements\"",
- "\"import\"",
- "\"instanceof\"",
- "\"int\"",
- "\"interface\"",
- "\"long\"",
- "\"native\"",
- "\"new\"",
- "\"null\"",
- "\"package\"",
- "\"private\"",
- "\"protected\"",
- "\"public\"",
- "\"return\"",
- "\"short\"",
- "\"static\"",
- "\"super\"",
- "\"switch\"",
- "\"synchronized\"",
- "\"this\"",
- "\"throw\"",
- "\"throws\"",
- "\"transient\"",
- "\"true\"",
- "\"try\"",
- "\"void\"",
- "\"volatile\"",
- "\"while\"",
- "<INTEGER_LITERAL>",
- "<DECIMAL_LITERAL>",
- "<HEX_LITERAL>",
- "<OCTAL_LITERAL>",
- "<FLOATING_POINT_LITERAL>",
- "<EXPONENT>",
- "<CHARACTER_LITERAL>",
- "<STRING_LITERAL>",
- "<IDENTIFIER>",
- "<LETTER>",
- "<DIGIT>",
- "\"(\"",
- "\")\"",
- "\"{\"",
- "\"}\"",
- "\"[\"",
- "\"]\"",
- "\";\"",
- "\",\"",
- "\".\"",
- "\"=\"",
- "\">\"",
- "\"<\"",
- "\"!\"",
- "\"~\"",
- "\"?\"",
- "\":\"",
- "\"==\"",
- "\"<=\"",
- "\">=\"",
- "\"!=\"",
- "\"||\"",
- "\"&&\"",
- "\"++\"",
- "\"--\"",
- "\"+\"",
- "\"-\"",
- "\"*\"",
- "\"/\"",
- "\"&\"",
- "\"|\"",
- "\"^\"",
- "\"%\"",
- "\"<<\"",
- "\">>\"",
- "\">>>\"",
- "\"+=\"",
- "\"-=\"",
- "\"*=\"",
- "\"/=\"",
- "\"&=\"",
- "\"|=\"",
- "\"^=\"",
- "\"%=\"",
- "\"<<=\"",
- "\">>=\"",
- "\">>>=\"",
- };
-
-}
+/* Generated By:JavaCC: Do not edit this line. ExpressionParserConstants.java */
+package jde.debugger.expr;
+
+public interface ExpressionParserConstants {
+
+ int EOF = 0;
+ int SINGLE_LINE_COMMENT = 6;
+ int FORMAL_COMMENT = 7;
+ int MULTI_LINE_COMMENT = 8;
+ int ABSTRACT = 9;
+ int BOOLEAN = 10;
+ int BREAK = 11;
+ int BYTE = 12;
+ int CASE = 13;
+ int CATCH = 14;
+ int CHAR = 15;
+ int CLASS = 16;
+ int CONST = 17;
+ int CONTINUE = 18;
+ int _DEFAULT = 19;
+ int DO = 20;
+ int DOUBLE = 21;
+ int ELSE = 22;
+ int EXTENDS = 23;
+ int FALSE = 24;
+ int FINAL = 25;
+ int FINALLY = 26;
+ int FLOAT = 27;
+ int FOR = 28;
+ int GOTO = 29;
+ int IF = 30;
+ int IMPLEMENTS = 31;
+ int IMPORT = 32;
+ int INSTANCEOF = 33;
+ int INT = 34;
+ int INTERFACE = 35;
+ int LONG = 36;
+ int NATIVE = 37;
+ int NEW = 38;
+ int NULL = 39;
+ int PACKAGE = 40;
+ int PRIVATE = 41;
+ int PROTECTED = 42;
+ int PUBLIC = 43;
+ int RETURN = 44;
+ int SHORT = 45;
+ int STATIC = 46;
+ int SUPER = 47;
+ int SWITCH = 48;
+ int SYNCHRONIZED = 49;
+ int THIS = 50;
+ int THROW = 51;
+ int THROWS = 52;
+ int TRANSIENT = 53;
+ int TRUE = 54;
+ int TRY = 55;
+ int VOID = 56;
+ int VOLATILE = 57;
+ int WHILE = 58;
+ int INTEGER_LITERAL = 59;
+ int DECIMAL_LITERAL = 60;
+ int HEX_LITERAL = 61;
+ int OCTAL_LITERAL = 62;
+ int FLOATING_POINT_LITERAL = 63;
+ int EXPONENT = 64;
+ int CHARACTER_LITERAL = 65;
+ int STRING_LITERAL = 66;
+ int IDENTIFIER = 67;
+ int LETTER = 68;
+ int DIGIT = 69;
+ int LPAREN = 70;
+ int RPAREN = 71;
+ int LBRACE = 72;
+ int RBRACE = 73;
+ int LBRACKET = 74;
+ int RBRACKET = 75;
+ int SEMICOLON = 76;
+ int COMMA = 77;
+ int DOT = 78;
+ int ASSIGN = 79;
+ int GT = 80;
+ int LT = 81;
+ int BANG = 82;
+ int TILDE = 83;
+ int HOOK = 84;
+ int COLON = 85;
+ int EQ = 86;
+ int LE = 87;
+ int GE = 88;
+ int NE = 89;
+ int SC_OR = 90;
+ int SC_AND = 91;
+ int INCR = 92;
+ int DECR = 93;
+ int PLUS = 94;
+ int MINUS = 95;
+ int STAR = 96;
+ int SLASH = 97;
+ int BIT_AND = 98;
+ int BIT_OR = 99;
+ int XOR = 100;
+ int REM = 101;
+ int LSHIFT = 102;
+ int RSIGNEDSHIFT = 103;
+ int RUNSIGNEDSHIFT = 104;
+ int PLUSASSIGN = 105;
+ int MINUSASSIGN = 106;
+ int STARASSIGN = 107;
+ int SLASHASSIGN = 108;
+ int ANDASSIGN = 109;
+ int ORASSIGN = 110;
+ int XORASSIGN = 111;
+ int REMASSIGN = 112;
+ int LSHIFTASSIGN = 113;
+ int RSIGNEDSHIFTASSIGN = 114;
+ int RUNSIGNEDSHIFTASSIGN = 115;
+
+ int DEFAULT = 0;
+
+ String[] tokenImage = {
+ "<EOF>",
+ "\" \"",
+ "\"\\t\"",
+ "\"\\n\"",
+ "\"\\r\"",
+ "\"\\f\"",
+ "<SINGLE_LINE_COMMENT>",
+ "<FORMAL_COMMENT>",
+ "<MULTI_LINE_COMMENT>",
+ "\"abstract\"",
+ "\"boolean\"",
+ "\"break\"",
+ "\"byte\"",
+ "\"case\"",
+ "\"catch\"",
+ "\"char\"",
+ "\"class\"",
+ "\"const\"",
+ "\"continue\"",
+ "\"default\"",
+ "\"do\"",
+ "\"double\"",
+ "\"else\"",
+ "\"extends\"",
+ "\"false\"",
+ "\"final\"",
+ "\"finally\"",
+ "\"float\"",
+ "\"for\"",
+ "\"goto\"",
+ "\"if\"",
+ "\"implements\"",
+ "\"import\"",
+ "\"instanceof\"",
+ "\"int\"",
+ "\"interface\"",
+ "\"long\"",
+ "\"native\"",
+ "\"new\"",
+ "\"null\"",
+ "\"package\"",
+ "\"private\"",
+ "\"protected\"",
+ "\"public\"",
+ "\"return\"",
+ "\"short\"",
+ "\"static\"",
+ "\"super\"",
+ "\"switch\"",
+ "\"synchronized\"",
+ "\"this\"",
+ "\"throw\"",
+ "\"throws\"",
+ "\"transient\"",
+ "\"true\"",
+ "\"try\"",
+ "\"void\"",
+ "\"volatile\"",
+ "\"while\"",
+ "<INTEGER_LITERAL>",
+ "<DECIMAL_LITERAL>",
+ "<HEX_LITERAL>",
+ "<OCTAL_LITERAL>",
+ "<FLOATING_POINT_LITERAL>",
+ "<EXPONENT>",
+ "<CHARACTER_LITERAL>",
+ "<STRING_LITERAL>",
+ "<IDENTIFIER>",
+ "<LETTER>",
+ "<DIGIT>",
+ "\"(\"",
+ "\")\"",
+ "\"{\"",
+ "\"}\"",
+ "\"[\"",
+ "\"]\"",
+ "\";\"",
+ "\",\"",
+ "\".\"",
+ "\"=\"",
+ "\">\"",
+ "\"<\"",
+ "\"!\"",
+ "\"~\"",
+ "\"?\"",
+ "\":\"",
+ "\"==\"",
+ "\"<=\"",
+ "\">=\"",
+ "\"!=\"",
+ "\"||\"",
+ "\"&&\"",
+ "\"++\"",
+ "\"--\"",
+ "\"+\"",
+ "\"-\"",
+ "\"*\"",
+ "\"/\"",
+ "\"&\"",
+ "\"|\"",
+ "\"^\"",
+ "\"%\"",
+ "\"<<\"",
+ "\">>\"",
+ "\">>>\"",
+ "\"+=\"",
+ "\"-=\"",
+ "\"*=\"",
+ "\"/=\"",
+ "\"&=\"",
+ "\"|=\"",
+ "\"^=\"",
+ "\"%=\"",
+ "\"<<=\"",
+ "\">>=\"",
+ "\">>>=\"",
+ };
+
+}
Index: xemacs-packages/jde/java/src/jde/debugger/expr/ExpressionParserTokenManager.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/expr/ExpressionParserTokenManager.java,v
retrieving revision 1.1
diff -u -r1.1 ExpressionParserTokenManager.java
---
xemacs-packages/jde/java/src/jde/debugger/expr/ExpressionParserTokenManager.java 2000/08/13
13:36:58 1.1
+++
xemacs-packages/jde/java/src/jde/debugger/expr/ExpressionParserTokenManager.java 2001/08/15
05:27:49
@@ -1,1562 +1,1562 @@
-/* Generated By:JavaCC: Do not edit this line. ExpressionParserTokenManager.java */
-package jde.debugger.expr;
-import com.sun.jdi.*;
-import java.util.Stack;
-import java.util.List;
-import java.util.ArrayList;
-
-public class ExpressionParserTokenManager implements ExpressionParserConstants
-{
-private final int jjStopStringLiteralDfa_0(int pos, long active0, long active1)
-{
- switch (pos)
- {
- case 0:
- if ((active1 & 0x4000L) != 0L)
- return 4;
- if ((active0 & 0x7fffffffffffe00L) != 0L)
- {
- jjmatchedKind = 67;
- return 28;
- }
- if ((active1 & 0x100200000000L) != 0L)
- return 49;
- return -1;
- case 1:
- if ((active0 & 0x7ffffffbfcffe00L) != 0L)
- {
- if (jjmatchedPos != 1)
- {
- jjmatchedKind = 67;
- jjmatchedPos = 1;
- }
- return 28;
- }
- if ((active0 & 0x40300000L) != 0L)
- return 28;
- return -1;
- case 2:
- if ((active0 & 0x77fffb3afeffe00L) != 0L)
- {
- if (jjmatchedPos != 2)
- {
- jjmatchedKind = 67;
- jjmatchedPos = 2;
- }
- return 28;
- }
- if ((active0 & 0x80004c10000000L) != 0L)
- return 28;
- return -1;
- case 3:
- if ((active0 & 0x63bff2b8faf4e00L) != 0L)
- {
- jjmatchedKind = 67;
- jjmatchedPos = 3;
- return 28;
- }
- if ((active0 & 0x14400902040b000L) != 0L)
- return 28;
- return -1;
- case 4:
- if ((active0 & 0x2235f2b80ac0600L) != 0L)
- {
- if (jjmatchedPos != 4)
- {
- jjmatchedKind = 67;
- jjmatchedPos = 4;
- }
- return 28;
- }
- if ((active0 & 0x418a0000f034800L) != 0L)
- return 28;
- return -1;
- case 5:
- if ((active0 & 0x222070a848c0600L) != 0L)
- {
- jjmatchedKind = 67;
- jjmatchedPos = 5;
- return 28;
- }
- if ((active0 & 0x11582100200000L) != 0L)
- return 28;
- return -1;
- case 6:
- if ((active0 & 0x222040a80040200L) != 0L)
- {
- jjmatchedKind = 67;
- jjmatchedPos = 6;
- return 28;
- }
- if ((active0 & 0x30004880400L) != 0L)
- return 28;
- return -1;
- case 7:
- if ((active0 & 0x22040a80000000L) != 0L)
- {
- jjmatchedKind = 67;
- jjmatchedPos = 7;
- return 28;
- }
- if ((active0 & 0x200000000040200L) != 0L)
- return 28;
- return -1;
- case 8:
- if ((active0 & 0x2000280000000L) != 0L)
- {
- jjmatchedKind = 67;
- jjmatchedPos = 8;
- return 28;
- }
- if ((active0 & 0x20040800000000L) != 0L)
- return 28;
- return -1;
- case 9:
- if ((active0 & 0x2000000000000L) != 0L)
- {
- jjmatchedKind = 67;
- jjmatchedPos = 9;
- return 28;
- }
- if ((active0 & 0x280000000L) != 0L)
- return 28;
- return -1;
- case 10:
- if ((active0 & 0x2000000000000L) != 0L)
- {
- jjmatchedKind = 67;
- jjmatchedPos = 10;
- return 28;
- }
- return -1;
- default :
- return -1;
- }
-}
-private final int jjStartNfa_0(int pos, long active0, long active1)
-{
- return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0, active1), pos + 1);
-}
-private final int jjStopAtPos(int pos, int kind)
-{
- jjmatchedKind = kind;
- jjmatchedPos = pos;
- return pos + 1;
-}
-private final int jjStartNfaWithStates_0(int pos, int kind, int state)
-{
- jjmatchedKind = kind;
- jjmatchedPos = pos;
- try { curChar = input_stream.readChar(); }
- catch(java.io.IOException e) { return pos + 1; }
- return jjMoveNfa_0(state, pos + 1);
-}
-private final int jjMoveStringLiteralDfa0_0()
-{
- switch(curChar)
- {
- case 33:
- jjmatchedKind = 82;
- return jjMoveStringLiteralDfa1_0(0x0L, 0x2000000L);
- case 37:
- jjmatchedKind = 101;
- return jjMoveStringLiteralDfa1_0(0x0L, 0x1000000000000L);
- case 38:
- jjmatchedKind = 98;
- return jjMoveStringLiteralDfa1_0(0x0L, 0x200008000000L);
- case 40:
- return jjStopAtPos(0, 70);
- case 41:
- return jjStopAtPos(0, 71);
- case 42:
- jjmatchedKind = 96;
- return jjMoveStringLiteralDfa1_0(0x0L, 0x80000000000L);
- case 43:
- jjmatchedKind = 94;
- return jjMoveStringLiteralDfa1_0(0x0L, 0x20010000000L);
- case 44:
- return jjStopAtPos(0, 77);
- case 45:
- jjmatchedKind = 95;
- return jjMoveStringLiteralDfa1_0(0x0L, 0x40020000000L);
- case 46:
- return jjStartNfaWithStates_0(0, 78, 4);
- case 47:
- jjmatchedKind = 97;
- return jjMoveStringLiteralDfa1_0(0x0L, 0x100000000000L);
- case 58:
- return jjStopAtPos(0, 85);
- case 59:
- return jjStopAtPos(0, 76);
- case 60:
- jjmatchedKind = 81;
- return jjMoveStringLiteralDfa1_0(0x0L, 0x2004000800000L);
- case 61:
- jjmatchedKind = 79;
- return jjMoveStringLiteralDfa1_0(0x0L, 0x400000L);
- case 62:
- jjmatchedKind = 80;
- return jjMoveStringLiteralDfa1_0(0x0L, 0xc018001000000L);
- case 63:
- return jjStopAtPos(0, 84);
- case 91:
- return jjStopAtPos(0, 74);
- case 93:
- return jjStopAtPos(0, 75);
- case 94:
- jjmatchedKind = 100;
- return jjMoveStringLiteralDfa1_0(0x0L, 0x800000000000L);
- case 97:
- return jjMoveStringLiteralDfa1_0(0x200L, 0x0L);
- case 98:
- return jjMoveStringLiteralDfa1_0(0x1c00L, 0x0L);
- case 99:
- return jjMoveStringLiteralDfa1_0(0x7e000L, 0x0L);
- case 100:
- return jjMoveStringLiteralDfa1_0(0x380000L, 0x0L);
- case 101:
- return jjMoveStringLiteralDfa1_0(0xc00000L, 0x0L);
- case 102:
- return jjMoveStringLiteralDfa1_0(0x1f000000L, 0x0L);
- case 103:
- return jjMoveStringLiteralDfa1_0(0x20000000L, 0x0L);
- case 105:
- return jjMoveStringLiteralDfa1_0(0xfc0000000L, 0x0L);
- case 108:
- return jjMoveStringLiteralDfa1_0(0x1000000000L, 0x0L);
- case 110:
- return jjMoveStringLiteralDfa1_0(0xe000000000L, 0x0L);
- case 112:
- return jjMoveStringLiteralDfa1_0(0xf0000000000L, 0x0L);
- case 114:
- return jjMoveStringLiteralDfa1_0(0x100000000000L, 0x0L);
- case 115:
- return jjMoveStringLiteralDfa1_0(0x3e00000000000L, 0x0L);
- case 116:
- return jjMoveStringLiteralDfa1_0(0xfc000000000000L, 0x0L);
- case 118:
- return jjMoveStringLiteralDfa1_0(0x300000000000000L, 0x0L);
- case 119:
- return jjMoveStringLiteralDfa1_0(0x400000000000000L, 0x0L);
- case 123:
- return jjStopAtPos(0, 72);
- case 124:
- jjmatchedKind = 99;
- return jjMoveStringLiteralDfa1_0(0x0L, 0x400004000000L);
- case 125:
- return jjStopAtPos(0, 73);
- case 126:
- return jjStopAtPos(0, 83);
- default :
- return jjMoveNfa_0(0, 0);
- }
-}
-private final int jjMoveStringLiteralDfa1_0(long active0, long active1)
-{
- try { curChar = input_stream.readChar(); }
- catch(java.io.IOException e) {
- jjStopStringLiteralDfa_0(0, active0, active1);
- return 1;
- }
- switch(curChar)
- {
- case 38:
- if ((active1 & 0x8000000L) != 0L)
- return jjStopAtPos(1, 91);
- break;
- case 43:
- if ((active1 & 0x10000000L) != 0L)
- return jjStopAtPos(1, 92);
- break;
- case 45:
- if ((active1 & 0x20000000L) != 0L)
- return jjStopAtPos(1, 93);
- break;
- case 60:
- if ((active1 & 0x4000000000L) != 0L)
- {
- jjmatchedKind = 102;
- jjmatchedPos = 1;
- }
- return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x2000000000000L);
- case 61:
- if ((active1 & 0x400000L) != 0L)
- return jjStopAtPos(1, 86);
- else if ((active1 & 0x800000L) != 0L)
- return jjStopAtPos(1, 87);
- else if ((active1 & 0x1000000L) != 0L)
- return jjStopAtPos(1, 88);
- else if ((active1 & 0x2000000L) != 0L)
- return jjStopAtPos(1, 89);
- else if ((active1 & 0x20000000000L) != 0L)
- return jjStopAtPos(1, 105);
- else if ((active1 & 0x40000000000L) != 0L)
- return jjStopAtPos(1, 106);
- else if ((active1 & 0x80000000000L) != 0L)
- return jjStopAtPos(1, 107);
- else if ((active1 & 0x100000000000L) != 0L)
- return jjStopAtPos(1, 108);
- else if ((active1 & 0x200000000000L) != 0L)
- return jjStopAtPos(1, 109);
- else if ((active1 & 0x400000000000L) != 0L)
- return jjStopAtPos(1, 110);
- else if ((active1 & 0x800000000000L) != 0L)
- return jjStopAtPos(1, 111);
- else if ((active1 & 0x1000000000000L) != 0L)
- return jjStopAtPos(1, 112);
- break;
- case 62:
- if ((active1 & 0x8000000000L) != 0L)
- {
- jjmatchedKind = 103;
- jjmatchedPos = 1;
- }
- return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0xc010000000000L);
- case 97:
- return jjMoveStringLiteralDfa2_0(active0, 0x12001006000L, active1, 0L);
- case 98:
- return jjMoveStringLiteralDfa2_0(active0, 0x200L, active1, 0L);
- case 101:
- return jjMoveStringLiteralDfa2_0(active0, 0x104000080000L, active1, 0L);
- case 102:
- if ((active0 & 0x40000000L) != 0L)
- return jjStartNfaWithStates_0(1, 30, 28);
- break;
- case 104:
- return jjMoveStringLiteralDfa2_0(active0, 0x41c200000008000L, active1, 0L);
- case 105:
- return jjMoveStringLiteralDfa2_0(active0, 0x6000000L, active1, 0L);
- case 108:
- return jjMoveStringLiteralDfa2_0(active0, 0x8410000L, active1, 0L);
- case 109:
- return jjMoveStringLiteralDfa2_0(active0, 0x180000000L, active1, 0L);
- case 110:
- return jjMoveStringLiteralDfa2_0(active0, 0xe00000000L, active1, 0L);
- case 111:
- if ((active0 & 0x100000L) != 0L)
- {
- jjmatchedKind = 20;
- jjmatchedPos = 1;
- }
- return jjMoveStringLiteralDfa2_0(active0, 0x300001030260400L, active1, 0L);
- case 114:
- return jjMoveStringLiteralDfa2_0(active0, 0xe0060000000800L, active1, 0L);
- case 116:
- return jjMoveStringLiteralDfa2_0(active0, 0x400000000000L, active1, 0L);
- case 117:
- return jjMoveStringLiteralDfa2_0(active0, 0x888000000000L, active1, 0L);
- case 119:
- return jjMoveStringLiteralDfa2_0(active0, 0x1000000000000L, active1, 0L);
- case 120:
- return jjMoveStringLiteralDfa2_0(active0, 0x800000L, active1, 0L);
- case 121:
- return jjMoveStringLiteralDfa2_0(active0, 0x2000000001000L, active1, 0L);
- case 124:
- if ((active1 & 0x4000000L) != 0L)
- return jjStopAtPos(1, 90);
- break;
- default :
- break;
- }
- return jjStartNfa_0(0, active0, active1);
-}
-private final int jjMoveStringLiteralDfa2_0(long old0, long active0, long old1, long
active1)
-{
- if (((active0 &= old0) | (active1 &= old1)) == 0L)
- return jjStartNfa_0(0, old0, old1);
- try { curChar = input_stream.readChar(); }
- catch(java.io.IOException e) {
- jjStopStringLiteralDfa_0(1, active0, active1);
- return 2;
- }
- switch(curChar)
- {
- case 61:
- if ((active1 & 0x2000000000000L) != 0L)
- return jjStopAtPos(2, 113);
- else if ((active1 & 0x4000000000000L) != 0L)
- return jjStopAtPos(2, 114);
- break;
- case 62:
- if ((active1 & 0x10000000000L) != 0L)
- {
- jjmatchedKind = 104;
- jjmatchedPos = 2;
- }
- return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0x8000000000000L);
- case 97:
- return jjMoveStringLiteralDfa3_0(active0, 0x20400000018000L, active1, 0L);
- case 98:
- return jjMoveStringLiteralDfa3_0(active0, 0x80000000000L, active1, 0L);
- case 99:
- return jjMoveStringLiteralDfa3_0(active0, 0x10000000000L, active1, 0L);
- case 101:
- return jjMoveStringLiteralDfa3_0(active0, 0x800L, active1, 0L);
- case 102:
- return jjMoveStringLiteralDfa3_0(active0, 0x80000L, active1, 0L);
- case 105:
- return jjMoveStringLiteralDfa3_0(active0, 0x505020000000000L, active1, 0L);
- case 108:
- return jjMoveStringLiteralDfa3_0(active0, 0x200008001000000L, active1, 0L);
- case 110:
- return jjMoveStringLiteralDfa3_0(active0, 0x2001006060000L, active1, 0L);
- case 111:
- return jjMoveStringLiteralDfa3_0(active0, 0x240008000400L, active1, 0L);
- case 112:
- return jjMoveStringLiteralDfa3_0(active0, 0x800180000000L, active1, 0L);
- case 114:
- if ((active0 & 0x10000000L) != 0L)
- return jjStartNfaWithStates_0(2, 28, 28);
- return jjMoveStringLiteralDfa3_0(active0, 0x18000000000000L, active1, 0L);
- case 115:
- return jjMoveStringLiteralDfa3_0(active0, 0x200402200L, active1, 0L);
- case 116:
- if ((active0 & 0x400000000L) != 0L)
- {
- jjmatchedKind = 34;
- jjmatchedPos = 2;
- }
- return jjMoveStringLiteralDfa3_0(active0, 0x102820805000L, active1, 0L);
- case 117:
- return jjMoveStringLiteralDfa3_0(active0, 0x40000000200000L, active1, 0L);
- case 119:
- if ((active0 & 0x4000000000L) != 0L)
- return jjStartNfaWithStates_0(2, 38, 28);
- break;
- case 121:
- if ((active0 & 0x80000000000000L) != 0L)
- return jjStartNfaWithStates_0(2, 55, 28);
- break;
- default :
- break;
- }
- return jjStartNfa_0(1, active0, active1);
-}
-private final int jjMoveStringLiteralDfa3_0(long old0, long active0, long old1, long
active1)
-{
- if (((active0 &= old0) | (active1 &= old1)) == 0L)
- return jjStartNfa_0(1, old0, old1);
- try { curChar = input_stream.readChar(); }
- catch(java.io.IOException e) {
- jjStopStringLiteralDfa_0(2, active0, active1);
- return 3;
- }
- switch(curChar)
- {
- case 61:
- if ((active1 & 0x8000000000000L) != 0L)
- return jjStopAtPos(3, 115);
- break;
- case 97:
- return jjMoveStringLiteralDfa4_0(active0, 0x20000000e080800L, active1, 0L);
- case 98:
- return jjMoveStringLiteralDfa4_0(active0, 0x200000L, active1, 0L);
- case 99:
- return jjMoveStringLiteralDfa4_0(active0, 0x2000000004000L, active1, 0L);
- case 100:
- if ((active0 & 0x100000000000000L) != 0L)
- return jjStartNfaWithStates_0(3, 56, 28);
- break;
- case 101:
- if ((active0 & 0x1000L) != 0L)
- return jjStartNfaWithStates_0(3, 12, 28);
- else if ((active0 & 0x2000L) != 0L)
- return jjStartNfaWithStates_0(3, 13, 28);
- else if ((active0 & 0x400000L) != 0L)
- return jjStartNfaWithStates_0(3, 22, 28);
- else if ((active0 & 0x40000000000000L) != 0L)
- return jjStartNfaWithStates_0(3, 54, 28);
- return jjMoveStringLiteralDfa4_0(active0, 0x800800800000L, active1, 0L);
- case 103:
- if ((active0 & 0x1000000000L) != 0L)
- return jjStartNfaWithStates_0(3, 36, 28);
- break;
- case 105:
- return jjMoveStringLiteralDfa4_0(active0, 0x2000000000L, active1, 0L);
- case 107:
- return jjMoveStringLiteralDfa4_0(active0, 0x10000000000L, active1, 0L);
- case 108:
- if ((active0 & 0x8000000000L) != 0L)
- return jjStartNfaWithStates_0(3, 39, 28);
- return jjMoveStringLiteralDfa4_0(active0, 0x400080080000400L, active1, 0L);
- case 110:
- return jjMoveStringLiteralDfa4_0(active0, 0x20000000000000L, active1, 0L);
- case 111:
- if ((active0 & 0x20000000L) != 0L)
- return jjStartNfaWithStates_0(3, 29, 28);
- return jjMoveStringLiteralDfa4_0(active0, 0x18000100000000L, active1, 0L);
- case 114:
- if ((active0 & 0x8000L) != 0L)
- return jjStartNfaWithStates_0(3, 15, 28);
- return jjMoveStringLiteralDfa4_0(active0, 0x200000000000L, active1, 0L);
- case 115:
- if ((active0 & 0x4000000000000L) != 0L)
- return jjStartNfaWithStates_0(3, 50, 28);
- return jjMoveStringLiteralDfa4_0(active0, 0x1030000L, active1, 0L);
- case 116:
- return jjMoveStringLiteralDfa4_0(active0, 0x1440200040200L, active1, 0L);
- case 117:
- return jjMoveStringLiteralDfa4_0(active0, 0x100000000000L, active1, 0L);
- case 118:
- return jjMoveStringLiteralDfa4_0(active0, 0x20000000000L, active1, 0L);
- default :
- break;
- }
- return jjStartNfa_0(2, active0, active1);
-}
-private final int jjMoveStringLiteralDfa4_0(long old0, long active0, long old1, long
active1)
-{
- if (((active0 &= old0) | (active1 &= old1)) == 0L)
- return jjStartNfa_0(2, old0, old1);
- try { curChar = input_stream.readChar(); }
- catch(java.io.IOException e) {
- jjStopStringLiteralDfa_0(3, active0, 0L);
- return 4;
- }
- switch(curChar)
- {
- case 97:
- return jjMoveStringLiteralDfa5_0(active0, 0x30200000000L);
- case 99:
- return jjMoveStringLiteralDfa5_0(active0, 0x1000000000000L);
- case 101:
- if ((active0 & 0x1000000L) != 0L)
- return jjStartNfaWithStates_0(4, 24, 28);
- else if ((active0 & 0x400000000000000L) != 0L)
- return jjStartNfaWithStates_0(4, 58, 28);
- return jjMoveStringLiteralDfa5_0(active0, 0x40080000400L);
- case 104:
- if ((active0 & 0x4000L) != 0L)
- return jjStartNfaWithStates_0(4, 14, 28);
- return jjMoveStringLiteralDfa5_0(active0, 0x2000000000000L);
- case 105:
- return jjMoveStringLiteralDfa5_0(active0, 0x480000040000L);
- case 107:
- if ((active0 & 0x800L) != 0L)
- return jjStartNfaWithStates_0(4, 11, 28);
- break;
- case 108:
- if ((active0 & 0x2000000L) != 0L)
- {
- jjmatchedKind = 25;
- jjmatchedPos = 4;
- }
- return jjMoveStringLiteralDfa5_0(active0, 0x4200000L);
- case 110:
- return jjMoveStringLiteralDfa5_0(active0, 0x800000L);
- case 114:
- if ((active0 & 0x800000000000L) != 0L)
- return jjStartNfaWithStates_0(4, 47, 28);
- return jjMoveStringLiteralDfa5_0(active0, 0x100900000200L);
- case 115:
- if ((active0 & 0x10000L) != 0L)
- return jjStartNfaWithStates_0(4, 16, 28);
- return jjMoveStringLiteralDfa5_0(active0, 0x20000000000000L);
- case 116:
- if ((active0 & 0x20000L) != 0L)
- return jjStartNfaWithStates_0(4, 17, 28);
- else if ((active0 & 0x8000000L) != 0L)
- return jjStartNfaWithStates_0(4, 27, 28);
- else if ((active0 & 0x200000000000L) != 0L)
- return jjStartNfaWithStates_0(4, 45, 28);
- return jjMoveStringLiteralDfa5_0(active0, 0x200000000000000L);
- case 117:
- return jjMoveStringLiteralDfa5_0(active0, 0x80000L);
- case 118:
- return jjMoveStringLiteralDfa5_0(active0, 0x2000000000L);
- case 119:
- if ((active0 & 0x8000000000000L) != 0L)
- {
- jjmatchedKind = 51;
- jjmatchedPos = 4;
- }
- return jjMoveStringLiteralDfa5_0(active0, 0x10000000000000L);
- default :
- break;
- }
- return jjStartNfa_0(3, active0, 0L);
-}
-private final int jjMoveStringLiteralDfa5_0(long old0, long active0)
-{
- if (((active0 &= old0)) == 0L)
- return jjStartNfa_0(3, old0, 0L);
- try { curChar = input_stream.readChar(); }
- catch(java.io.IOException e) {
- jjStopStringLiteralDfa_0(4, active0, 0L);
- return 5;
- }
- switch(curChar)
- {
- case 97:
- return jjMoveStringLiteralDfa6_0(active0, 0x600L);
- case 99:
- if ((active0 & 0x80000000000L) != 0L)
- return jjStartNfaWithStates_0(5, 43, 28);
- else if ((active0 & 0x400000000000L) != 0L)
- return jjStartNfaWithStates_0(5, 46, 28);
- return jjMoveStringLiteralDfa6_0(active0, 0x40000000000L);
- case 100:
- return jjMoveStringLiteralDfa6_0(active0, 0x800000L);
- case 101:
- if ((active0 & 0x200000L) != 0L)
- return jjStartNfaWithStates_0(5, 21, 28);
- else if ((active0 & 0x2000000000L) != 0L)
- return jjStartNfaWithStates_0(5, 37, 28);
- break;
- case 102:
- return jjMoveStringLiteralDfa6_0(active0, 0x800000000L);
- case 103:
- return jjMoveStringLiteralDfa6_0(active0, 0x10000000000L);
- case 104:
- if ((active0 & 0x1000000000000L) != 0L)
- return jjStartNfaWithStates_0(5, 48, 28);
- break;
- case 105:
- return jjMoveStringLiteralDfa6_0(active0, 0x220000000000000L);
- case 108:
- return jjMoveStringLiteralDfa6_0(active0, 0x4080000L);
- case 109:
- return jjMoveStringLiteralDfa6_0(active0, 0x80000000L);
- case 110:
- if ((active0 & 0x100000000000L) != 0L)
- return jjStartNfaWithStates_0(5, 44, 28);
- return jjMoveStringLiteralDfa6_0(active0, 0x200040000L);
- case 114:
- return jjMoveStringLiteralDfa6_0(active0, 0x2000000000000L);
- case 115:
- if ((active0 & 0x10000000000000L) != 0L)
- return jjStartNfaWithStates_0(5, 52, 28);
- break;
- case 116:
- if ((active0 & 0x100000000L) != 0L)
- return jjStartNfaWithStates_0(5, 32, 28);
- return jjMoveStringLiteralDfa6_0(active0, 0x20000000000L);
- default :
- break;
- }
- return jjStartNfa_0(4, active0, 0L);
-}
-private final int jjMoveStringLiteralDfa6_0(long old0, long active0)
-{
- if (((active0 &= old0)) == 0L)
- return jjStartNfa_0(4, old0, 0L);
- try { curChar = input_stream.readChar(); }
- catch(java.io.IOException e) {
- jjStopStringLiteralDfa_0(5, active0, 0L);
- return 6;
- }
- switch(curChar)
- {
- case 97:
- return jjMoveStringLiteralDfa7_0(active0, 0x800000000L);
- case 99:
- return jjMoveStringLiteralDfa7_0(active0, 0x200000200L);
- case 101:
- if ((active0 & 0x10000000000L) != 0L)
- return jjStartNfaWithStates_0(6, 40, 28);
- else if ((active0 & 0x20000000000L) != 0L)
- return jjStartNfaWithStates_0(6, 41, 28);
- return jjMoveStringLiteralDfa7_0(active0, 0x20000080000000L);
- case 108:
- return jjMoveStringLiteralDfa7_0(active0, 0x200000000000000L);
- case 110:
- if ((active0 & 0x400L) != 0L)
- return jjStartNfaWithStates_0(6, 10, 28);
- break;
- case 111:
- return jjMoveStringLiteralDfa7_0(active0, 0x2000000000000L);
- case 115:
- if ((active0 & 0x800000L) != 0L)
- return jjStartNfaWithStates_0(6, 23, 28);
- break;
- case 116:
- if ((active0 & 0x80000L) != 0L)
- return jjStartNfaWithStates_0(6, 19, 28);
- return jjMoveStringLiteralDfa7_0(active0, 0x40000000000L);
- case 117:
- return jjMoveStringLiteralDfa7_0(active0, 0x40000L);
- case 121:
- if ((active0 & 0x4000000L) != 0L)
- return jjStartNfaWithStates_0(6, 26, 28);
- break;
- default :
- break;
- }
- return jjStartNfa_0(5, active0, 0L);
-}
-private final int jjMoveStringLiteralDfa7_0(long old0, long active0)
-{
- if (((active0 &= old0)) == 0L)
- return jjStartNfa_0(5, old0, 0L);
- try { curChar = input_stream.readChar(); }
- catch(java.io.IOException e) {
- jjStopStringLiteralDfa_0(6, active0, 0L);
- return 7;
- }
- switch(curChar)
- {
- case 99:
- return jjMoveStringLiteralDfa8_0(active0, 0x800000000L);
- case 101:
- if ((active0 & 0x40000L) != 0L)
- return jjStartNfaWithStates_0(7, 18, 28);
- else if ((active0 & 0x200000000000000L) != 0L)
- return jjStartNfaWithStates_0(7, 57, 28);
- return jjMoveStringLiteralDfa8_0(active0, 0x40200000000L);
- case 110:
- return jjMoveStringLiteralDfa8_0(active0, 0x22000080000000L);
- case 116:
- if ((active0 & 0x200L) != 0L)
- return jjStartNfaWithStates_0(7, 9, 28);
- break;
- default :
- break;
- }
- return jjStartNfa_0(6, active0, 0L);
-}
-private final int jjMoveStringLiteralDfa8_0(long old0, long active0)
-{
- if (((active0 &= old0)) == 0L)
- return jjStartNfa_0(6, old0, 0L);
- try { curChar = input_stream.readChar(); }
- catch(java.io.IOException e) {
- jjStopStringLiteralDfa_0(7, active0, 0L);
- return 8;
- }
- switch(curChar)
- {
- case 100:
- if ((active0 & 0x40000000000L) != 0L)
- return jjStartNfaWithStates_0(8, 42, 28);
- break;
- case 101:
- if ((active0 & 0x800000000L) != 0L)
- return jjStartNfaWithStates_0(8, 35, 28);
- break;
- case 105:
- return jjMoveStringLiteralDfa9_0(active0, 0x2000000000000L);
- case 111:
- return jjMoveStringLiteralDfa9_0(active0, 0x200000000L);
- case 116:
- if ((active0 & 0x20000000000000L) != 0L)
- return jjStartNfaWithStates_0(8, 53, 28);
- return jjMoveStringLiteralDfa9_0(active0, 0x80000000L);
- default :
- break;
- }
- return jjStartNfa_0(7, active0, 0L);
-}
-private final int jjMoveStringLiteralDfa9_0(long old0, long active0)
-{
- if (((active0 &= old0)) == 0L)
- return jjStartNfa_0(7, old0, 0L);
- try { curChar = input_stream.readChar(); }
- catch(java.io.IOException e) {
- jjStopStringLiteralDfa_0(8, active0, 0L);
- return 9;
- }
- switch(curChar)
- {
- case 102:
- if ((active0 & 0x200000000L) != 0L)
- return jjStartNfaWithStates_0(9, 33, 28);
- break;
- case 115:
- if ((active0 & 0x80000000L) != 0L)
- return jjStartNfaWithStates_0(9, 31, 28);
- break;
- case 122:
- return jjMoveStringLiteralDfa10_0(active0, 0x2000000000000L);
- default :
- break;
- }
- return jjStartNfa_0(8, active0, 0L);
-}
-private final int jjMoveStringLiteralDfa10_0(long old0, long active0)
-{
- if (((active0 &= old0)) == 0L)
- return jjStartNfa_0(8, old0, 0L);
- try { curChar = input_stream.readChar(); }
- catch(java.io.IOException e) {
- jjStopStringLiteralDfa_0(9, active0, 0L);
- return 10;
- }
- switch(curChar)
- {
- case 101:
- return jjMoveStringLiteralDfa11_0(active0, 0x2000000000000L);
- default :
- break;
- }
- return jjStartNfa_0(9, active0, 0L);
-}
-private final int jjMoveStringLiteralDfa11_0(long old0, long active0)
-{
- if (((active0 &= old0)) == 0L)
- return jjStartNfa_0(9, old0, 0L);
- try { curChar = input_stream.readChar(); }
- catch(java.io.IOException e) {
- jjStopStringLiteralDfa_0(10, active0, 0L);
- return 11;
- }
- switch(curChar)
- {
- case 100:
- if ((active0 & 0x2000000000000L) != 0L)
- return jjStartNfaWithStates_0(11, 49, 28);
- break;
- default :
- break;
- }
- return jjStartNfa_0(10, active0, 0L);
-}
-private final void jjCheckNAdd(int state)
-{
- if (jjrounds[state] != jjround)
- {
- jjstateSet[jjnewStateCnt++] = state;
- jjrounds[state] = jjround;
- }
-}
-private final void jjAddStates(int start, int end)
-{
- do {
- jjstateSet[jjnewStateCnt++] = jjnextStates[start];
- } while (start++ != end);
-}
-private final void jjCheckNAddTwoStates(int state1, int state2)
-{
- jjCheckNAdd(state1);
- jjCheckNAdd(state2);
-}
-private final void jjCheckNAddStates(int start, int end)
-{
- do {
- jjCheckNAdd(jjnextStates[start]);
- } while (start++ != end);
-}
-private final void jjCheckNAddStates(int start)
-{
- jjCheckNAdd(jjnextStates[start]);
- jjCheckNAdd(jjnextStates[start + 1]);
-}
-static final long[] jjbitVec0 = {
- 0xfffffffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL
-};
-static final long[] jjbitVec2 = {
- 0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
-};
-static final long[] jjbitVec3 = {
- 0x1ff00000fffffffeL, 0xffffffffffffc000L, 0xffffffffL, 0x600000000000000L
-};
-static final long[] jjbitVec4 = {
- 0x0L, 0x0L, 0x0L, 0xff7fffffff7fffffL
-};
-static final long[] jjbitVec5 = {
- 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL
-};
-static final long[] jjbitVec6 = {
- 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffL, 0x0L
-};
-static final long[] jjbitVec7 = {
- 0xffffffffffffffffL, 0xffffffffffffffffL, 0x0L, 0x0L
-};
-static final long[] jjbitVec8 = {
- 0x3fffffffffffL, 0x0L, 0x0L, 0x0L
-};
-private final int jjMoveNfa_0(int startState, int curPos)
-{
- int[] nextStates;
- int startsAt = 0;
- jjnewStateCnt = 67;
- int i = 1;
- jjstateSet[0] = startState;
- int j, kind = 0x7fffffff;
- for (;;)
- {
- if (++jjround == 0x7fffffff)
- ReInitRounds();
- if (curChar < 64)
- {
- long l = 1L << curChar;
- MatchLoop: do
- {
- switch(jjstateSet[--i])
- {
- case 0:
- if ((0x3ff000000000000L & l) != 0L)
- jjCheckNAddStates(0, 6);
- else if (curChar == 47)
- jjAddStates(7, 9);
- else if (curChar == 36)
- {
- if (kind > 67)
- kind = 67;
- jjCheckNAdd(28);
- }
- else if (curChar == 34)
- jjCheckNAddStates(10, 12);
- else if (curChar == 39)
- jjAddStates(13, 14);
- else if (curChar == 46)
- jjCheckNAdd(4);
- if ((0x3fe000000000000L & l) != 0L)
- {
- if (kind > 59)
- kind = 59;
- jjCheckNAddTwoStates(1, 2);
- }
- else if (curChar == 48)
- {
- if (kind > 59)
- kind = 59;
- jjCheckNAddStates(15, 17);
- }
- break;
- case 49:
- if (curChar == 42)
- jjCheckNAddTwoStates(62, 63);
- else if (curChar == 47)
- jjCheckNAddStates(18, 20);
- if (curChar == 42)
- jjstateSet[jjnewStateCnt++] = 54;
- break;
- case 1:
- if ((0x3ff000000000000L & l) == 0L)
- break;
- if (kind > 59)
- kind = 59;
- jjCheckNAddTwoStates(1, 2);
- break;
- case 3:
- if (curChar == 46)
- jjCheckNAdd(4);
- break;
- case 4:
- if ((0x3ff000000000000L & l) == 0L)
- break;
- if (kind > 63)
- kind = 63;
- jjCheckNAddStates(21, 23);
- break;
- case 6:
- if ((0x280000000000L & l) != 0L)
- jjCheckNAdd(7);
- break;
- case 7:
- if ((0x3ff000000000000L & l) == 0L)
- break;
- if (kind > 63)
- kind = 63;
- jjCheckNAddTwoStates(7, 8);
- break;
- case 9:
- if (curChar == 39)
- jjAddStates(13, 14);
- break;
- case 10:
- if ((0xffffff7fffffdbffL & l) != 0L)
- jjCheckNAdd(11);
- break;
- case 11:
- if (curChar == 39 && kind > 65)
- kind = 65;
- break;
- case 13:
- if ((0x8400000000L & l) != 0L)
- jjCheckNAdd(11);
- break;
- case 14:
- if ((0xff000000000000L & l) != 0L)
- jjCheckNAddTwoStates(15, 11);
- break;
- case 15:
- if ((0xff000000000000L & l) != 0L)
- jjCheckNAdd(11);
- break;
- case 16:
- if ((0xf000000000000L & l) != 0L)
- jjstateSet[jjnewStateCnt++] = 17;
- break;
- case 17:
- if ((0xff000000000000L & l) != 0L)
- jjCheckNAdd(15);
- break;
- case 18:
- if (curChar == 34)
- jjCheckNAddStates(10, 12);
- break;
- case 19:
- if ((0xfffffffbffffdbffL & l) != 0L)
- jjCheckNAddStates(10, 12);
- break;
- case 21:
- if ((0x8400000000L & l) != 0L)
- jjCheckNAddStates(10, 12);
- break;
- case 22:
- if (curChar == 34 && kind > 66)
- kind = 66;
- break;
- case 23:
- if ((0xff000000000000L & l) != 0L)
- jjCheckNAddStates(24, 27);
- break;
- case 24:
- if ((0xff000000000000L & l) != 0L)
- jjCheckNAddStates(10, 12);
- break;
- case 25:
- if ((0xf000000000000L & l) != 0L)
- jjstateSet[jjnewStateCnt++] = 26;
- break;
- case 26:
- if ((0xff000000000000L & l) != 0L)
- jjCheckNAdd(24);
- break;
- case 27:
- if (curChar != 36)
- break;
- if (kind > 67)
- kind = 67;
- jjCheckNAdd(28);
- break;
- case 28:
- if ((0x3ff001000000000L & l) == 0L)
- break;
- if (kind > 67)
- kind = 67;
- jjCheckNAdd(28);
- break;
- case 29:
- if ((0x3ff000000000000L & l) != 0L)
- jjCheckNAddStates(0, 6);
- break;
- case 30:
- if ((0x3ff000000000000L & l) != 0L)
- jjCheckNAddTwoStates(30, 31);
- break;
- case 31:
- if (curChar != 46)
- break;
- if (kind > 63)
- kind = 63;
- jjCheckNAddStates(28, 30);
- break;
- case 32:
- if ((0x3ff000000000000L & l) == 0L)
- break;
- if (kind > 63)
- kind = 63;
- jjCheckNAddStates(28, 30);
- break;
- case 34:
- if ((0x280000000000L & l) != 0L)
- jjCheckNAdd(35);
- break;
- case 35:
- if ((0x3ff000000000000L & l) == 0L)
- break;
- if (kind > 63)
- kind = 63;
- jjCheckNAddTwoStates(35, 8);
- break;
- case 36:
- if ((0x3ff000000000000L & l) != 0L)
- jjCheckNAddTwoStates(36, 37);
- break;
- case 38:
- if ((0x280000000000L & l) != 0L)
- jjCheckNAdd(39);
- break;
- case 39:
- if ((0x3ff000000000000L & l) == 0L)
- break;
- if (kind > 63)
- kind = 63;
- jjCheckNAddTwoStates(39, 8);
- break;
- case 40:
- if ((0x3ff000000000000L & l) != 0L)
- jjCheckNAddStates(31, 33);
- break;
- case 42:
- if ((0x280000000000L & l) != 0L)
- jjCheckNAdd(43);
- break;
- case 43:
- if ((0x3ff000000000000L & l) != 0L)
- jjCheckNAddTwoStates(43, 8);
- break;
- case 44:
- if (curChar != 48)
- break;
- if (kind > 59)
- kind = 59;
- jjCheckNAddStates(15, 17);
- break;
- case 46:
- if ((0x3ff000000000000L & l) == 0L)
- break;
- if (kind > 59)
- kind = 59;
- jjCheckNAddTwoStates(46, 2);
- break;
- case 47:
- if ((0xff000000000000L & l) == 0L)
- break;
- if (kind > 59)
- kind = 59;
- jjCheckNAddTwoStates(47, 2);
- break;
- case 48:
- if (curChar == 47)
- jjAddStates(7, 9);
- break;
- case 50:
- if ((0xffffffffffffdbffL & l) != 0L)
- jjCheckNAddStates(18, 20);
- break;
- case 51:
- if ((0x2400L & l) != 0L && kind > 6)
- kind = 6;
- break;
- case 52:
- if (curChar == 10 && kind > 6)
- kind = 6;
- break;
- case 53:
- if (curChar == 13)
- jjstateSet[jjnewStateCnt++] = 52;
- break;
- case 54:
- if (curChar == 42)
- jjCheckNAddTwoStates(55, 56);
- break;
- case 55:
- if ((0xfffffbffffffffffL & l) != 0L)
- jjCheckNAddTwoStates(55, 56);
- break;
- case 56:
- if (curChar == 42)
- jjCheckNAddStates(34, 36);
- break;
- case 57:
- if ((0xffff7bffffffffffL & l) != 0L)
- jjCheckNAddTwoStates(58, 56);
- break;
- case 58:
- if ((0xfffffbffffffffffL & l) != 0L)
- jjCheckNAddTwoStates(58, 56);
- break;
- case 59:
- if (curChar == 47 && kind > 7)
- kind = 7;
- break;
- case 60:
- if (curChar == 42)
- jjstateSet[jjnewStateCnt++] = 54;
- break;
- case 61:
- if (curChar == 42)
- jjCheckNAddTwoStates(62, 63);
- break;
- case 62:
- if ((0xfffffbffffffffffL & l) != 0L)
- jjCheckNAddTwoStates(62, 63);
- break;
- case 63:
- if (curChar == 42)
- jjCheckNAddStates(37, 39);
- break;
- case 64:
- if ((0xffff7bffffffffffL & l) != 0L)
- jjCheckNAddTwoStates(65, 63);
- break;
- case 65:
- if ((0xfffffbffffffffffL & l) != 0L)
- jjCheckNAddTwoStates(65, 63);
- break;
- case 66:
- if (curChar == 47 && kind > 8)
- kind = 8;
- break;
- default : break;
- }
- } while(i != startsAt);
- }
- else if (curChar < 128)
- {
- long l = 1L << (curChar & 077);
- MatchLoop: do
- {
- switch(jjstateSet[--i])
- {
- case 0:
- case 28:
- if ((0x7fffffe87fffffeL & l) == 0L)
- break;
- if (kind > 67)
- kind = 67;
- jjCheckNAdd(28);
- break;
- case 2:
- if ((0x100000001000L & l) != 0L && kind > 59)
- kind = 59;
- break;
- case 5:
- if ((0x2000000020L & l) != 0L)
- jjAddStates(40, 41);
- break;
- case 8:
- if ((0x5000000050L & l) != 0L && kind > 63)
- kind = 63;
- break;
- case 10:
- if ((0xffffffffefffffffL & l) != 0L)
- jjCheckNAdd(11);
- break;
- case 12:
- if (curChar == 92)
- jjAddStates(42, 44);
- break;
- case 13:
- if ((0x14404410000000L & l) != 0L)
- jjCheckNAdd(11);
- break;
- case 19:
- if ((0xffffffffefffffffL & l) != 0L)
- jjCheckNAddStates(10, 12);
- break;
- case 20:
- if (curChar == 92)
- jjAddStates(45, 47);
- break;
- case 21:
- if ((0x14404410000000L & l) != 0L)
- jjCheckNAddStates(10, 12);
- break;
- case 33:
- if ((0x2000000020L & l) != 0L)
- jjAddStates(48, 49);
- break;
- case 37:
- if ((0x2000000020L & l) != 0L)
- jjAddStates(50, 51);
- break;
- case 41:
- if ((0x2000000020L & l) != 0L)
- jjAddStates(52, 53);
- break;
- case 45:
- if ((0x100000001000000L & l) != 0L)
- jjCheckNAdd(46);
- break;
- case 46:
- if ((0x7e0000007eL & l) == 0L)
- break;
- if (kind > 59)
- kind = 59;
- jjCheckNAddTwoStates(46, 2);
- break;
- case 50:
- jjAddStates(18, 20);
- break;
- case 55:
- jjCheckNAddTwoStates(55, 56);
- break;
- case 57:
- case 58:
- jjCheckNAddTwoStates(58, 56);
- break;
- case 62:
- jjCheckNAddTwoStates(62, 63);
- break;
- case 64:
- case 65:
- jjCheckNAddTwoStates(65, 63);
- break;
- default : break;
- }
- } while(i != startsAt);
- }
- else
- {
- int hiByte = (int)(curChar >> 8);
- int i1 = hiByte >> 6;
- long l1 = 1L << (hiByte & 077);
- int i2 = (curChar & 0xff) >> 6;
- long l2 = 1L << (curChar & 077);
- MatchLoop: do
- {
- switch(jjstateSet[--i])
- {
- case 0:
- case 28:
- if (!jjCanMove_1(hiByte, i1, i2, l1, l2))
- break;
- if (kind > 67)
- kind = 67;
- jjCheckNAdd(28);
- break;
- case 10:
- if (jjCanMove_0(hiByte, i1, i2, l1, l2))
- jjstateSet[jjnewStateCnt++] = 11;
- break;
- case 19:
- if (jjCanMove_0(hiByte, i1, i2, l1, l2))
- jjAddStates(10, 12);
- break;
- case 50:
- if (jjCanMove_0(hiByte, i1, i2, l1, l2))
- jjAddStates(18, 20);
- break;
- case 55:
- if (jjCanMove_0(hiByte, i1, i2, l1, l2))
- jjCheckNAddTwoStates(55, 56);
- break;
- case 57:
- case 58:
- if (jjCanMove_0(hiByte, i1, i2, l1, l2))
- jjCheckNAddTwoStates(58, 56);
- break;
- case 62:
- if (jjCanMove_0(hiByte, i1, i2, l1, l2))
- jjCheckNAddTwoStates(62, 63);
- break;
- case 64:
- case 65:
- if (jjCanMove_0(hiByte, i1, i2, l1, l2))
- jjCheckNAddTwoStates(65, 63);
- break;
- default : break;
- }
- } while(i != startsAt);
- }
- if (kind != 0x7fffffff)
- {
- jjmatchedKind = kind;
- jjmatchedPos = curPos;
- kind = 0x7fffffff;
- }
- ++curPos;
- if ((i = jjnewStateCnt) == (startsAt = 67 - (jjnewStateCnt = startsAt)))
- return curPos;
- try { curChar = input_stream.readChar(); }
- catch(java.io.IOException e) { return curPos; }
- }
-}
-static final int[] jjnextStates = {
- 30, 31, 36, 37, 40, 41, 8, 49, 60, 61, 19, 20, 22, 10, 12, 45,
- 47, 2, 50, 51, 53, 4, 5, 8, 19, 20, 24, 22, 32, 33, 8, 40,
- 41, 8, 56, 57, 59, 63, 64, 66, 6, 7, 13, 14, 16, 21, 23, 25,
- 34, 35, 38, 39, 42, 43,
-};
-private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, long l2)
-{
- switch(hiByte)
- {
- case 0:
- return ((jjbitVec2[i2] & l2) != 0L);
- default :
- if ((jjbitVec0[i1] & l1) != 0L)
- return true;
- return false;
- }
-}
-private static final boolean jjCanMove_1(int hiByte, int i1, int i2, long l1, long l2)
-{
- switch(hiByte)
- {
- case 0:
- return ((jjbitVec4[i2] & l2) != 0L);
- case 48:
- return ((jjbitVec5[i2] & l2) != 0L);
- case 49:
- return ((jjbitVec6[i2] & l2) != 0L);
- case 51:
- return ((jjbitVec7[i2] & l2) != 0L);
- case 61:
- return ((jjbitVec8[i2] & l2) != 0L);
- default :
- if ((jjbitVec3[i1] & l1) != 0L)
- return true;
- return false;
- }
-}
-public static final String[] jjstrLiteralImages = {
-"", null, null, null, null, null, null, null, null,
-"\141\142\163\164\162\141\143\164", "\142\157\157\154\145\141\156",
"\142\162\145\141\153", "\142\171\164\145",
-"\143\141\163\145", "\143\141\164\143\150",
"\143\150\141\162", "\143\154\141\163\163",
-"\143\157\156\163\164", "\143\157\156\164\151\156\165\145",
"\144\145\146\141\165\154\164",
-"\144\157", "\144\157\165\142\154\145", "\145\154\163\145",
-"\145\170\164\145\156\144\163", "\146\141\154\163\145",
"\146\151\156\141\154",
-"\146\151\156\141\154\154\171", "\146\154\157\141\164",
"\146\157\162", "\147\157\164\157", "\151\146",
-"\151\155\160\154\145\155\145\156\164\163",
"\151\155\160\157\162\164",
"\151\156\163\164\141\156\143\145\157\146",
-"\151\156\164", "\151\156\164\145\162\146\141\143\145",
"\154\157\156\147",
-"\156\141\164\151\166\145", "\156\145\167",
"\156\165\154\154", "\160\141\143\153\141\147\145",
-"\160\162\151\166\141\164\145",
"\160\162\157\164\145\143\164\145\144", "\160\165\142\154\151\143",
-"\162\145\164\165\162\156", "\163\150\157\162\164",
"\163\164\141\164\151\143", "\163\165\160\145\162",
-"\163\167\151\164\143\150",
"\163\171\156\143\150\162\157\156\151\172\145\144",
"\164\150\151\163",
-"\164\150\162\157\167", "\164\150\162\157\167\163",
"\164\162\141\156\163\151\145\156\164",
-"\164\162\165\145", "\164\162\171", "\166\157\151\144",
"\166\157\154\141\164\151\154\145",
-"\167\150\151\154\145", null, null, null, null, null, null, null, null, null,
null, null, "\50",
-"\51", "\173", "\175", "\133", "\135",
"\73", "\54", "\56", "\75", "\76",
"\74",
-"\41", "\176", "\77", "\72", "\75\75",
"\74\75", "\76\75", "\41\75", "\174\174",
-"\46\46", "\53\53", "\55\55", "\53",
"\55", "\52", "\57", "\46", "\174",
"\136", "\45",
-"\74\74", "\76\76", "\76\76\76", "\53\75",
"\55\75", "\52\75", "\57\75", "\46\75",
-"\174\75", "\136\75", "\45\75", "\74\74\75",
"\76\76\75", "\76\76\76\75", };
-public static final String[] lexStateNames = {
- "DEFAULT",
-};
-static final long[] jjtoToken = {
- 0x8ffffffffffffe01L, 0xfffffffffffceL,
-};
-static final long[] jjtoSkip = {
- 0x1feL, 0x0L,
-};
-static final long[] jjtoSpecial = {
- 0x1c0L, 0x0L,
-};
-private ASCII_UCodeESC_CharStream input_stream;
-private final int[] jjrounds = new int[67];
-private final int[] jjstateSet = new int[134];
-protected char curChar;
-public ExpressionParserTokenManager(ASCII_UCodeESC_CharStream stream)
-{
- if (ASCII_UCodeESC_CharStream.staticFlag)
- throw new Error("ERROR: Cannot use a static CharStream class with a non-static
lexical analyzer.");
- input_stream = stream;
-}
-public ExpressionParserTokenManager(ASCII_UCodeESC_CharStream stream, int lexState)
-{
- this(stream);
- SwitchTo(lexState);
-}
-public void ReInit(ASCII_UCodeESC_CharStream stream)
-{
- jjmatchedPos = jjnewStateCnt = 0;
- curLexState = defaultLexState;
- input_stream = stream;
- ReInitRounds();
-}
-private final void ReInitRounds()
-{
- int i;
- jjround = 0x80000001;
- for (i = 67; i-- > 0;)
- jjrounds[i] = 0x80000000;
-}
-public void ReInit(ASCII_UCodeESC_CharStream stream, int lexState)
-{
- ReInit(stream);
- SwitchTo(lexState);
-}
-public void SwitchTo(int lexState)
-{
- if (lexState >= 1 || lexState < 0)
- throw new TokenMgrError("Error: Ignoring invalid lexical state : " +
lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
- else
- curLexState = lexState;
-}
-
-private final Token jjFillToken()
-{
- Token t = Token.newToken(jjmatchedKind);
- t.kind = jjmatchedKind;
- String im = jjstrLiteralImages[jjmatchedKind];
- t.image = (im == null) ? input_stream.GetImage() : im;
- t.beginLine = input_stream.getBeginLine();
- t.beginColumn = input_stream.getBeginColumn();
- t.endLine = input_stream.getEndLine();
- t.endColumn = input_stream.getEndColumn();
- return t;
-}
-
-int curLexState = 0;
-int defaultLexState = 0;
-int jjnewStateCnt;
-int jjround;
-int jjmatchedPos;
-int jjmatchedKind;
-
-public final Token getNextToken()
-{
- int kind;
- Token specialToken = null;
- Token matchedToken;
- int curPos = 0;
-
- EOFLoop :
- for (;;)
- {
- try
- {
- curChar = input_stream.BeginToken();
- }
- catch(java.io.IOException e)
- {
- jjmatchedKind = 0;
- matchedToken = jjFillToken();
- matchedToken.specialToken = specialToken;
- return matchedToken;
- }
-
- try {
- while (curChar <= 32 && (0x100003600L & (1L << curChar)) !=
0L)
- curChar = input_stream.BeginToken();
- }
- catch (java.io.IOException e1) { continue EOFLoop; }
- jjmatchedKind = 0x7fffffff;
- jjmatchedPos = 0;
- curPos = jjMoveStringLiteralDfa0_0();
- if (jjmatchedKind != 0x7fffffff)
- {
- if (jjmatchedPos + 1 < curPos)
- input_stream.backup(curPos - jjmatchedPos - 1);
- if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind &
077))) != 0L)
- {
- matchedToken = jjFillToken();
- matchedToken.specialToken = specialToken;
- return matchedToken;
- }
- else
- {
- if ((jjtoSpecial[jjmatchedKind >> 6] & (1L << (jjmatchedKind
& 077))) != 0L)
- {
- matchedToken = jjFillToken();
- if (specialToken == null)
- specialToken = matchedToken;
- else
- {
- matchedToken.specialToken = specialToken;
- specialToken = (specialToken.next = matchedToken);
- }
- }
- continue EOFLoop;
- }
- }
- int error_line = input_stream.getEndLine();
- int error_column = input_stream.getEndColumn();
- String error_after = null;
- boolean EOFSeen = false;
- try { input_stream.readChar(); input_stream.backup(1); }
- catch (java.io.IOException e1) {
- EOFSeen = true;
- error_after = curPos <= 1 ? "" : input_stream.GetImage();
- if (curChar == '\n' || curChar == '\r') {
- error_line++;
- error_column = 0;
- }
- else
- error_column++;
- }
- if (!EOFSeen) {
- input_stream.backup(1);
- error_after = curPos <= 1 ? "" : input_stream.GetImage();
- }
- throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after,
curChar, TokenMgrError.LEXICAL_ERROR);
- }
-}
-
-}
+/* Generated By:JavaCC: Do not edit this line. ExpressionParserTokenManager.java */
+package jde.debugger.expr;
+import com.sun.jdi.*;
+import java.util.Stack;
+import java.util.List;
+import java.util.ArrayList;
+
+public class ExpressionParserTokenManager implements ExpressionParserConstants
+{
+private final int jjStopStringLiteralDfa_0(int pos, long active0, long active1)
+{
+ switch (pos)
+ {
+ case 0:
+ if ((active1 & 0x4000L) != 0L)
+ return 4;
+ if ((active0 & 0x7fffffffffffe00L) != 0L)
+ {
+ jjmatchedKind = 67;
+ return 28;
+ }
+ if ((active1 & 0x100200000000L) != 0L)
+ return 49;
+ return -1;
+ case 1:
+ if ((active0 & 0x7ffffffbfcffe00L) != 0L)
+ {
+ if (jjmatchedPos != 1)
+ {
+ jjmatchedKind = 67;
+ jjmatchedPos = 1;
+ }
+ return 28;
+ }
+ if ((active0 & 0x40300000L) != 0L)
+ return 28;
+ return -1;
+ case 2:
+ if ((active0 & 0x77fffb3afeffe00L) != 0L)
+ {
+ if (jjmatchedPos != 2)
+ {
+ jjmatchedKind = 67;
+ jjmatchedPos = 2;
+ }
+ return 28;
+ }
+ if ((active0 & 0x80004c10000000L) != 0L)
+ return 28;
+ return -1;
+ case 3:
+ if ((active0 & 0x63bff2b8faf4e00L) != 0L)
+ {
+ jjmatchedKind = 67;
+ jjmatchedPos = 3;
+ return 28;
+ }
+ if ((active0 & 0x14400902040b000L) != 0L)
+ return 28;
+ return -1;
+ case 4:
+ if ((active0 & 0x2235f2b80ac0600L) != 0L)
+ {
+ if (jjmatchedPos != 4)
+ {
+ jjmatchedKind = 67;
+ jjmatchedPos = 4;
+ }
+ return 28;
+ }
+ if ((active0 & 0x418a0000f034800L) != 0L)
+ return 28;
+ return -1;
+ case 5:
+ if ((active0 & 0x222070a848c0600L) != 0L)
+ {
+ jjmatchedKind = 67;
+ jjmatchedPos = 5;
+ return 28;
+ }
+ if ((active0 & 0x11582100200000L) != 0L)
+ return 28;
+ return -1;
+ case 6:
+ if ((active0 & 0x222040a80040200L) != 0L)
+ {
+ jjmatchedKind = 67;
+ jjmatchedPos = 6;
+ return 28;
+ }
+ if ((active0 & 0x30004880400L) != 0L)
+ return 28;
+ return -1;
+ case 7:
+ if ((active0 & 0x22040a80000000L) != 0L)
+ {
+ jjmatchedKind = 67;
+ jjmatchedPos = 7;
+ return 28;
+ }
+ if ((active0 & 0x200000000040200L) != 0L)
+ return 28;
+ return -1;
+ case 8:
+ if ((active0 & 0x2000280000000L) != 0L)
+ {
+ jjmatchedKind = 67;
+ jjmatchedPos = 8;
+ return 28;
+ }
+ if ((active0 & 0x20040800000000L) != 0L)
+ return 28;
+ return -1;
+ case 9:
+ if ((active0 & 0x2000000000000L) != 0L)
+ {
+ jjmatchedKind = 67;
+ jjmatchedPos = 9;
+ return 28;
+ }
+ if ((active0 & 0x280000000L) != 0L)
+ return 28;
+ return -1;
+ case 10:
+ if ((active0 & 0x2000000000000L) != 0L)
+ {
+ jjmatchedKind = 67;
+ jjmatchedPos = 10;
+ return 28;
+ }
+ return -1;
+ default :
+ return -1;
+ }
+}
+private final int jjStartNfa_0(int pos, long active0, long active1)
+{
+ return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0, active1), pos + 1);
+}
+private final int jjStopAtPos(int pos, int kind)
+{
+ jjmatchedKind = kind;
+ jjmatchedPos = pos;
+ return pos + 1;
+}
+private final int jjStartNfaWithStates_0(int pos, int kind, int state)
+{
+ jjmatchedKind = kind;
+ jjmatchedPos = pos;
+ try { curChar = input_stream.readChar(); }
+ catch(java.io.IOException e) { return pos + 1; }
+ return jjMoveNfa_0(state, pos + 1);
+}
+private final int jjMoveStringLiteralDfa0_0()
+{
+ switch(curChar)
+ {
+ case 33:
+ jjmatchedKind = 82;
+ return jjMoveStringLiteralDfa1_0(0x0L, 0x2000000L);
+ case 37:
+ jjmatchedKind = 101;
+ return jjMoveStringLiteralDfa1_0(0x0L, 0x1000000000000L);
+ case 38:
+ jjmatchedKind = 98;
+ return jjMoveStringLiteralDfa1_0(0x0L, 0x200008000000L);
+ case 40:
+ return jjStopAtPos(0, 70);
+ case 41:
+ return jjStopAtPos(0, 71);
+ case 42:
+ jjmatchedKind = 96;
+ return jjMoveStringLiteralDfa1_0(0x0L, 0x80000000000L);
+ case 43:
+ jjmatchedKind = 94;
+ return jjMoveStringLiteralDfa1_0(0x0L, 0x20010000000L);
+ case 44:
+ return jjStopAtPos(0, 77);
+ case 45:
+ jjmatchedKind = 95;
+ return jjMoveStringLiteralDfa1_0(0x0L, 0x40020000000L);
+ case 46:
+ return jjStartNfaWithStates_0(0, 78, 4);
+ case 47:
+ jjmatchedKind = 97;
+ return jjMoveStringLiteralDfa1_0(0x0L, 0x100000000000L);
+ case 58:
+ return jjStopAtPos(0, 85);
+ case 59:
+ return jjStopAtPos(0, 76);
+ case 60:
+ jjmatchedKind = 81;
+ return jjMoveStringLiteralDfa1_0(0x0L, 0x2004000800000L);
+ case 61:
+ jjmatchedKind = 79;
+ return jjMoveStringLiteralDfa1_0(0x0L, 0x400000L);
+ case 62:
+ jjmatchedKind = 80;
+ return jjMoveStringLiteralDfa1_0(0x0L, 0xc018001000000L);
+ case 63:
+ return jjStopAtPos(0, 84);
+ case 91:
+ return jjStopAtPos(0, 74);
+ case 93:
+ return jjStopAtPos(0, 75);
+ case 94:
+ jjmatchedKind = 100;
+ return jjMoveStringLiteralDfa1_0(0x0L, 0x800000000000L);
+ case 97:
+ return jjMoveStringLiteralDfa1_0(0x200L, 0x0L);
+ case 98:
+ return jjMoveStringLiteralDfa1_0(0x1c00L, 0x0L);
+ case 99:
+ return jjMoveStringLiteralDfa1_0(0x7e000L, 0x0L);
+ case 100:
+ return jjMoveStringLiteralDfa1_0(0x380000L, 0x0L);
+ case 101:
+ return jjMoveStringLiteralDfa1_0(0xc00000L, 0x0L);
+ case 102:
+ return jjMoveStringLiteralDfa1_0(0x1f000000L, 0x0L);
+ case 103:
+ return jjMoveStringLiteralDfa1_0(0x20000000L, 0x0L);
+ case 105:
+ return jjMoveStringLiteralDfa1_0(0xfc0000000L, 0x0L);
+ case 108:
+ return jjMoveStringLiteralDfa1_0(0x1000000000L, 0x0L);
+ case 110:
+ return jjMoveStringLiteralDfa1_0(0xe000000000L, 0x0L);
+ case 112:
+ return jjMoveStringLiteralDfa1_0(0xf0000000000L, 0x0L);
+ case 114:
+ return jjMoveStringLiteralDfa1_0(0x100000000000L, 0x0L);
+ case 115:
+ return jjMoveStringLiteralDfa1_0(0x3e00000000000L, 0x0L);
+ case 116:
+ return jjMoveStringLiteralDfa1_0(0xfc000000000000L, 0x0L);
+ case 118:
+ return jjMoveStringLiteralDfa1_0(0x300000000000000L, 0x0L);
+ case 119:
+ return jjMoveStringLiteralDfa1_0(0x400000000000000L, 0x0L);
+ case 123:
+ return jjStopAtPos(0, 72);
+ case 124:
+ jjmatchedKind = 99;
+ return jjMoveStringLiteralDfa1_0(0x0L, 0x400004000000L);
+ case 125:
+ return jjStopAtPos(0, 73);
+ case 126:
+ return jjStopAtPos(0, 83);
+ default :
+ return jjMoveNfa_0(0, 0);
+ }
+}
+private final int jjMoveStringLiteralDfa1_0(long active0, long active1)
+{
+ try { curChar = input_stream.readChar(); }
+ catch(java.io.IOException e) {
+ jjStopStringLiteralDfa_0(0, active0, active1);
+ return 1;
+ }
+ switch(curChar)
+ {
+ case 38:
+ if ((active1 & 0x8000000L) != 0L)
+ return jjStopAtPos(1, 91);
+ break;
+ case 43:
+ if ((active1 & 0x10000000L) != 0L)
+ return jjStopAtPos(1, 92);
+ break;
+ case 45:
+ if ((active1 & 0x20000000L) != 0L)
+ return jjStopAtPos(1, 93);
+ break;
+ case 60:
+ if ((active1 & 0x4000000000L) != 0L)
+ {
+ jjmatchedKind = 102;
+ jjmatchedPos = 1;
+ }
+ return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x2000000000000L);
+ case 61:
+ if ((active1 & 0x400000L) != 0L)
+ return jjStopAtPos(1, 86);
+ else if ((active1 & 0x800000L) != 0L)
+ return jjStopAtPos(1, 87);
+ else if ((active1 & 0x1000000L) != 0L)
+ return jjStopAtPos(1, 88);
+ else if ((active1 & 0x2000000L) != 0L)
+ return jjStopAtPos(1, 89);
+ else if ((active1 & 0x20000000000L) != 0L)
+ return jjStopAtPos(1, 105);
+ else if ((active1 & 0x40000000000L) != 0L)
+ return jjStopAtPos(1, 106);
+ else if ((active1 & 0x80000000000L) != 0L)
+ return jjStopAtPos(1, 107);
+ else if ((active1 & 0x100000000000L) != 0L)
+ return jjStopAtPos(1, 108);
+ else if ((active1 & 0x200000000000L) != 0L)
+ return jjStopAtPos(1, 109);
+ else if ((active1 & 0x400000000000L) != 0L)
+ return jjStopAtPos(1, 110);
+ else if ((active1 & 0x800000000000L) != 0L)
+ return jjStopAtPos(1, 111);
+ else if ((active1 & 0x1000000000000L) != 0L)
+ return jjStopAtPos(1, 112);
+ break;
+ case 62:
+ if ((active1 & 0x8000000000L) != 0L)
+ {
+ jjmatchedKind = 103;
+ jjmatchedPos = 1;
+ }
+ return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0xc010000000000L);
+ case 97:
+ return jjMoveStringLiteralDfa2_0(active0, 0x12001006000L, active1, 0L);
+ case 98:
+ return jjMoveStringLiteralDfa2_0(active0, 0x200L, active1, 0L);
+ case 101:
+ return jjMoveStringLiteralDfa2_0(active0, 0x104000080000L, active1, 0L);
+ case 102:
+ if ((active0 & 0x40000000L) != 0L)
+ return jjStartNfaWithStates_0(1, 30, 28);
+ break;
+ case 104:
+ return jjMoveStringLiteralDfa2_0(active0, 0x41c200000008000L, active1, 0L);
+ case 105:
+ return jjMoveStringLiteralDfa2_0(active0, 0x6000000L, active1, 0L);
+ case 108:
+ return jjMoveStringLiteralDfa2_0(active0, 0x8410000L, active1, 0L);
+ case 109:
+ return jjMoveStringLiteralDfa2_0(active0, 0x180000000L, active1, 0L);
+ case 110:
+ return jjMoveStringLiteralDfa2_0(active0, 0xe00000000L, active1, 0L);
+ case 111:
+ if ((active0 & 0x100000L) != 0L)
+ {
+ jjmatchedKind = 20;
+ jjmatchedPos = 1;
+ }
+ return jjMoveStringLiteralDfa2_0(active0, 0x300001030260400L, active1, 0L);
+ case 114:
+ return jjMoveStringLiteralDfa2_0(active0, 0xe0060000000800L, active1, 0L);
+ case 116:
+ return jjMoveStringLiteralDfa2_0(active0, 0x400000000000L, active1, 0L);
+ case 117:
+ return jjMoveStringLiteralDfa2_0(active0, 0x888000000000L, active1, 0L);
+ case 119:
+ return jjMoveStringLiteralDfa2_0(active0, 0x1000000000000L, active1, 0L);
+ case 120:
+ return jjMoveStringLiteralDfa2_0(active0, 0x800000L, active1, 0L);
+ case 121:
+ return jjMoveStringLiteralDfa2_0(active0, 0x2000000001000L, active1, 0L);
+ case 124:
+ if ((active1 & 0x4000000L) != 0L)
+ return jjStopAtPos(1, 90);
+ break;
+ default :
+ break;
+ }
+ return jjStartNfa_0(0, active0, active1);
+}
+private final int jjMoveStringLiteralDfa2_0(long old0, long active0, long old1, long
active1)
+{
+ if (((active0 &= old0) | (active1 &= old1)) == 0L)
+ return jjStartNfa_0(0, old0, old1);
+ try { curChar = input_stream.readChar(); }
+ catch(java.io.IOException e) {
+ jjStopStringLiteralDfa_0(1, active0, active1);
+ return 2;
+ }
+ switch(curChar)
+ {
+ case 61:
+ if ((active1 & 0x2000000000000L) != 0L)
+ return jjStopAtPos(2, 113);
+ else if ((active1 & 0x4000000000000L) != 0L)
+ return jjStopAtPos(2, 114);
+ break;
+ case 62:
+ if ((active1 & 0x10000000000L) != 0L)
+ {
+ jjmatchedKind = 104;
+ jjmatchedPos = 2;
+ }
+ return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0x8000000000000L);
+ case 97:
+ return jjMoveStringLiteralDfa3_0(active0, 0x20400000018000L, active1, 0L);
+ case 98:
+ return jjMoveStringLiteralDfa3_0(active0, 0x80000000000L, active1, 0L);
+ case 99:
+ return jjMoveStringLiteralDfa3_0(active0, 0x10000000000L, active1, 0L);
+ case 101:
+ return jjMoveStringLiteralDfa3_0(active0, 0x800L, active1, 0L);
+ case 102:
+ return jjMoveStringLiteralDfa3_0(active0, 0x80000L, active1, 0L);
+ case 105:
+ return jjMoveStringLiteralDfa3_0(active0, 0x505020000000000L, active1, 0L);
+ case 108:
+ return jjMoveStringLiteralDfa3_0(active0, 0x200008001000000L, active1, 0L);
+ case 110:
+ return jjMoveStringLiteralDfa3_0(active0, 0x2001006060000L, active1, 0L);
+ case 111:
+ return jjMoveStringLiteralDfa3_0(active0, 0x240008000400L, active1, 0L);
+ case 112:
+ return jjMoveStringLiteralDfa3_0(active0, 0x800180000000L, active1, 0L);
+ case 114:
+ if ((active0 & 0x10000000L) != 0L)
+ return jjStartNfaWithStates_0(2, 28, 28);
+ return jjMoveStringLiteralDfa3_0(active0, 0x18000000000000L, active1, 0L);
+ case 115:
+ return jjMoveStringLiteralDfa3_0(active0, 0x200402200L, active1, 0L);
+ case 116:
+ if ((active0 & 0x400000000L) != 0L)
+ {
+ jjmatchedKind = 34;
+ jjmatchedPos = 2;
+ }
+ return jjMoveStringLiteralDfa3_0(active0, 0x102820805000L, active1, 0L);
+ case 117:
+ return jjMoveStringLiteralDfa3_0(active0, 0x40000000200000L, active1, 0L);
+ case 119:
+ if ((active0 & 0x4000000000L) != 0L)
+ return jjStartNfaWithStates_0(2, 38, 28);
+ break;
+ case 121:
+ if ((active0 & 0x80000000000000L) != 0L)
+ return jjStartNfaWithStates_0(2, 55, 28);
+ break;
+ default :
+ break;
+ }
+ return jjStartNfa_0(1, active0, active1);
+}
+private final int jjMoveStringLiteralDfa3_0(long old0, long active0, long old1, long
active1)
+{
+ if (((active0 &= old0) | (active1 &= old1)) == 0L)
+ return jjStartNfa_0(1, old0, old1);
+ try { curChar = input_stream.readChar(); }
+ catch(java.io.IOException e) {
+ jjStopStringLiteralDfa_0(2, active0, active1);
+ return 3;
+ }
+ switch(curChar)
+ {
+ case 61:
+ if ((active1 & 0x8000000000000L) != 0L)
+ return jjStopAtPos(3, 115);
+ break;
+ case 97:
+ return jjMoveStringLiteralDfa4_0(active0, 0x20000000e080800L, active1, 0L);
+ case 98:
+ return jjMoveStringLiteralDfa4_0(active0, 0x200000L, active1, 0L);
+ case 99:
+ return jjMoveStringLiteralDfa4_0(active0, 0x2000000004000L, active1, 0L);
+ case 100:
+ if ((active0 & 0x100000000000000L) != 0L)
+ return jjStartNfaWithStates_0(3, 56, 28);
+ break;
+ case 101:
+ if ((active0 & 0x1000L) != 0L)
+ return jjStartNfaWithStates_0(3, 12, 28);
+ else if ((active0 & 0x2000L) != 0L)
+ return jjStartNfaWithStates_0(3, 13, 28);
+ else if ((active0 & 0x400000L) != 0L)
+ return jjStartNfaWithStates_0(3, 22, 28);
+ else if ((active0 & 0x40000000000000L) != 0L)
+ return jjStartNfaWithStates_0(3, 54, 28);
+ return jjMoveStringLiteralDfa4_0(active0, 0x800800800000L, active1, 0L);
+ case 103:
+ if ((active0 & 0x1000000000L) != 0L)
+ return jjStartNfaWithStates_0(3, 36, 28);
+ break;
+ case 105:
+ return jjMoveStringLiteralDfa4_0(active0, 0x2000000000L, active1, 0L);
+ case 107:
+ return jjMoveStringLiteralDfa4_0(active0, 0x10000000000L, active1, 0L);
+ case 108:
+ if ((active0 & 0x8000000000L) != 0L)
+ return jjStartNfaWithStates_0(3, 39, 28);
+ return jjMoveStringLiteralDfa4_0(active0, 0x400080080000400L, active1, 0L);
+ case 110:
+ return jjMoveStringLiteralDfa4_0(active0, 0x20000000000000L, active1, 0L);
+ case 111:
+ if ((active0 & 0x20000000L) != 0L)
+ return jjStartNfaWithStates_0(3, 29, 28);
+ return jjMoveStringLiteralDfa4_0(active0, 0x18000100000000L, active1, 0L);
+ case 114:
+ if ((active0 & 0x8000L) != 0L)
+ return jjStartNfaWithStates_0(3, 15, 28);
+ return jjMoveStringLiteralDfa4_0(active0, 0x200000000000L, active1, 0L);
+ case 115:
+ if ((active0 & 0x4000000000000L) != 0L)
+ return jjStartNfaWithStates_0(3, 50, 28);
+ return jjMoveStringLiteralDfa4_0(active0, 0x1030000L, active1, 0L);
+ case 116:
+ return jjMoveStringLiteralDfa4_0(active0, 0x1440200040200L, active1, 0L);
+ case 117:
+ return jjMoveStringLiteralDfa4_0(active0, 0x100000000000L, active1, 0L);
+ case 118:
+ return jjMoveStringLiteralDfa4_0(active0, 0x20000000000L, active1, 0L);
+ default :
+ break;
+ }
+ return jjStartNfa_0(2, active0, active1);
+}
+private final int jjMoveStringLiteralDfa4_0(long old0, long active0, long old1, long
active1)
+{
+ if (((active0 &= old0) | (active1 &= old1)) == 0L)
+ return jjStartNfa_0(2, old0, old1);
+ try { curChar = input_stream.readChar(); }
+ catch(java.io.IOException e) {
+ jjStopStringLiteralDfa_0(3, active0, 0L);
+ return 4;
+ }
+ switch(curChar)
+ {
+ case 97:
+ return jjMoveStringLiteralDfa5_0(active0, 0x30200000000L);
+ case 99:
+ return jjMoveStringLiteralDfa5_0(active0, 0x1000000000000L);
+ case 101:
+ if ((active0 & 0x1000000L) != 0L)
+ return jjStartNfaWithStates_0(4, 24, 28);
+ else if ((active0 & 0x400000000000000L) != 0L)
+ return jjStartNfaWithStates_0(4, 58, 28);
+ return jjMoveStringLiteralDfa5_0(active0, 0x40080000400L);
+ case 104:
+ if ((active0 & 0x4000L) != 0L)
+ return jjStartNfaWithStates_0(4, 14, 28);
+ return jjMoveStringLiteralDfa5_0(active0, 0x2000000000000L);
+ case 105:
+ return jjMoveStringLiteralDfa5_0(active0, 0x480000040000L);
+ case 107:
+ if ((active0 & 0x800L) != 0L)
+ return jjStartNfaWithStates_0(4, 11, 28);
+ break;
+ case 108:
+ if ((active0 & 0x2000000L) != 0L)
+ {
+ jjmatchedKind = 25;
+ jjmatchedPos = 4;
+ }
+ return jjMoveStringLiteralDfa5_0(active0, 0x4200000L);
+ case 110:
+ return jjMoveStringLiteralDfa5_0(active0, 0x800000L);
+ case 114:
+ if ((active0 & 0x800000000000L) != 0L)
+ return jjStartNfaWithStates_0(4, 47, 28);
+ return jjMoveStringLiteralDfa5_0(active0, 0x100900000200L);
+ case 115:
+ if ((active0 & 0x10000L) != 0L)
+ return jjStartNfaWithStates_0(4, 16, 28);
+ return jjMoveStringLiteralDfa5_0(active0, 0x20000000000000L);
+ case 116:
+ if ((active0 & 0x20000L) != 0L)
+ return jjStartNfaWithStates_0(4, 17, 28);
+ else if ((active0 & 0x8000000L) != 0L)
+ return jjStartNfaWithStates_0(4, 27, 28);
+ else if ((active0 & 0x200000000000L) != 0L)
+ return jjStartNfaWithStates_0(4, 45, 28);
+ return jjMoveStringLiteralDfa5_0(active0, 0x200000000000000L);
+ case 117:
+ return jjMoveStringLiteralDfa5_0(active0, 0x80000L);
+ case 118:
+ return jjMoveStringLiteralDfa5_0(active0, 0x2000000000L);
+ case 119:
+ if ((active0 & 0x8000000000000L) != 0L)
+ {
+ jjmatchedKind = 51;
+ jjmatchedPos = 4;
+ }
+ return jjMoveStringLiteralDfa5_0(active0, 0x10000000000000L);
+ default :
+ break;
+ }
+ return jjStartNfa_0(3, active0, 0L);
+}
+private final int jjMoveStringLiteralDfa5_0(long old0, long active0)
+{
+ if (((active0 &= old0)) == 0L)
+ return jjStartNfa_0(3, old0, 0L);
+ try { curChar = input_stream.readChar(); }
+ catch(java.io.IOException e) {
+ jjStopStringLiteralDfa_0(4, active0, 0L);
+ return 5;
+ }
+ switch(curChar)
+ {
+ case 97:
+ return jjMoveStringLiteralDfa6_0(active0, 0x600L);
+ case 99:
+ if ((active0 & 0x80000000000L) != 0L)
+ return jjStartNfaWithStates_0(5, 43, 28);
+ else if ((active0 & 0x400000000000L) != 0L)
+ return jjStartNfaWithStates_0(5, 46, 28);
+ return jjMoveStringLiteralDfa6_0(active0, 0x40000000000L);
+ case 100:
+ return jjMoveStringLiteralDfa6_0(active0, 0x800000L);
+ case 101:
+ if ((active0 & 0x200000L) != 0L)
+ return jjStartNfaWithStates_0(5, 21, 28);
+ else if ((active0 & 0x2000000000L) != 0L)
+ return jjStartNfaWithStates_0(5, 37, 28);
+ break;
+ case 102:
+ return jjMoveStringLiteralDfa6_0(active0, 0x800000000L);
+ case 103:
+ return jjMoveStringLiteralDfa6_0(active0, 0x10000000000L);
+ case 104:
+ if ((active0 & 0x1000000000000L) != 0L)
+ return jjStartNfaWithStates_0(5, 48, 28);
+ break;
+ case 105:
+ return jjMoveStringLiteralDfa6_0(active0, 0x220000000000000L);
+ case 108:
+ return jjMoveStringLiteralDfa6_0(active0, 0x4080000L);
+ case 109:
+ return jjMoveStringLiteralDfa6_0(active0, 0x80000000L);
+ case 110:
+ if ((active0 & 0x100000000000L) != 0L)
+ return jjStartNfaWithStates_0(5, 44, 28);
+ return jjMoveStringLiteralDfa6_0(active0, 0x200040000L);
+ case 114:
+ return jjMoveStringLiteralDfa6_0(active0, 0x2000000000000L);
+ case 115:
+ if ((active0 & 0x10000000000000L) != 0L)
+ return jjStartNfaWithStates_0(5, 52, 28);
+ break;
+ case 116:
+ if ((active0 & 0x100000000L) != 0L)
+ return jjStartNfaWithStates_0(5, 32, 28);
+ return jjMoveStringLiteralDfa6_0(active0, 0x20000000000L);
+ default :
+ break;
+ }
+ return jjStartNfa_0(4, active0, 0L);
+}
+private final int jjMoveStringLiteralDfa6_0(long old0, long active0)
+{
+ if (((active0 &= old0)) == 0L)
+ return jjStartNfa_0(4, old0, 0L);
+ try { curChar = input_stream.readChar(); }
+ catch(java.io.IOException e) {
+ jjStopStringLiteralDfa_0(5, active0, 0L);
+ return 6;
+ }
+ switch(curChar)
+ {
+ case 97:
+ return jjMoveStringLiteralDfa7_0(active0, 0x800000000L);
+ case 99:
+ return jjMoveStringLiteralDfa7_0(active0, 0x200000200L);
+ case 101:
+ if ((active0 & 0x10000000000L) != 0L)
+ return jjStartNfaWithStates_0(6, 40, 28);
+ else if ((active0 & 0x20000000000L) != 0L)
+ return jjStartNfaWithStates_0(6, 41, 28);
+ return jjMoveStringLiteralDfa7_0(active0, 0x20000080000000L);
+ case 108:
+ return jjMoveStringLiteralDfa7_0(active0, 0x200000000000000L);
+ case 110:
+ if ((active0 & 0x400L) != 0L)
+ return jjStartNfaWithStates_0(6, 10, 28);
+ break;
+ case 111:
+ return jjMoveStringLiteralDfa7_0(active0, 0x2000000000000L);
+ case 115:
+ if ((active0 & 0x800000L) != 0L)
+ return jjStartNfaWithStates_0(6, 23, 28);
+ break;
+ case 116:
+ if ((active0 & 0x80000L) != 0L)
+ return jjStartNfaWithStates_0(6, 19, 28);
+ return jjMoveStringLiteralDfa7_0(active0, 0x40000000000L);
+ case 117:
+ return jjMoveStringLiteralDfa7_0(active0, 0x40000L);
+ case 121:
+ if ((active0 & 0x4000000L) != 0L)
+ return jjStartNfaWithStates_0(6, 26, 28);
+ break;
+ default :
+ break;
+ }
+ return jjStartNfa_0(5, active0, 0L);
+}
+private final int jjMoveStringLiteralDfa7_0(long old0, long active0)
+{
+ if (((active0 &= old0)) == 0L)
+ return jjStartNfa_0(5, old0, 0L);
+ try { curChar = input_stream.readChar(); }
+ catch(java.io.IOException e) {
+ jjStopStringLiteralDfa_0(6, active0, 0L);
+ return 7;
+ }
+ switch(curChar)
+ {
+ case 99:
+ return jjMoveStringLiteralDfa8_0(active0, 0x800000000L);
+ case 101:
+ if ((active0 & 0x40000L) != 0L)
+ return jjStartNfaWithStates_0(7, 18, 28);
+ else if ((active0 & 0x200000000000000L) != 0L)
+ return jjStartNfaWithStates_0(7, 57, 28);
+ return jjMoveStringLiteralDfa8_0(active0, 0x40200000000L);
+ case 110:
+ return jjMoveStringLiteralDfa8_0(active0, 0x22000080000000L);
+ case 116:
+ if ((active0 & 0x200L) != 0L)
+ return jjStartNfaWithStates_0(7, 9, 28);
+ break;
+ default :
+ break;
+ }
+ return jjStartNfa_0(6, active0, 0L);
+}
+private final int jjMoveStringLiteralDfa8_0(long old0, long active0)
+{
+ if (((active0 &= old0)) == 0L)
+ return jjStartNfa_0(6, old0, 0L);
+ try { curChar = input_stream.readChar(); }
+ catch(java.io.IOException e) {
+ jjStopStringLiteralDfa_0(7, active0, 0L);
+ return 8;
+ }
+ switch(curChar)
+ {
+ case 100:
+ if ((active0 & 0x40000000000L) != 0L)
+ return jjStartNfaWithStates_0(8, 42, 28);
+ break;
+ case 101:
+ if ((active0 & 0x800000000L) != 0L)
+ return jjStartNfaWithStates_0(8, 35, 28);
+ break;
+ case 105:
+ return jjMoveStringLiteralDfa9_0(active0, 0x2000000000000L);
+ case 111:
+ return jjMoveStringLiteralDfa9_0(active0, 0x200000000L);
+ case 116:
+ if ((active0 & 0x20000000000000L) != 0L)
+ return jjStartNfaWithStates_0(8, 53, 28);
+ return jjMoveStringLiteralDfa9_0(active0, 0x80000000L);
+ default :
+ break;
+ }
+ return jjStartNfa_0(7, active0, 0L);
+}
+private final int jjMoveStringLiteralDfa9_0(long old0, long active0)
+{
+ if (((active0 &= old0)) == 0L)
+ return jjStartNfa_0(7, old0, 0L);
+ try { curChar = input_stream.readChar(); }
+ catch(java.io.IOException e) {
+ jjStopStringLiteralDfa_0(8, active0, 0L);
+ return 9;
+ }
+ switch(curChar)
+ {
+ case 102:
+ if ((active0 & 0x200000000L) != 0L)
+ return jjStartNfaWithStates_0(9, 33, 28);
+ break;
+ case 115:
+ if ((active0 & 0x80000000L) != 0L)
+ return jjStartNfaWithStates_0(9, 31, 28);
+ break;
+ case 122:
+ return jjMoveStringLiteralDfa10_0(active0, 0x2000000000000L);
+ default :
+ break;
+ }
+ return jjStartNfa_0(8, active0, 0L);
+}
+private final int jjMoveStringLiteralDfa10_0(long old0, long active0)
+{
+ if (((active0 &= old0)) == 0L)
+ return jjStartNfa_0(8, old0, 0L);
+ try { curChar = input_stream.readChar(); }
+ catch(java.io.IOException e) {
+ jjStopStringLiteralDfa_0(9, active0, 0L);
+ return 10;
+ }
+ switch(curChar)
+ {
+ case 101:
+ return jjMoveStringLiteralDfa11_0(active0, 0x2000000000000L);
+ default :
+ break;
+ }
+ return jjStartNfa_0(9, active0, 0L);
+}
+private final int jjMoveStringLiteralDfa11_0(long old0, long active0)
+{
+ if (((active0 &= old0)) == 0L)
+ return jjStartNfa_0(9, old0, 0L);
+ try { curChar = input_stream.readChar(); }
+ catch(java.io.IOException e) {
+ jjStopStringLiteralDfa_0(10, active0, 0L);
+ return 11;
+ }
+ switch(curChar)
+ {
+ case 100:
+ if ((active0 & 0x2000000000000L) != 0L)
+ return jjStartNfaWithStates_0(11, 49, 28);
+ break;
+ default :
+ break;
+ }
+ return jjStartNfa_0(10, active0, 0L);
+}
+private final void jjCheckNAdd(int state)
+{
+ if (jjrounds[state] != jjround)
+ {
+ jjstateSet[jjnewStateCnt++] = state;
+ jjrounds[state] = jjround;
+ }
+}
+private final void jjAddStates(int start, int end)
+{
+ do {
+ jjstateSet[jjnewStateCnt++] = jjnextStates[start];
+ } while (start++ != end);
+}
+private final void jjCheckNAddTwoStates(int state1, int state2)
+{
+ jjCheckNAdd(state1);
+ jjCheckNAdd(state2);
+}
+private final void jjCheckNAddStates(int start, int end)
+{
+ do {
+ jjCheckNAdd(jjnextStates[start]);
+ } while (start++ != end);
+}
+private final void jjCheckNAddStates(int start)
+{
+ jjCheckNAdd(jjnextStates[start]);
+ jjCheckNAdd(jjnextStates[start + 1]);
+}
+static final long[] jjbitVec0 = {
+ 0xfffffffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL
+};
+static final long[] jjbitVec2 = {
+ 0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
+};
+static final long[] jjbitVec3 = {
+ 0x1ff00000fffffffeL, 0xffffffffffffc000L, 0xffffffffL, 0x600000000000000L
+};
+static final long[] jjbitVec4 = {
+ 0x0L, 0x0L, 0x0L, 0xff7fffffff7fffffL
+};
+static final long[] jjbitVec5 = {
+ 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL
+};
+static final long[] jjbitVec6 = {
+ 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffL, 0x0L
+};
+static final long[] jjbitVec7 = {
+ 0xffffffffffffffffL, 0xffffffffffffffffL, 0x0L, 0x0L
+};
+static final long[] jjbitVec8 = {
+ 0x3fffffffffffL, 0x0L, 0x0L, 0x0L
+};
+private final int jjMoveNfa_0(int startState, int curPos)
+{
+ int[] nextStates;
+ int startsAt = 0;
+ jjnewStateCnt = 67;
+ int i = 1;
+ jjstateSet[0] = startState;
+ int j, kind = 0x7fffffff;
+ for (;;)
+ {
+ if (++jjround == 0x7fffffff)
+ ReInitRounds();
+ if (curChar < 64)
+ {
+ long l = 1L << curChar;
+ MatchLoop: do
+ {
+ switch(jjstateSet[--i])
+ {
+ case 0:
+ if ((0x3ff000000000000L & l) != 0L)
+ jjCheckNAddStates(0, 6);
+ else if (curChar == 47)
+ jjAddStates(7, 9);
+ else if (curChar == 36)
+ {
+ if (kind > 67)
+ kind = 67;
+ jjCheckNAdd(28);
+ }
+ else if (curChar == 34)
+ jjCheckNAddStates(10, 12);
+ else if (curChar == 39)
+ jjAddStates(13, 14);
+ else if (curChar == 46)
+ jjCheckNAdd(4);
+ if ((0x3fe000000000000L & l) != 0L)
+ {
+ if (kind > 59)
+ kind = 59;
+ jjCheckNAddTwoStates(1, 2);
+ }
+ else if (curChar == 48)
+ {
+ if (kind > 59)
+ kind = 59;
+ jjCheckNAddStates(15, 17);
+ }
+ break;
+ case 49:
+ if (curChar == 42)
+ jjCheckNAddTwoStates(62, 63);
+ else if (curChar == 47)
+ jjCheckNAddStates(18, 20);
+ if (curChar == 42)
+ jjstateSet[jjnewStateCnt++] = 54;
+ break;
+ case 1:
+ if ((0x3ff000000000000L & l) == 0L)
+ break;
+ if (kind > 59)
+ kind = 59;
+ jjCheckNAddTwoStates(1, 2);
+ break;
+ case 3:
+ if (curChar == 46)
+ jjCheckNAdd(4);
+ break;
+ case 4:
+ if ((0x3ff000000000000L & l) == 0L)
+ break;
+ if (kind > 63)
+ kind = 63;
+ jjCheckNAddStates(21, 23);
+ break;
+ case 6:
+ if ((0x280000000000L & l) != 0L)
+ jjCheckNAdd(7);
+ break;
+ case 7:
+ if ((0x3ff000000000000L & l) == 0L)
+ break;
+ if (kind > 63)
+ kind = 63;
+ jjCheckNAddTwoStates(7, 8);
+ break;
+ case 9:
+ if (curChar == 39)
+ jjAddStates(13, 14);
+ break;
+ case 10:
+ if ((0xffffff7fffffdbffL & l) != 0L)
+ jjCheckNAdd(11);
+ break;
+ case 11:
+ if (curChar == 39 && kind > 65)
+ kind = 65;
+ break;
+ case 13:
+ if ((0x8400000000L & l) != 0L)
+ jjCheckNAdd(11);
+ break;
+ case 14:
+ if ((0xff000000000000L & l) != 0L)
+ jjCheckNAddTwoStates(15, 11);
+ break;
+ case 15:
+ if ((0xff000000000000L & l) != 0L)
+ jjCheckNAdd(11);
+ break;
+ case 16:
+ if ((0xf000000000000L & l) != 0L)
+ jjstateSet[jjnewStateCnt++] = 17;
+ break;
+ case 17:
+ if ((0xff000000000000L & l) != 0L)
+ jjCheckNAdd(15);
+ break;
+ case 18:
+ if (curChar == 34)
+ jjCheckNAddStates(10, 12);
+ break;
+ case 19:
+ if ((0xfffffffbffffdbffL & l) != 0L)
+ jjCheckNAddStates(10, 12);
+ break;
+ case 21:
+ if ((0x8400000000L & l) != 0L)
+ jjCheckNAddStates(10, 12);
+ break;
+ case 22:
+ if (curChar == 34 && kind > 66)
+ kind = 66;
+ break;
+ case 23:
+ if ((0xff000000000000L & l) != 0L)
+ jjCheckNAddStates(24, 27);
+ break;
+ case 24:
+ if ((0xff000000000000L & l) != 0L)
+ jjCheckNAddStates(10, 12);
+ break;
+ case 25:
+ if ((0xf000000000000L & l) != 0L)
+ jjstateSet[jjnewStateCnt++] = 26;
+ break;
+ case 26:
+ if ((0xff000000000000L & l) != 0L)
+ jjCheckNAdd(24);
+ break;
+ case 27:
+ if (curChar != 36)
+ break;
+ if (kind > 67)
+ kind = 67;
+ jjCheckNAdd(28);
+ break;
+ case 28:
+ if ((0x3ff001000000000L & l) == 0L)
+ break;
+ if (kind > 67)
+ kind = 67;
+ jjCheckNAdd(28);
+ break;
+ case 29:
+ if ((0x3ff000000000000L & l) != 0L)
+ jjCheckNAddStates(0, 6);
+ break;
+ case 30:
+ if ((0x3ff000000000000L & l) != 0L)
+ jjCheckNAddTwoStates(30, 31);
+ break;
+ case 31:
+ if (curChar != 46)
+ break;
+ if (kind > 63)
+ kind = 63;
+ jjCheckNAddStates(28, 30);
+ break;
+ case 32:
+ if ((0x3ff000000000000L & l) == 0L)
+ break;
+ if (kind > 63)
+ kind = 63;
+ jjCheckNAddStates(28, 30);
+ break;
+ case 34:
+ if ((0x280000000000L & l) != 0L)
+ jjCheckNAdd(35);
+ break;
+ case 35:
+ if ((0x3ff000000000000L & l) == 0L)
+ break;
+ if (kind > 63)
+ kind = 63;
+ jjCheckNAddTwoStates(35, 8);
+ break;
+ case 36:
+ if ((0x3ff000000000000L & l) != 0L)
+ jjCheckNAddTwoStates(36, 37);
+ break;
+ case 38:
+ if ((0x280000000000L & l) != 0L)
+ jjCheckNAdd(39);
+ break;
+ case 39:
+ if ((0x3ff000000000000L & l) == 0L)
+ break;
+ if (kind > 63)
+ kind = 63;
+ jjCheckNAddTwoStates(39, 8);
+ break;
+ case 40:
+ if ((0x3ff000000000000L & l) != 0L)
+ jjCheckNAddStates(31, 33);
+ break;
+ case 42:
+ if ((0x280000000000L & l) != 0L)
+ jjCheckNAdd(43);
+ break;
+ case 43:
+ if ((0x3ff000000000000L & l) != 0L)
+ jjCheckNAddTwoStates(43, 8);
+ break;
+ case 44:
+ if (curChar != 48)
+ break;
+ if (kind > 59)
+ kind = 59;
+ jjCheckNAddStates(15, 17);
+ break;
+ case 46:
+ if ((0x3ff000000000000L & l) == 0L)
+ break;
+ if (kind > 59)
+ kind = 59;
+ jjCheckNAddTwoStates(46, 2);
+ break;
+ case 47:
+ if ((0xff000000000000L & l) == 0L)
+ break;
+ if (kind > 59)
+ kind = 59;
+ jjCheckNAddTwoStates(47, 2);
+ break;
+ case 48:
+ if (curChar == 47)
+ jjAddStates(7, 9);
+ break;
+ case 50:
+ if ((0xffffffffffffdbffL & l) != 0L)
+ jjCheckNAddStates(18, 20);
+ break;
+ case 51:
+ if ((0x2400L & l) != 0L && kind > 6)
+ kind = 6;
+ break;
+ case 52:
+ if (curChar == 10 && kind > 6)
+ kind = 6;
+ break;
+ case 53:
+ if (curChar == 13)
+ jjstateSet[jjnewStateCnt++] = 52;
+ break;
+ case 54:
+ if (curChar == 42)
+ jjCheckNAddTwoStates(55, 56);
+ break;
+ case 55:
+ if ((0xfffffbffffffffffL & l) != 0L)
+ jjCheckNAddTwoStates(55, 56);
+ break;
+ case 56:
+ if (curChar == 42)
+ jjCheckNAddStates(34, 36);
+ break;
+ case 57:
+ if ((0xffff7bffffffffffL & l) != 0L)
+ jjCheckNAddTwoStates(58, 56);
+ break;
+ case 58:
+ if ((0xfffffbffffffffffL & l) != 0L)
+ jjCheckNAddTwoStates(58, 56);
+ break;
+ case 59:
+ if (curChar == 47 && kind > 7)
+ kind = 7;
+ break;
+ case 60:
+ if (curChar == 42)
+ jjstateSet[jjnewStateCnt++] = 54;
+ break;
+ case 61:
+ if (curChar == 42)
+ jjCheckNAddTwoStates(62, 63);
+ break;
+ case 62:
+ if ((0xfffffbffffffffffL & l) != 0L)
+ jjCheckNAddTwoStates(62, 63);
+ break;
+ case 63:
+ if (curChar == 42)
+ jjCheckNAddStates(37, 39);
+ break;
+ case 64:
+ if ((0xffff7bffffffffffL & l) != 0L)
+ jjCheckNAddTwoStates(65, 63);
+ break;
+ case 65:
+ if ((0xfffffbffffffffffL & l) != 0L)
+ jjCheckNAddTwoStates(65, 63);
+ break;
+ case 66:
+ if (curChar == 47 && kind > 8)
+ kind = 8;
+ break;
+ default : break;
+ }
+ } while(i != startsAt);
+ }
+ else if (curChar < 128)
+ {
+ long l = 1L << (curChar & 077);
+ MatchLoop: do
+ {
+ switch(jjstateSet[--i])
+ {
+ case 0:
+ case 28:
+ if ((0x7fffffe87fffffeL & l) == 0L)
+ break;
+ if (kind > 67)
+ kind = 67;
+ jjCheckNAdd(28);
+ break;
+ case 2:
+ if ((0x100000001000L & l) != 0L && kind > 59)
+ kind = 59;
+ break;
+ case 5:
+ if ((0x2000000020L & l) != 0L)
+ jjAddStates(40, 41);
+ break;
+ case 8:
+ if ((0x5000000050L & l) != 0L && kind > 63)
+ kind = 63;
+ break;
+ case 10:
+ if ((0xffffffffefffffffL & l) != 0L)
+ jjCheckNAdd(11);
+ break;
+ case 12:
+ if (curChar == 92)
+ jjAddStates(42, 44);
+ break;
+ case 13:
+ if ((0x14404410000000L & l) != 0L)
+ jjCheckNAdd(11);
+ break;
+ case 19:
+ if ((0xffffffffefffffffL & l) != 0L)
+ jjCheckNAddStates(10, 12);
+ break;
+ case 20:
+ if (curChar == 92)
+ jjAddStates(45, 47);
+ break;
+ case 21:
+ if ((0x14404410000000L & l) != 0L)
+ jjCheckNAddStates(10, 12);
+ break;
+ case 33:
+ if ((0x2000000020L & l) != 0L)
+ jjAddStates(48, 49);
+ break;
+ case 37:
+ if ((0x2000000020L & l) != 0L)
+ jjAddStates(50, 51);
+ break;
+ case 41:
+ if ((0x2000000020L & l) != 0L)
+ jjAddStates(52, 53);
+ break;
+ case 45:
+ if ((0x100000001000000L & l) != 0L)
+ jjCheckNAdd(46);
+ break;
+ case 46:
+ if ((0x7e0000007eL & l) == 0L)
+ break;
+ if (kind > 59)
+ kind = 59;
+ jjCheckNAddTwoStates(46, 2);
+ break;
+ case 50:
+ jjAddStates(18, 20);
+ break;
+ case 55:
+ jjCheckNAddTwoStates(55, 56);
+ break;
+ case 57:
+ case 58:
+ jjCheckNAddTwoStates(58, 56);
+ break;
+ case 62:
+ jjCheckNAddTwoStates(62, 63);
+ break;
+ case 64:
+ case 65:
+ jjCheckNAddTwoStates(65, 63);
+ break;
+ default : break;
+ }
+ } while(i != startsAt);
+ }
+ else
+ {
+ int hiByte = (int)(curChar >> 8);
+ int i1 = hiByte >> 6;
+ long l1 = 1L << (hiByte & 077);
+ int i2 = (curChar & 0xff) >> 6;
+ long l2 = 1L << (curChar & 077);
+ MatchLoop: do
+ {
+ switch(jjstateSet[--i])
+ {
+ case 0:
+ case 28:
+ if (!jjCanMove_1(hiByte, i1, i2, l1, l2))
+ break;
+ if (kind > 67)
+ kind = 67;
+ jjCheckNAdd(28);
+ break;
+ case 10:
+ if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+ jjstateSet[jjnewStateCnt++] = 11;
+ break;
+ case 19:
+ if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+ jjAddStates(10, 12);
+ break;
+ case 50:
+ if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+ jjAddStates(18, 20);
+ break;
+ case 55:
+ if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+ jjCheckNAddTwoStates(55, 56);
+ break;
+ case 57:
+ case 58:
+ if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+ jjCheckNAddTwoStates(58, 56);
+ break;
+ case 62:
+ if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+ jjCheckNAddTwoStates(62, 63);
+ break;
+ case 64:
+ case 65:
+ if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+ jjCheckNAddTwoStates(65, 63);
+ break;
+ default : break;
+ }
+ } while(i != startsAt);
+ }
+ if (kind != 0x7fffffff)
+ {
+ jjmatchedKind = kind;
+ jjmatchedPos = curPos;
+ kind = 0x7fffffff;
+ }
+ ++curPos;
+ if ((i = jjnewStateCnt) == (startsAt = 67 - (jjnewStateCnt = startsAt)))
+ return curPos;
+ try { curChar = input_stream.readChar(); }
+ catch(java.io.IOException e) { return curPos; }
+ }
+}
+static final int[] jjnextStates = {
+ 30, 31, 36, 37, 40, 41, 8, 49, 60, 61, 19, 20, 22, 10, 12, 45,
+ 47, 2, 50, 51, 53, 4, 5, 8, 19, 20, 24, 22, 32, 33, 8, 40,
+ 41, 8, 56, 57, 59, 63, 64, 66, 6, 7, 13, 14, 16, 21, 23, 25,
+ 34, 35, 38, 39, 42, 43,
+};
+private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, long l2)
+{
+ switch(hiByte)
+ {
+ case 0:
+ return ((jjbitVec2[i2] & l2) != 0L);
+ default :
+ if ((jjbitVec0[i1] & l1) != 0L)
+ return true;
+ return false;
+ }
+}
+private static final boolean jjCanMove_1(int hiByte, int i1, int i2, long l1, long l2)
+{
+ switch(hiByte)
+ {
+ case 0:
+ return ((jjbitVec4[i2] & l2) != 0L);
+ case 48:
+ return ((jjbitVec5[i2] & l2) != 0L);
+ case 49:
+ return ((jjbitVec6[i2] & l2) != 0L);
+ case 51:
+ return ((jjbitVec7[i2] & l2) != 0L);
+ case 61:
+ return ((jjbitVec8[i2] & l2) != 0L);
+ default :
+ if ((jjbitVec3[i1] & l1) != 0L)
+ return true;
+ return false;
+ }
+}
+public static final String[] jjstrLiteralImages = {
+"", null, null, null, null, null, null, null, null,
+"\141\142\163\164\162\141\143\164", "\142\157\157\154\145\141\156",
"\142\162\145\141\153", "\142\171\164\145",
+"\143\141\163\145", "\143\141\164\143\150",
"\143\150\141\162", "\143\154\141\163\163",
+"\143\157\156\163\164", "\143\157\156\164\151\156\165\145",
"\144\145\146\141\165\154\164",
+"\144\157", "\144\157\165\142\154\145", "\145\154\163\145",
+"\145\170\164\145\156\144\163", "\146\141\154\163\145",
"\146\151\156\141\154",
+"\146\151\156\141\154\154\171", "\146\154\157\141\164",
"\146\157\162", "\147\157\164\157", "\151\146",
+"\151\155\160\154\145\155\145\156\164\163",
"\151\155\160\157\162\164",
"\151\156\163\164\141\156\143\145\157\146",
+"\151\156\164", "\151\156\164\145\162\146\141\143\145",
"\154\157\156\147",
+"\156\141\164\151\166\145", "\156\145\167",
"\156\165\154\154", "\160\141\143\153\141\147\145",
+"\160\162\151\166\141\164\145",
"\160\162\157\164\145\143\164\145\144", "\160\165\142\154\151\143",
+"\162\145\164\165\162\156", "\163\150\157\162\164",
"\163\164\141\164\151\143", "\163\165\160\145\162",
+"\163\167\151\164\143\150",
"\163\171\156\143\150\162\157\156\151\172\145\144",
"\164\150\151\163",
+"\164\150\162\157\167", "\164\150\162\157\167\163",
"\164\162\141\156\163\151\145\156\164",
+"\164\162\165\145", "\164\162\171", "\166\157\151\144",
"\166\157\154\141\164\151\154\145",
+"\167\150\151\154\145", null, null, null, null, null, null, null, null, null,
null, null, "\50",
+"\51", "\173", "\175", "\133", "\135",
"\73", "\54", "\56", "\75", "\76",
"\74",
+"\41", "\176", "\77", "\72", "\75\75",
"\74\75", "\76\75", "\41\75", "\174\174",
+"\46\46", "\53\53", "\55\55", "\53",
"\55", "\52", "\57", "\46", "\174",
"\136", "\45",
+"\74\74", "\76\76", "\76\76\76", "\53\75",
"\55\75", "\52\75", "\57\75", "\46\75",
+"\174\75", "\136\75", "\45\75", "\74\74\75",
"\76\76\75", "\76\76\76\75", };
+public static final String[] lexStateNames = {
+ "DEFAULT",
+};
+static final long[] jjtoToken = {
+ 0x8ffffffffffffe01L, 0xfffffffffffceL,
+};
+static final long[] jjtoSkip = {
+ 0x1feL, 0x0L,
+};
+static final long[] jjtoSpecial = {
+ 0x1c0L, 0x0L,
+};
+private ASCII_UCodeESC_CharStream input_stream;
+private final int[] jjrounds = new int[67];
+private final int[] jjstateSet = new int[134];
+protected char curChar;
+public ExpressionParserTokenManager(ASCII_UCodeESC_CharStream stream)
+{
+ if (ASCII_UCodeESC_CharStream.staticFlag)
+ throw new Error("ERROR: Cannot use a static CharStream class with a non-static
lexical analyzer.");
+ input_stream = stream;
+}
+public ExpressionParserTokenManager(ASCII_UCodeESC_CharStream stream, int lexState)
+{
+ this(stream);
+ SwitchTo(lexState);
+}
+public void ReInit(ASCII_UCodeESC_CharStream stream)
+{
+ jjmatchedPos = jjnewStateCnt = 0;
+ curLexState = defaultLexState;
+ input_stream = stream;
+ ReInitRounds();
+}
+private final void ReInitRounds()
+{
+ int i;
+ jjround = 0x80000001;
+ for (i = 67; i-- > 0;)
+ jjrounds[i] = 0x80000000;
+}
+public void ReInit(ASCII_UCodeESC_CharStream stream, int lexState)
+{
+ ReInit(stream);
+ SwitchTo(lexState);
+}
+public void SwitchTo(int lexState)
+{
+ if (lexState >= 1 || lexState < 0)
+ throw new TokenMgrError("Error: Ignoring invalid lexical state : " +
lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
+ else
+ curLexState = lexState;
+}
+
+private final Token jjFillToken()
+{
+ Token t = Token.newToken(jjmatchedKind);
+ t.kind = jjmatchedKind;
+ String im = jjstrLiteralImages[jjmatchedKind];
+ t.image = (im == null) ? input_stream.GetImage() : im;
+ t.beginLine = input_stream.getBeginLine();
+ t.beginColumn = input_stream.getBeginColumn();
+ t.endLine = input_stream.getEndLine();
+ t.endColumn = input_stream.getEndColumn();
+ return t;
+}
+
+int curLexState = 0;
+int defaultLexState = 0;
+int jjnewStateCnt;
+int jjround;
+int jjmatchedPos;
+int jjmatchedKind;
+
+public final Token getNextToken()
+{
+ int kind;
+ Token specialToken = null;
+ Token matchedToken;
+ int curPos = 0;
+
+ EOFLoop :
+ for (;;)
+ {
+ try
+ {
+ curChar = input_stream.BeginToken();
+ }
+ catch(java.io.IOException e)
+ {
+ jjmatchedKind = 0;
+ matchedToken = jjFillToken();
+ matchedToken.specialToken = specialToken;
+ return matchedToken;
+ }
+
+ try {
+ while (curChar <= 32 && (0x100003600L & (1L << curChar)) !=
0L)
+ curChar = input_stream.BeginToken();
+ }
+ catch (java.io.IOException e1) { continue EOFLoop; }
+ jjmatchedKind = 0x7fffffff;
+ jjmatchedPos = 0;
+ curPos = jjMoveStringLiteralDfa0_0();
+ if (jjmatchedKind != 0x7fffffff)
+ {
+ if (jjmatchedPos + 1 < curPos)
+ input_stream.backup(curPos - jjmatchedPos - 1);
+ if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind &
077))) != 0L)
+ {
+ matchedToken = jjFillToken();
+ matchedToken.specialToken = specialToken;
+ return matchedToken;
+ }
+ else
+ {
+ if ((jjtoSpecial[jjmatchedKind >> 6] & (1L << (jjmatchedKind
& 077))) != 0L)
+ {
+ matchedToken = jjFillToken();
+ if (specialToken == null)
+ specialToken = matchedToken;
+ else
+ {
+ matchedToken.specialToken = specialToken;
+ specialToken = (specialToken.next = matchedToken);
+ }
+ }
+ continue EOFLoop;
+ }
+ }
+ int error_line = input_stream.getEndLine();
+ int error_column = input_stream.getEndColumn();
+ String error_after = null;
+ boolean EOFSeen = false;
+ try { input_stream.readChar(); input_stream.backup(1); }
+ catch (java.io.IOException e1) {
+ EOFSeen = true;
+ error_after = curPos <= 1 ? "" : input_stream.GetImage();
+ if (curChar == '\n' || curChar == '\r') {
+ error_line++;
+ error_column = 0;
+ }
+ else
+ error_column++;
+ }
+ if (!EOFSeen) {
+ input_stream.backup(1);
+ error_after = curPos <= 1 ? "" : input_stream.GetImage();
+ }
+ throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after,
curChar, TokenMgrError.LEXICAL_ERROR);
+ }
+}
+
+}
Index: xemacs-packages/jde/java/src/jde/debugger/expr/LValue.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/expr/LValue.java,v
retrieving revision 1.1
diff -u -r1.1 LValue.java
--- xemacs-packages/jde/java/src/jde/debugger/expr/LValue.java 2000/08/13 13:36:58 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/expr/LValue.java 2001/08/15 05:27:50
@@ -1,779 +1,778 @@
-/*
- * @(#)LValue.java 1.17 99/05/21
- *
- * Copyright (c) 1997-1999 by Sun Microsystems, Inc. All Rights Reserved.
- *
- * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
- * modify and redistribute this software in source and binary code form,
- * provided that i) this copyright notice and license appear on all copies of
- * the software; and ii) Licensee does not utilize the software in a manner
- * which is disparaging to Sun.
- *
- * This software is provided "AS IS," without a warranty of any kind. ALL
- * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
- * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
- * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
- * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
- * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
- * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
- * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
- * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
- * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGES.
- *
- * This software is not designed or intended for use in on-line control of
- * aircraft, air traffic, aircraft navigation or aircraft communications; or in
- * the design, construction, operation or maintenance of any nuclear
- * facility. Licensee represents and warrants that it will not use or
- * redistribute the Software for such purposes.
- */
-
-package jde.debugger.expr;
-
-import com.sun.jdi.*;
-import java.util.*;
-import com.sun.jdi.Value;
-
-abstract class LValue {
-
- abstract Value getValue() throws InvocationException,
- IncompatibleThreadStateException,
- InvalidTypeException,
- ClassNotLoadedException;
-
- abstract void setValue0(Value value)
- throws ParseException, InvalidTypeException,
- ClassNotLoadedException;
-
- abstract void invokeWith(List arguments) throws ParseException;
-
- void setValue(Value value) throws ParseException {
- try {
- setValue0(value);
- } catch (InvalidTypeException exc) {
- throw new ParseException(
- "Attempt to set value of incorrect type" +
- exc);
- } catch (ClassNotLoadedException exc) {
- throw new ParseException(
- "Attempt to set value before " + exc.className() + " was
loaded" +
- exc);
- }
- }
-
- void setValue(LValue lval) throws ParseException {
- setValue(lval.interiorGetValue());
- }
-
- LValue memberLValue(ExpressionParser.GetFrame frameGetter,
- String fieldName) throws ParseException {
- try {
- return memberLValue(fieldName, frameGetter.get().thread());
- } catch (IncompatibleThreadStateException exc) {
- throw new ParseException("Thread not suspended");
- }
- }
-
- LValue memberLValue(String fieldName, ThreadReference thread) throws ParseException
{
- return new LValueInstanceMember(interiorGetValue(), fieldName, thread);
- }
-
- Value interiorGetValue() throws ParseException {
- Value value;
- try {
- value = getValue();
- } catch (InvocationException e) {
- throw new ParseException("Unable to complete expression. Exception
" +
- e.exception() + " thrown");
- } catch (IncompatibleThreadStateException itse) {
- throw new ParseException("Unable to complete expression. Thread "
+
- "not suspended for method invoke");
- } catch (InvalidTypeException ite) {
- throw new ParseException("Unable to complete expression. Method "
+
- "argument type mismatch");
- } catch (ClassNotLoadedException tnle) {
- throw new ParseException("Unable to complete expression. Method "
+
- "argument type " + tnle.className() +
- " not yet loaded");
- }
-// if (value == null) {
-// throw new ParseException("Cannot invoke a void method within an
expression");
-// }
- return value;
- }
-
- LValue arrayElementLValue(LValue lval) throws ParseException {
- Value indexValue = lval.interiorGetValue();
- int index;
- if ( (indexValue instanceof IntegerValue) ||
- (indexValue instanceof ShortValue) ||
- (indexValue instanceof ByteValue) ||
- (indexValue instanceof CharValue) ) {
- index = ((PrimitiveValue)indexValue).intValue();
- } else {
- throw new ParseException("Array index must be a integer type");
- }
- return new LValueArrayElement(interiorGetValue(), index);
- }
-
- public String toString() {
- try {
- return interiorGetValue().toString();
- } catch (ParseException e) {
- return "<Parse Exception>";
- }
- }
-
- static final int STATIC = 0;
- static final int INSTANCE = 1;
-
- static Field fieldByName(ReferenceType refType, String name, int kind) {
- /*
- * TO DO: Note that this currently fails to find superclass
- * or implemented interface fields. This is due to a temporary
- * limititation of RefType.fieldByName. Once that method is
- * fixed, superclass fields will be found.
- */
- Field field = refType.fieldByName(name);
- if (field != null) {
- boolean isStatic = field.isStatic();
- if (((kind == STATIC) && !isStatic) ||
- ((kind == INSTANCE) && isStatic)) {
- field = null;
- }
- }
-/***
- System.err.println("fieldByName: " + refType.name() + " " +
- name + " " +
- kind + " " +
- (field != null));
-***/
- return field;
- }
-
- static List methodsByName(ReferenceType refType, String name, int kind) {
- List list = refType.methodsByName(name);
- Iterator iter = list.iterator();
- while (iter.hasNext()) {
- Method method = (Method)iter.next();
- boolean isStatic = method.isStatic();
- if (((kind == STATIC) && !isStatic) ||
- ((kind == INSTANCE) && isStatic)) {
- iter.remove();
- }
- }
- return list;
- }
-
- static List primitiveTypeNames = new ArrayList();
- static {
- primitiveTypeNames.add("boolean");
- primitiveTypeNames.add("byte");
- primitiveTypeNames.add("char");
- primitiveTypeNames.add("short");
- primitiveTypeNames.add("int");
- primitiveTypeNames.add("long");
- primitiveTypeNames.add("float");
- primitiveTypeNames.add("double");
- }
-
- static boolean argumentsMatch(List argNames, List arguments) {
- if (argNames.size() != arguments.size()) {
- return false;
- }
- Iterator nameIter = argNames.iterator();
- Iterator valIter = arguments.iterator();
- while (nameIter.hasNext()) {
- String argTypeName = (String)nameIter.next();
- Value value = (Value)valIter.next();
- /*
- * For now we require exact match
- */
- if (value == null) {
- // Null values can be passed to any non-primitive argument
- if (primitiveTypeNames.contains(argTypeName)) {
- return false;
- }
- } else if (!argTypeName.equals(value.type().name())) {
- return false;
- }
- }
- return true;
- }
-
- static Method resolveOverload(List overloads, List arguments)
- throws ParseException {
- Iterator iter = overloads.iterator();
- while (iter.hasNext()) {
- Method method = (Method)iter.next();
- List argNames = method.argumentTypeNames();
- if (argumentsMatch(argNames, arguments)) {
- return method;
- }
- }
- throw new ParseException("Arguments match no method");
- }
-
- private static class LValueLocal extends LValue {
- final StackFrame frame;
- final LocalVariable var;
-
- LValueLocal(StackFrame frame, LocalVariable var) {
- this.frame = frame;
- this.var = var;
- }
-
- Value getValue() {
- return frame.getValue(var);
- }
-
- void setValue0(Value val) throws InvalidTypeException,
- ClassNotLoadedException {
- frame.setValue(var, val);
- }
-
- void invokeWith(List arguments) throws ParseException {
- throw new ParseException(var.name() + " is not a method");
- }
- }
-
- private static class LValueInstanceMember extends LValue {
- final ObjectReference obj;
- final ThreadReference thread;
- final Field matchingField;
- final List overloads;
- Method matchingMethod = null;
- List methodArguments = null;
-
- LValueInstanceMember(Value value,
- String memberName,
- ThreadReference thread) throws ParseException {
- if (!(value instanceof ObjectReference)) {
- throw new ParseException(
- "Cannot access field of primitive type: " + value);
- }
- this.obj = (ObjectReference)value;
- this.thread = thread;
- ReferenceType refType = obj.referenceType();
- /*
- * Can't tell yet whether this LValue will be accessed as a
- * field or method, so we keep track of all the possibilities
- */
- matchingField = LValue.fieldByName(refType, memberName,
- LValue.INSTANCE);
- overloads = LValue.methodsByName(refType, memberName,
- LValue.INSTANCE);
- if ((matchingField == null) && overloads.size() == 0) {
- throw new ParseException("No instance field or method with the name
"
- + memberName + " in " + refType.name());
- }
- }
-
- Value getValue() throws InvocationException, InvalidTypeException,
- ClassNotLoadedException, IncompatibleThreadStateException
{
- if (matchingMethod == null) {
- return obj.getValue(matchingField);
- } else {
- return obj.invokeMethod(thread, matchingMethod, methodArguments, 0);
- }
- }
-
- void setValue0(Value val) throws ParseException,
- InvalidTypeException,
- ClassNotLoadedException {
- if (matchingMethod != null) {
- throw new ParseException("Cannot assign to a method
invocation");
- }
- obj.setValue(matchingField, val);
- }
-
- void invokeWith(List arguments) throws ParseException {
- if (matchingMethod != null) {
- throw new ParseException("Invalid consecutive invocations");
- }
- methodArguments = arguments;
- matchingMethod = LValue.resolveOverload(overloads, arguments);
- }
- }
-
- private static class LValueStaticMember extends LValue {
- final ReferenceType refType;
- final ThreadReference thread;
- final Field matchingField;
- final List overloads;
- Method matchingMethod = null;
- List methodArguments = null;
-
- LValueStaticMember(ReferenceType refType,
- String memberName,
- ThreadReference thread) throws ParseException {
- this.refType = refType;
- this.thread = thread;
- /*
- * Can't tell yet whether this LValue will be accessed as a
- * field or method, so we keep track of all the possibilities
- */
- matchingField = LValue.fieldByName(refType, memberName,
- LValue.STATIC);
- overloads = LValue.methodsByName(refType, memberName,
- LValue.STATIC);
- if ((matchingField == null) && overloads.size() == 0) {
- throw new ParseException("No static field or method with the name
"
- + memberName + " in " + refType.name());
- }
- }
-
- Value getValue() throws InvocationException, InvalidTypeException,
- ClassNotLoadedException, IncompatibleThreadStateException
{
- if (matchingMethod == null) {
- return refType.getValue(matchingField);
- } else if (refType instanceof ClassType) {
- ClassType clazz = (ClassType)refType;
- return clazz.invokeMethod(thread, matchingMethod, methodArguments, 0);
- } else {
- throw new InvalidTypeException("Cannot invoke static method on
" +
- refType.name());
- }
- }
-
- void setValue0(Value val)
- throws ParseException, InvalidTypeException,
- ClassNotLoadedException {
- if (matchingMethod != null) {
- throw new ParseException("Cannot assign to a method
invocation");
- }
- if (!(refType instanceof ClassType)) {
- throw new ParseException(
- "Cannot set interface field: " + refType);
- }
- ((ClassType)refType).setValue(matchingField, val);
- }
-
- void invokeWith(List arguments) throws ParseException {
- if (matchingMethod != null) {
- throw new ParseException("Invalid consecutive invocations");
- }
- methodArguments = arguments;
- matchingMethod = LValue.resolveOverload(overloads, arguments);
- }
- }
-
- private static class LValueArrayElement extends LValue {
- final ArrayReference array;
- final int index;
-
- LValueArrayElement(Value value, int index) throws ParseException {
- if (!(value instanceof ArrayReference)) {
- throw new ParseException(
- "Must be array type: " + value);
- }
- this.array = (ArrayReference)value;
- this.index = index;
- }
-
- Value getValue() {
- return array.getValue(index);
- }
-
- void setValue0(Value val) throws InvalidTypeException,
- ClassNotLoadedException {
- array.setValue(index, val);
- }
-
- void invokeWith(List arguments) throws ParseException {
- throw new ParseException("Array element is not a method");
- }
- }
-
- private static class LValueConstant extends LValue {
- final Value value;
-
- LValueConstant(Value value) {
- this.value = value;
- }
-
- Value getValue() {
- return value;
- }
-
- void setValue0(Value val) throws ParseException {
- throw new ParseException("Cannot set constant: " + value);
- }
-
- void invokeWith(List arguments) throws ParseException {
- throw new ParseException("Constant is not a method");
- }
- }
-
- static LValue make(VirtualMachine vm, boolean val) {
- return new LValueConstant(vm.mirrorOf(val));
- }
-
- static LValue make(VirtualMachine vm, byte val) {
- return new LValueConstant(vm.mirrorOf(val));
- }
-
- static LValue make(VirtualMachine vm, char val) {
- return new LValueConstant(vm.mirrorOf(val));
- }
-
- static LValue make(VirtualMachine vm, short val) {
- return new LValueConstant(vm.mirrorOf(val));
- }
-
- static LValue make(VirtualMachine vm, int val) {
- return new LValueConstant(vm.mirrorOf(val));
- }
-
- static LValue make(VirtualMachine vm, long val) {
- return new LValueConstant(vm.mirrorOf(val));
- }
-
- static LValue make(VirtualMachine vm, float val) {
- return new LValueConstant(vm.mirrorOf(val));
- }
-
- static LValue make(VirtualMachine vm, double val) {
- return new LValueConstant(vm.mirrorOf(val));
- }
-
- static LValue make(VirtualMachine vm, String val) throws ParseException {
- return new LValueConstant(vm.mirrorOf(val));
- }
-
- static LValue makeBoolean(VirtualMachine vm, Token token) {
- return make(vm, token.image.charAt(0) == 't');
- }
-
- static LValue makeCharacter(VirtualMachine vm, Token token) {
- return make(vm, token.image.charAt(1));
- }
-
- static LValue makeFloat(VirtualMachine vm, Token token) {
- return make(vm, Float.valueOf(token.image).floatValue());
- }
-
- static LValue makeDouble(VirtualMachine vm, Token token) {
- return make(vm, Double.valueOf(token.image).doubleValue());
- }
-
- static LValue makeInteger(VirtualMachine vm, Token token) {
- return make(vm, Integer.parseInt(token.image));
- }
-
- static LValue makeShort(VirtualMachine vm, Token token) {
- return make(vm, Short.parseShort(token.image));
- }
-
- static LValue makeLong(VirtualMachine vm, Token token) {
- return make(vm, Long.parseLong(token.image));
- }
-
- static LValue makeByte(VirtualMachine vm, Token token) {
- return make(vm, Byte.parseByte(token.image));
- }
-
- static LValue makeString(VirtualMachine vm,
- Token token) throws ParseException {
- int len = token.image.length();
- return make(vm, token.image.substring(1,len-1));
- }
-
- static LValue makeNull(VirtualMachine vm,
- Token token) throws ParseException {
- return new LValueConstant(null);
- }
-
- static LValue makeThisObject(VirtualMachine vm,
- ExpressionParser.GetFrame frameGetter,
- Token token) throws ParseException {
- if (frameGetter == null) {
- throw new ParseException("No current thread");
- } else {
- try {
- StackFrame frame = frameGetter.get();
- ObjectReference thisObject = frame.thisObject();
- if (thisObject == null) {
- throw new ParseException(
- "No 'this'. In native or static method");
- } else {
- return new LValueConstant(thisObject);
- }
- } catch (IncompatibleThreadStateException exc) {
- throw new ParseException("Thread not suspended");
- }
- }
- }
-
- static LValue makeNewObject(VirtualMachine vm,
- ExpressionParser.GetFrame frameGetter,
- String className, List arguments) throws ParseException
{
- List classes = vm.classesByName(className);
- if (classes.size() == 0) {
- throw new ParseException("No class named: " + className);
- }
-
- if (classes.size() > 1) {
- throw new ParseException("More than one class named: " +
- className);
- }
- ReferenceType refType = (ReferenceType)classes.get(0);
-
-
- if (!(refType instanceof ClassType)) {
- throw new ParseException("Cannot create instance of interface " +
- className);
- }
-
- ClassType classType = (ClassType)refType;
- List methods = new ArrayList(classType.methods()); // writable
- Iterator iter = methods.iterator();
- while (iter.hasNext()) {
- Method method = (Method)iter.next();
- if (!method.isConstructor()) {
- iter.remove();
- }
- }
- Method constructor = LValue.resolveOverload(methods, arguments);
-
- ObjectReference newObject;
- try {
- ThreadReference thread = frameGetter.get().thread();
- newObject = classType.newInstance(thread, constructor, arguments, 0);
- } catch (InvocationException ie) {
- throw new ParseException("Exception in " + className + "
constructor: " +
- ie.exception().referenceType().name());
- } catch (IncompatibleThreadStateException exc) {
- throw new ParseException("Thread not suspended");
- } catch (Exception e) {
- /*
- * TO DO: Better error handling
- */
- throw new ParseException("Unable to create " + className + "
instance");
- }
- return new LValueConstant(newObject);
- }
-
- private static LValue nFields(LValue lval,
- StringTokenizer izer,
- ThreadReference thread)
- throws ParseException {
- if (!izer.hasMoreTokens()) {
- return lval;
- } else {
- return nFields(lval.memberLValue(izer.nextToken(), thread), izer, thread);
- }
- }
-
- static LValue makeName(VirtualMachine vm,
- ExpressionParser.GetFrame frameGetter,
- String name) throws ParseException {
- StringTokenizer izer = new StringTokenizer(name, ".");
- String first = izer.nextToken();
-
- // check local variables
- if (frameGetter != null) {
- try {
- StackFrame frame = frameGetter.get();
- ThreadReference thread = frame.thread();
- LocalVariable var;
- try {
- var = frame.visibleVariableByName(first);
- } catch (AbsentInformationException e) {
- var = null;
- }
- if (var != null) {
- return nFields(new LValueLocal(frame, var), izer, thread);
- } else {
- ObjectReference thisObject = frame.thisObject();
- if (thisObject != null) {
- // check if it is a field of 'this'
- LValue thisLValue = new LValueConstant(thisObject);
- LValue fv;
- try {
- fv = thisLValue.memberLValue(first, thread);
- } catch (ParseException exc) {
- fv = null;
- }
- if (fv != null) {
- return nFields(fv, izer, thread);
- }
- }
- }
- // check for class name
- while (izer.hasMoreTokens()) {
- List classes = vm.classesByName(first);
- if (classes.size() > 0) {
- if (classes.size() > 1) {
- throw new ParseException("More than one class named:
" +
- first);
- } else {
- ReferenceType refType = (ReferenceType)classes.get(0);
- LValue lval = new LValueStaticMember(refType,
- izer.nextToken(), thread);
- return nFields(lval, izer, thread);
- }
- }
- first = first + '.' + izer.nextToken();
- }
- } catch (IncompatibleThreadStateException exc) {
- throw new ParseException("Thread not suspended");
- }
- }
- throw new ParseException("Name unknown: " + name);
- }
-
- static String stringValue(Value val) {
- if (val instanceof StringReference) {
- return ((StringReference)val).value();
- } else if (val instanceof ObjectReference) {
- return ((ObjectReference)val).toString(); // TODO
- } else if (val == null) {
- return "null";
- } else {
- return val.toString(); // TODO not correct in all cases
- }
- }
-
- static LValue booleanOperation(VirtualMachine vm, Token token,
- LValue rightL,
- LValue leftL) throws ParseException {
- String op = token.image;
- Value right = rightL.interiorGetValue();
- Value left = leftL.interiorGetValue();
- if ( !(right instanceof PrimitiveValue) ||
- !(left instanceof PrimitiveValue) ) {
- if (op.equals("==")) {
- return make(vm, right.equals(left));
- } else if (op.equals("!=")) {
- return make(vm, !right.equals(left));
- } else {
- throw new ParseException("Operands or '" + op +
- "' must be primitive");
- }
- }
- // can compare any numeric doubles
- double rr = ((PrimitiveValue)right).doubleValue();
- double ll = ((PrimitiveValue)left).doubleValue();
- boolean res;
- if (op.equals("<")) {
- res = rr < ll;
- } else if (op.equals(">")) {
- res = rr > ll;
- } else if (op.equals("<=")) {
- res = rr <= ll;
- } else if (op.equals(">=")) {
- res = rr >= ll;
- } else if (op.equals("==")) {
- res = rr == ll;
- } else if (op.equals("!=")) {
- res = rr != ll;
- } else {
- throw new ParseException("Unknown operation: " + op);
- }
- return make(vm, res);
- }
-
- static LValue operation(VirtualMachine vm, Token token,
- LValue rightL,
- LValue leftL) throws ParseException {
- String op = token.image;
- Value right = rightL.interiorGetValue();
- Value left = leftL.interiorGetValue();
- if ((right instanceof StringReference) ||
- (left instanceof StringReference)) {
- if (op.equals("+")) {
- return make(vm, stringValue(right) + stringValue(left));
- }
- }
- if ((right instanceof ObjectReference) ||
- (left instanceof ObjectReference)) {
- if (op.equals("==")) {
- return make(vm, right.equals(left));
- } else if (op.equals("!=")) {
- return make(vm, !right.equals(left));
- } else {
- throw new ParseException("Invalid operation '" +
- op + "' on an Object");
- }
- }
- if ((right instanceof BooleanValue) ||
- (left instanceof BooleanValue)) {
- throw new ParseException("Invalid operation '" +
- op + "' on a Boolean");
- }
- // from here on, we know it is a integer kind of type
- PrimitiveValue primRight = (PrimitiveValue)right;
- PrimitiveValue primLeft = (PrimitiveValue)left;
- if ((primRight instanceof DoubleValue) ||
- (primLeft instanceof DoubleValue)) {
- double rr = primRight.doubleValue();
- double ll = primLeft.doubleValue();
- double res;
- if (op.equals("+")) {
- res = rr + ll;
- } else if (op.equals("-")) {
- res = rr - ll;
- } else if (op.equals("*")) {
- res = rr * ll;
- } else if (op.equals("/")) {
- res = rr / ll;
- } else {
- throw new ParseException("Unknown operation: " + op);
- }
- return make(vm, res);
- }
- if ((primRight instanceof FloatValue) ||
- (primLeft instanceof FloatValue)) {
- float rr = primRight.floatValue();
- float ll = primLeft.floatValue();
- float res;
- if (op.equals("+")) {
- res = rr + ll;
- } else if (op.equals("-")) {
- res = rr - ll;
- } else if (op.equals("*")) {
- res = rr * ll;
- } else if (op.equals("/")) {
- res = rr / ll;
- } else {
- throw new ParseException("Unknown operation: " + op);
- }
- return make(vm, res);
- }
- if ((primRight instanceof LongValue) ||
- (primLeft instanceof LongValue)) {
- long rr = primRight.longValue();
- long ll = primLeft.longValue();
- long res;
- if (op.equals("+")) {
- res = rr + ll;
- } else if (op.equals("-")) {
- res = rr - ll;
- } else if (op.equals("*")) {
- res = rr * ll;
- } else if (op.equals("/")) {
- res = rr / ll;
- } else {
- throw new ParseException("Unknown operation: " + op);
- }
- return make(vm, res);
- } else {
- int rr = primRight.intValue();
- int ll = primLeft.intValue();
- int res;
- if (op.equals("+")) {
- res = rr + ll;
- } else if (op.equals("-")) {
- res = rr - ll;
- } else if (op.equals("*")) {
- res = rr * ll;
- } else if (op.equals("/")) {
- res = rr / ll;
- } else {
- throw new ParseException("Unknown operation: " + op);
- }
- return make(vm, res);
- }
- }
-}
+/*
+ * @(#)LValue.java 1.17 99/05/21
+ *
+ * Copyright (c) 1997-1999 by Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
+ * modify and redistribute this software in source and binary code form,
+ * provided that i) this copyright notice and license appear on all copies of
+ * the software; and ii) Licensee does not utilize the software in a manner
+ * which is disparaging to Sun.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
+ * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
+ * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
+ * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
+ * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
+ * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
+ * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * This software is not designed or intended for use in on-line control of
+ * aircraft, air traffic, aircraft navigation or aircraft communications; or in
+ * the design, construction, operation or maintenance of any nuclear
+ * facility. Licensee represents and warrants that it will not use or
+ * redistribute the Software for such purposes.
+ */
+
+package jde.debugger.expr;
+
+import com.sun.jdi.*;
+import java.util.*;
+
+abstract class LValue {
+
+ abstract Value getValue() throws InvocationException,
+ IncompatibleThreadStateException,
+ InvalidTypeException,
+ ClassNotLoadedException;
+
+ abstract void setValue0(Value value)
+ throws ParseException, InvalidTypeException,
+ ClassNotLoadedException;
+
+ abstract void invokeWith(List arguments) throws ParseException;
+
+ void setValue(Value value) throws ParseException {
+ try {
+ setValue0(value);
+ } catch (InvalidTypeException exc) {
+ throw new ParseException(
+ "Attempt to set value of incorrect type" +
+ exc);
+ } catch (ClassNotLoadedException exc) {
+ throw new ParseException(
+ "Attempt to set value before " + exc.className() + " was
loaded" +
+ exc);
+ }
+ }
+
+ void setValue(LValue lval) throws ParseException {
+ setValue(lval.interiorGetValue());
+ }
+
+ LValue memberLValue(ExpressionParser.GetFrame frameGetter,
+ String fieldName) throws ParseException {
+ try {
+ return memberLValue(fieldName, frameGetter.get().thread());
+ } catch (IncompatibleThreadStateException exc) {
+ throw new ParseException("Thread not suspended");
+ }
+ }
+
+ LValue memberLValue(String fieldName, ThreadReference thread) throws ParseException
{
+ return new LValueInstanceMember(interiorGetValue(), fieldName, thread);
+ }
+
+ Value interiorGetValue() throws ParseException {
+ Value value;
+ try {
+ value = getValue();
+ } catch (InvocationException e) {
+ throw new ParseException("Unable to complete expression. Exception
" +
+ e.exception() + " thrown");
+ } catch (IncompatibleThreadStateException itse) {
+ throw new ParseException("Unable to complete expression. Thread "
+
+ "not suspended for method invoke");
+ } catch (InvalidTypeException ite) {
+ throw new ParseException("Unable to complete expression. Method "
+
+ "argument type mismatch");
+ } catch (ClassNotLoadedException tnle) {
+ throw new ParseException("Unable to complete expression. Method "
+
+ "argument type " + tnle.className() +
+ " not yet loaded");
+ }
+// if (value == null) {
+// throw new ParseException("Cannot invoke a void method within an
expression");
+// }
+ return value;
+ }
+
+ LValue arrayElementLValue(LValue lval) throws ParseException {
+ Value indexValue = lval.interiorGetValue();
+ int index;
+ if ( (indexValue instanceof IntegerValue) ||
+ (indexValue instanceof ShortValue) ||
+ (indexValue instanceof ByteValue) ||
+ (indexValue instanceof CharValue) ) {
+ index = ((PrimitiveValue)indexValue).intValue();
+ } else {
+ throw new ParseException("Array index must be a integer type");
+ }
+ return new LValueArrayElement(interiorGetValue(), index);
+ }
+
+ public String toString() {
+ try {
+ return interiorGetValue().toString();
+ } catch (ParseException e) {
+ return "<Parse Exception>";
+ }
+ }
+
+ static final int STATIC = 0;
+ static final int INSTANCE = 1;
+
+ static Field fieldByName(ReferenceType refType, String name, int kind) {
+ /*
+ * TO DO: Note that this currently fails to find superclass
+ * or implemented interface fields. This is due to a temporary
+ * limititation of RefType.fieldByName. Once that method is
+ * fixed, superclass fields will be found.
+ */
+ Field field = refType.fieldByName(name);
+ if (field != null) {
+ boolean isStatic = field.isStatic();
+ if (((kind == STATIC) && !isStatic) ||
+ ((kind == INSTANCE) && isStatic)) {
+ field = null;
+ }
+ }
+/***
+ System.err.println("fieldByName: " + refType.name() + " " +
+ name + " " +
+ kind + " " +
+ (field != null));
+***/
+ return field;
+ }
+
+ static List methodsByName(ReferenceType refType, String name, int kind) {
+ List list = refType.methodsByName(name);
+ Iterator iter = list.iterator();
+ while (iter.hasNext()) {
+ Method method = (Method)iter.next();
+ boolean isStatic = method.isStatic();
+ if (((kind == STATIC) && !isStatic) ||
+ ((kind == INSTANCE) && isStatic)) {
+ iter.remove();
+ }
+ }
+ return list;
+ }
+
+ static List primitiveTypeNames = new ArrayList();
+ static {
+ primitiveTypeNames.add("boolean");
+ primitiveTypeNames.add("byte");
+ primitiveTypeNames.add("char");
+ primitiveTypeNames.add("short");
+ primitiveTypeNames.add("int");
+ primitiveTypeNames.add("long");
+ primitiveTypeNames.add("float");
+ primitiveTypeNames.add("double");
+ }
+
+ static boolean argumentsMatch(List argNames, List arguments) {
+ if (argNames.size() != arguments.size()) {
+ return false;
+ }
+ Iterator nameIter = argNames.iterator();
+ Iterator valIter = arguments.iterator();
+ while (nameIter.hasNext()) {
+ String argTypeName = (String)nameIter.next();
+ Value value = (Value)valIter.next();
+ /*
+ * For now we require exact match
+ */
+ if (value == null) {
+ // Null values can be passed to any non-primitive argument
+ if (primitiveTypeNames.contains(argTypeName)) {
+ return false;
+ }
+ } else if (!argTypeName.equals(value.type().name())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ static Method resolveOverload(List overloads, List arguments)
+ throws ParseException {
+ Iterator iter = overloads.iterator();
+ while (iter.hasNext()) {
+ Method method = (Method)iter.next();
+ List argNames = method.argumentTypeNames();
+ if (argumentsMatch(argNames, arguments)) {
+ return method;
+ }
+ }
+ throw new ParseException("Arguments match no method");
+ }
+
+ private static class LValueLocal extends LValue {
+ final StackFrame frame;
+ final LocalVariable var;
+
+ LValueLocal(StackFrame frame, LocalVariable var) {
+ this.frame = frame;
+ this.var = var;
+ }
+
+ Value getValue() {
+ return frame.getValue(var);
+ }
+
+ void setValue0(Value val) throws InvalidTypeException,
+ ClassNotLoadedException {
+ frame.setValue(var, val);
+ }
+
+ void invokeWith(List arguments) throws ParseException {
+ throw new ParseException(var.name() + " is not a method");
+ }
+ }
+
+ private static class LValueInstanceMember extends LValue {
+ final ObjectReference obj;
+ final ThreadReference thread;
+ final Field matchingField;
+ final List overloads;
+ Method matchingMethod = null;
+ List methodArguments = null;
+
+ LValueInstanceMember(Value value,
+ String memberName,
+ ThreadReference thread) throws ParseException {
+ if (!(value instanceof ObjectReference)) {
+ throw new ParseException(
+ "Cannot access field of primitive type: " + value);
+ }
+ this.obj = (ObjectReference)value;
+ this.thread = thread;
+ ReferenceType refType = obj.referenceType();
+ /*
+ * Can't tell yet whether this LValue will be accessed as a
+ * field or method, so we keep track of all the possibilities
+ */
+ matchingField = LValue.fieldByName(refType, memberName,
+ LValue.INSTANCE);
+ overloads = LValue.methodsByName(refType, memberName,
+ LValue.INSTANCE);
+ if ((matchingField == null) && overloads.size() == 0) {
+ throw new ParseException("No instance field or method with the name
"
+ + memberName + " in " + refType.name());
+ }
+ }
+
+ Value getValue() throws InvocationException, InvalidTypeException,
+ ClassNotLoadedException, IncompatibleThreadStateException
{
+ if (matchingMethod == null) {
+ return obj.getValue(matchingField);
+ } else {
+ return obj.invokeMethod(thread, matchingMethod, methodArguments, 0);
+ }
+ }
+
+ void setValue0(Value val) throws ParseException,
+ InvalidTypeException,
+ ClassNotLoadedException {
+ if (matchingMethod != null) {
+ throw new ParseException("Cannot assign to a method
invocation");
+ }
+ obj.setValue(matchingField, val);
+ }
+
+ void invokeWith(List arguments) throws ParseException {
+ if (matchingMethod != null) {
+ throw new ParseException("Invalid consecutive invocations");
+ }
+ methodArguments = arguments;
+ matchingMethod = LValue.resolveOverload(overloads, arguments);
+ }
+ }
+
+ private static class LValueStaticMember extends LValue {
+ final ReferenceType refType;
+ final ThreadReference thread;
+ final Field matchingField;
+ final List overloads;
+ Method matchingMethod = null;
+ List methodArguments = null;
+
+ LValueStaticMember(ReferenceType refType,
+ String memberName,
+ ThreadReference thread) throws ParseException {
+ this.refType = refType;
+ this.thread = thread;
+ /*
+ * Can't tell yet whether this LValue will be accessed as a
+ * field or method, so we keep track of all the possibilities
+ */
+ matchingField = LValue.fieldByName(refType, memberName,
+ LValue.STATIC);
+ overloads = LValue.methodsByName(refType, memberName,
+ LValue.STATIC);
+ if ((matchingField == null) && overloads.size() == 0) {
+ throw new ParseException("No static field or method with the name
"
+ + memberName + " in " + refType.name());
+ }
+ }
+
+ Value getValue() throws InvocationException, InvalidTypeException,
+ ClassNotLoadedException, IncompatibleThreadStateException
{
+ if (matchingMethod == null) {
+ return refType.getValue(matchingField);
+ } else if (refType instanceof ClassType) {
+ ClassType clazz = (ClassType)refType;
+ return clazz.invokeMethod(thread, matchingMethod, methodArguments, 0);
+ } else {
+ throw new InvalidTypeException("Cannot invoke static method on
" +
+ refType.name());
+ }
+ }
+
+ void setValue0(Value val)
+ throws ParseException, InvalidTypeException,
+ ClassNotLoadedException {
+ if (matchingMethod != null) {
+ throw new ParseException("Cannot assign to a method
invocation");
+ }
+ if (!(refType instanceof ClassType)) {
+ throw new ParseException(
+ "Cannot set interface field: " + refType);
+ }
+ ((ClassType)refType).setValue(matchingField, val);
+ }
+
+ void invokeWith(List arguments) throws ParseException {
+ if (matchingMethod != null) {
+ throw new ParseException("Invalid consecutive invocations");
+ }
+ methodArguments = arguments;
+ matchingMethod = LValue.resolveOverload(overloads, arguments);
+ }
+ }
+
+ private static class LValueArrayElement extends LValue {
+ final ArrayReference array;
+ final int index;
+
+ LValueArrayElement(Value value, int index) throws ParseException {
+ if (!(value instanceof ArrayReference)) {
+ throw new ParseException(
+ "Must be array type: " + value);
+ }
+ this.array = (ArrayReference)value;
+ this.index = index;
+ }
+
+ Value getValue() {
+ return array.getValue(index);
+ }
+
+ void setValue0(Value val) throws InvalidTypeException,
+ ClassNotLoadedException {
+ array.setValue(index, val);
+ }
+
+ void invokeWith(List arguments) throws ParseException {
+ throw new ParseException("Array element is not a method");
+ }
+ }
+
+ private static class LValueConstant extends LValue {
+ final Value value;
+
+ LValueConstant(Value value) {
+ this.value = value;
+ }
+
+ Value getValue() {
+ return value;
+ }
+
+ void setValue0(Value val) throws ParseException {
+ throw new ParseException("Cannot set constant: " + value);
+ }
+
+ void invokeWith(List arguments) throws ParseException {
+ throw new ParseException("Constant is not a method");
+ }
+ }
+
+ static LValue make(VirtualMachine vm, boolean val) {
+ return new LValueConstant(vm.mirrorOf(val));
+ }
+
+ static LValue make(VirtualMachine vm, byte val) {
+ return new LValueConstant(vm.mirrorOf(val));
+ }
+
+ static LValue make(VirtualMachine vm, char val) {
+ return new LValueConstant(vm.mirrorOf(val));
+ }
+
+ static LValue make(VirtualMachine vm, short val) {
+ return new LValueConstant(vm.mirrorOf(val));
+ }
+
+ static LValue make(VirtualMachine vm, int val) {
+ return new LValueConstant(vm.mirrorOf(val));
+ }
+
+ static LValue make(VirtualMachine vm, long val) {
+ return new LValueConstant(vm.mirrorOf(val));
+ }
+
+ static LValue make(VirtualMachine vm, float val) {
+ return new LValueConstant(vm.mirrorOf(val));
+ }
+
+ static LValue make(VirtualMachine vm, double val) {
+ return new LValueConstant(vm.mirrorOf(val));
+ }
+
+ static LValue make(VirtualMachine vm, String val) throws ParseException {
+ return new LValueConstant(vm.mirrorOf(val));
+ }
+
+ static LValue makeBoolean(VirtualMachine vm, Token token) {
+ return make(vm, token.image.charAt(0) == 't');
+ }
+
+ static LValue makeCharacter(VirtualMachine vm, Token token) {
+ return make(vm, token.image.charAt(1));
+ }
+
+ static LValue makeFloat(VirtualMachine vm, Token token) {
+ return make(vm, Float.valueOf(token.image).floatValue());
+ }
+
+ static LValue makeDouble(VirtualMachine vm, Token token) {
+ return make(vm, Double.valueOf(token.image).doubleValue());
+ }
+
+ static LValue makeInteger(VirtualMachine vm, Token token) {
+ return make(vm, Integer.parseInt(token.image));
+ }
+
+ static LValue makeShort(VirtualMachine vm, Token token) {
+ return make(vm, Short.parseShort(token.image));
+ }
+
+ static LValue makeLong(VirtualMachine vm, Token token) {
+ return make(vm, Long.parseLong(token.image));
+ }
+
+ static LValue makeByte(VirtualMachine vm, Token token) {
+ return make(vm, Byte.parseByte(token.image));
+ }
+
+ static LValue makeString(VirtualMachine vm,
+ Token token) throws ParseException {
+ int len = token.image.length();
+ return make(vm, token.image.substring(1,len-1));
+ }
+
+ static LValue makeNull(VirtualMachine vm,
+ Token token) throws ParseException {
+ return new LValueConstant(null);
+ }
+
+ static LValue makeThisObject(VirtualMachine vm,
+ ExpressionParser.GetFrame frameGetter,
+ Token token) throws ParseException {
+ if (frameGetter == null) {
+ throw new ParseException("No current thread");
+ } else {
+ try {
+ StackFrame frame = frameGetter.get();
+ ObjectReference thisObject = frame.thisObject();
+ if (thisObject == null) {
+ throw new ParseException(
+ "No 'this'. In native or static method");
+ } else {
+ return new LValueConstant(thisObject);
+ }
+ } catch (IncompatibleThreadStateException exc) {
+ throw new ParseException("Thread not suspended");
+ }
+ }
+ }
+
+ static LValue makeNewObject(VirtualMachine vm,
+ ExpressionParser.GetFrame frameGetter,
+ String className, List arguments) throws ParseException
{
+ List classes = vm.classesByName(className);
+ if (classes.size() == 0) {
+ throw new ParseException("No class named: " + className);
+ }
+
+ if (classes.size() > 1) {
+ throw new ParseException("More than one class named: " +
+ className);
+ }
+ ReferenceType refType = (ReferenceType)classes.get(0);
+
+
+ if (!(refType instanceof ClassType)) {
+ throw new ParseException("Cannot create instance of interface " +
+ className);
+ }
+
+ ClassType classType = (ClassType)refType;
+ List methods = new ArrayList(classType.methods()); // writable
+ Iterator iter = methods.iterator();
+ while (iter.hasNext()) {
+ Method method = (Method)iter.next();
+ if (!method.isConstructor()) {
+ iter.remove();
+ }
+ }
+ Method constructor = LValue.resolveOverload(methods, arguments);
+
+ ObjectReference newObject;
+ try {
+ ThreadReference thread = frameGetter.get().thread();
+ newObject = classType.newInstance(thread, constructor, arguments, 0);
+ } catch (InvocationException ie) {
+ throw new ParseException("Exception in " + className + "
constructor: " +
+ ie.exception().referenceType().name());
+ } catch (IncompatibleThreadStateException exc) {
+ throw new ParseException("Thread not suspended");
+ } catch (Exception e) {
+ /*
+ * TO DO: Better error handling
+ */
+ throw new ParseException("Unable to create " + className + "
instance");
+ }
+ return new LValueConstant(newObject);
+ }
+
+ private static LValue nFields(LValue lval,
+ StringTokenizer izer,
+ ThreadReference thread)
+ throws ParseException {
+ if (!izer.hasMoreTokens()) {
+ return lval;
+ } else {
+ return nFields(lval.memberLValue(izer.nextToken(), thread), izer, thread);
+ }
+ }
+
+ static LValue makeName(VirtualMachine vm,
+ ExpressionParser.GetFrame frameGetter,
+ String name) throws ParseException {
+ StringTokenizer izer = new StringTokenizer(name, ".");
+ String first = izer.nextToken();
+
+ // check local variables
+ if (frameGetter != null) {
+ try {
+ StackFrame frame = frameGetter.get();
+ ThreadReference thread = frame.thread();
+ LocalVariable var;
+ try {
+ var = frame.visibleVariableByName(first);
+ } catch (AbsentInformationException e) {
+ var = null;
+ }
+ if (var != null) {
+ return nFields(new LValueLocal(frame, var), izer, thread);
+ } else {
+ ObjectReference thisObject = frame.thisObject();
+ if (thisObject != null) {
+ // check if it is a field of 'this'
+ LValue thisLValue = new LValueConstant(thisObject);
+ LValue fv;
+ try {
+ fv = thisLValue.memberLValue(first, thread);
+ } catch (ParseException exc) {
+ fv = null;
+ }
+ if (fv != null) {
+ return nFields(fv, izer, thread);
+ }
+ }
+ }
+ // check for class name
+ while (izer.hasMoreTokens()) {
+ List classes = vm.classesByName(first);
+ if (classes.size() > 0) {
+ if (classes.size() > 1) {
+ throw new ParseException("More than one class named:
" +
+ first);
+ } else {
+ ReferenceType refType = (ReferenceType)classes.get(0);
+ LValue lval = new LValueStaticMember(refType,
+ izer.nextToken(), thread);
+ return nFields(lval, izer, thread);
+ }
+ }
+ first = first + '.' + izer.nextToken();
+ }
+ } catch (IncompatibleThreadStateException exc) {
+ throw new ParseException("Thread not suspended");
+ }
+ }
+ throw new ParseException("Name unknown: " + name);
+ }
+
+ static String stringValue(Value val) {
+ if (val instanceof StringReference) {
+ return ((StringReference)val).value();
+ } else if (val instanceof ObjectReference) {
+ return ((ObjectReference)val).toString(); // TODO
+ } else if (val == null) {
+ return "null";
+ } else {
+ return val.toString(); // TODO not correct in all cases
+ }
+ }
+
+ static LValue booleanOperation(VirtualMachine vm, Token token,
+ LValue rightL,
+ LValue leftL) throws ParseException {
+ String op = token.image;
+ Value right = rightL.interiorGetValue();
+ Value left = leftL.interiorGetValue();
+ if ( !(right instanceof PrimitiveValue) ||
+ !(left instanceof PrimitiveValue) ) {
+ if (op.equals("==")) {
+ return make(vm, right.equals(left));
+ } else if (op.equals("!=")) {
+ return make(vm, !right.equals(left));
+ } else {
+ throw new ParseException("Operands or '" + op +
+ "' must be primitive");
+ }
+ }
+ // can compare any numeric doubles
+ double rr = ((PrimitiveValue)right).doubleValue();
+ double ll = ((PrimitiveValue)left).doubleValue();
+ boolean res;
+ if (op.equals("<")) {
+ res = rr < ll;
+ } else if (op.equals(">")) {
+ res = rr > ll;
+ } else if (op.equals("<=")) {
+ res = rr <= ll;
+ } else if (op.equals(">=")) {
+ res = rr >= ll;
+ } else if (op.equals("==")) {
+ res = rr == ll;
+ } else if (op.equals("!=")) {
+ res = rr != ll;
+ } else {
+ throw new ParseException("Unknown operation: " + op);
+ }
+ return make(vm, res);
+ }
+
+ static LValue operation(VirtualMachine vm, Token token,
+ LValue rightL,
+ LValue leftL) throws ParseException {
+ String op = token.image;
+ Value right = rightL.interiorGetValue();
+ Value left = leftL.interiorGetValue();
+ if ((right instanceof StringReference) ||
+ (left instanceof StringReference)) {
+ if (op.equals("+")) {
+ return make(vm, stringValue(right) + stringValue(left));
+ }
+ }
+ if ((right instanceof ObjectReference) ||
+ (left instanceof ObjectReference)) {
+ if (op.equals("==")) {
+ return make(vm, right.equals(left));
+ } else if (op.equals("!=")) {
+ return make(vm, !right.equals(left));
+ } else {
+ throw new ParseException("Invalid operation '" +
+ op + "' on an Object");
+ }
+ }
+ if ((right instanceof BooleanValue) ||
+ (left instanceof BooleanValue)) {
+ throw new ParseException("Invalid operation '" +
+ op + "' on a Boolean");
+ }
+ // from here on, we know it is a integer kind of type
+ PrimitiveValue primRight = (PrimitiveValue)right;
+ PrimitiveValue primLeft = (PrimitiveValue)left;
+ if ((primRight instanceof DoubleValue) ||
+ (primLeft instanceof DoubleValue)) {
+ double rr = primRight.doubleValue();
+ double ll = primLeft.doubleValue();
+ double res;
+ if (op.equals("+")) {
+ res = rr + ll;
+ } else if (op.equals("-")) {
+ res = rr - ll;
+ } else if (op.equals("*")) {
+ res = rr * ll;
+ } else if (op.equals("/")) {
+ res = rr / ll;
+ } else {
+ throw new ParseException("Unknown operation: " + op);
+ }
+ return make(vm, res);
+ }
+ if ((primRight instanceof FloatValue) ||
+ (primLeft instanceof FloatValue)) {
+ float rr = primRight.floatValue();
+ float ll = primLeft.floatValue();
+ float res;
+ if (op.equals("+")) {
+ res = rr + ll;
+ } else if (op.equals("-")) {
+ res = rr - ll;
+ } else if (op.equals("*")) {
+ res = rr * ll;
+ } else if (op.equals("/")) {
+ res = rr / ll;
+ } else {
+ throw new ParseException("Unknown operation: " + op);
+ }
+ return make(vm, res);
+ }
+ if ((primRight instanceof LongValue) ||
+ (primLeft instanceof LongValue)) {
+ long rr = primRight.longValue();
+ long ll = primLeft.longValue();
+ long res;
+ if (op.equals("+")) {
+ res = rr + ll;
+ } else if (op.equals("-")) {
+ res = rr - ll;
+ } else if (op.equals("*")) {
+ res = rr * ll;
+ } else if (op.equals("/")) {
+ res = rr / ll;
+ } else {
+ throw new ParseException("Unknown operation: " + op);
+ }
+ return make(vm, res);
+ } else {
+ int rr = primRight.intValue();
+ int ll = primLeft.intValue();
+ int res;
+ if (op.equals("+")) {
+ res = rr + ll;
+ } else if (op.equals("-")) {
+ res = rr - ll;
+ } else if (op.equals("*")) {
+ res = rr * ll;
+ } else if (op.equals("/")) {
+ res = rr / ll;
+ } else {
+ throw new ParseException("Unknown operation: " + op);
+ }
+ return make(vm, res);
+ }
+ }
+}
Index: xemacs-packages/jde/java/src/jde/debugger/expr/ParseException.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/expr/ParseException.java,v
retrieving revision 1.1
diff -u -r1.1 ParseException.java
--- xemacs-packages/jde/java/src/jde/debugger/expr/ParseException.java 2000/08/13
13:36:58 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/expr/ParseException.java 2001/08/15
05:27:50
@@ -1,191 +1,191 @@
-/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 0.7pre6 */
-package jde.debugger.expr;
-
-/**
- * This exception is thrown when parse errors are encountered.
- * You can explicitly create objects of this exception type by
- * calling the method generateParseException in the generated
- * parser.
- *
- * You can modify this class to customize your error reporting
- * mechanisms so long as you retain the public fields.
- */
-public class ParseException extends Exception {
-
- /**
- * This constructor is used by the method "generateParseException"
- * in the generated parser. Calling this constructor generates
- * a new object of this type with the fields "currentToken",
- * "expectedTokenSequences", and "tokenImage" set. The boolean
- * flag "specialConstructor" is also set to true to indicate that
- * this constructor was used to create this object.
- * This constructor calls its super class with the empty string
- * to force the "toString" method of parent class "Throwable" to
- * print the error message in the form:
- * ParseException: <result of getMessage>
- */
- public ParseException(Token currentTokenVal,
- int[][] expectedTokenSequencesVal,
- String[] tokenImageVal
- )
- {
- super("");
- specialConstructor = true;
- currentToken = currentTokenVal;
- expectedTokenSequences = expectedTokenSequencesVal;
- tokenImage = tokenImageVal;
- }
-
- /**
- * The following constructors are for use by you for whatever
- * purpose you can think of. Constructing the exception in this
- * manner makes the exception behave in the normal way - i.e., as
- * documented in the class "Throwable". The fields "errorToken",
- * "expectedTokenSequences", and "tokenImage" do not contain
- * relevant information. The JavaCC generated code does not use
- * these constructors.
- */
-
- public ParseException() {
- super();
- specialConstructor = false;
- }
-
- public ParseException(String message) {
- super(message);
- specialConstructor = false;
- }
-
- /**
- * This variable determines which constructor was used to create
- * this object and thereby affects the semantics of the
- * "getMessage" method (see below).
- */
- protected boolean specialConstructor;
-
- /**
- * This is the last token that has been consumed successfully. If
- * this object has been created due to a parse error, the token
- * followng this token will (therefore) be the first error token.
- */
- public Token currentToken;
-
- /**
- * Each entry in this array is an array of integers. Each array
- * of integers represents a sequence of tokens (by their ordinal
- * values) that is expected at this point of the parse.
- */
- public int[][] expectedTokenSequences;
-
- /**
- * This is a reference to the "tokenImage" array of the generated
- * parser within which the parse error occurred. This array is
- * defined in the generated ...Constants interface.
- */
- public String[] tokenImage;
-
- /**
- * This method has the standard behavior when this object has been
- * created using the standard constructors. Otherwise, it uses
- * "currentToken" and "expectedTokenSequences" to generate a parse
- * error message and returns it. If this object has been created
- * due to a parse error, and you do not catch it (it gets thrown
- * from the parser), then this method is called during the printing
- * of the final stack trace, and hence the correct error message
- * gets displayed.
- */
- public String getMessage() {
- if (!specialConstructor) {
- return super.getMessage();
- }
- String expected = "";
- int maxSize = 0;
- for (int i = 0; i < expectedTokenSequences.length; i++) {
- if (maxSize < expectedTokenSequences[i].length) {
- maxSize = expectedTokenSequences[i].length;
- }
- for (int j = 0; j < expectedTokenSequences[i].length; j++) {
- expected += tokenImage[expectedTokenSequences[i][j]] + " ";
- }
- if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
- expected += "...";
- }
- expected += eol + " ";
- }
- String retval = "Encountered \"";
- Token tok = currentToken.next;
- for (int i = 0; i < maxSize; i++) {
- if (i != 0) retval += " ";
- if (tok.kind == 0) {
- retval += tokenImage[0];
- break;
- }
- retval += add_escapes(tok.image);
- tok = tok.next;
- }
- retval += "\" at line " + currentToken.next.beginLine + ", column
" + currentToken.next.beginColumn + "." + eol;
- if (expectedTokenSequences.length == 1) {
- retval += "Was expecting:" + eol + " ";
- } else {
- retval += "Was expecting one of:" + eol + " ";
- }
- retval += expected;
- return retval;
- }
-
- /**
- * The end of line string for this machine.
- */
- protected String eol = System.getProperty("line.separator", "\n");
-
- /**
- * Used to convert raw characters to their escaped version
- * when these raw version cannot be used as part of an ASCII
- * string literal.
- */
- protected String add_escapes(String str) {
- StringBuffer retval = new StringBuffer();
- char ch;
- for (int i = 0; i < str.length(); i++) {
- switch (str.charAt(i))
- {
- case 0 :
- continue;
- case '\b':
- retval.append("\\b");
- continue;
- case '\t':
- retval.append("\\t");
- continue;
- case '\n':
- retval.append("\\n");
- continue;
- case '\f':
- retval.append("\\f");
- continue;
- case '\r':
- retval.append("\\r");
- continue;
- case '\"':
- retval.append("\\\"");
- continue;
- case '\'':
- retval.append("\\\'");
- continue;
- case '\\':
- retval.append("\\\\");
- continue;
- default:
- if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
- String s = "0000" + Integer.toString(ch, 16);
- retval.append("\\u" + s.substring(s.length() - 4,
s.length()));
- } else {
- retval.append(ch);
- }
- continue;
- }
- }
- return retval.toString();
- }
-
-}
+/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 0.7pre6 */
+package jde.debugger.expr;
+
+/**
+ * This exception is thrown when parse errors are encountered.
+ * You can explicitly create objects of this exception type by
+ * calling the method generateParseException in the generated
+ * parser.
+ *
+ * You can modify this class to customize your error reporting
+ * mechanisms so long as you retain the public fields.
+ */
+public class ParseException extends Exception {
+
+ /**
+ * This constructor is used by the method "generateParseException"
+ * in the generated parser. Calling this constructor generates
+ * a new object of this type with the fields "currentToken",
+ * "expectedTokenSequences", and "tokenImage" set. The boolean
+ * flag "specialConstructor" is also set to true to indicate that
+ * this constructor was used to create this object.
+ * This constructor calls its super class with the empty string
+ * to force the "toString" method of parent class "Throwable" to
+ * print the error message in the form:
+ * ParseException: <result of getMessage>
+ */
+ public ParseException(Token currentTokenVal,
+ int[][] expectedTokenSequencesVal,
+ String[] tokenImageVal
+ )
+ {
+ super("");
+ specialConstructor = true;
+ currentToken = currentTokenVal;
+ expectedTokenSequences = expectedTokenSequencesVal;
+ tokenImage = tokenImageVal;
+ }
+
+ /**
+ * The following constructors are for use by you for whatever
+ * purpose you can think of. Constructing the exception in this
+ * manner makes the exception behave in the normal way - i.e., as
+ * documented in the class "Throwable". The fields "errorToken",
+ * "expectedTokenSequences", and "tokenImage" do not contain
+ * relevant information. The JavaCC generated code does not use
+ * these constructors.
+ */
+
+ public ParseException() {
+ super();
+ specialConstructor = false;
+ }
+
+ public ParseException(String message) {
+ super(message);
+ specialConstructor = false;
+ }
+
+ /**
+ * This variable determines which constructor was used to create
+ * this object and thereby affects the semantics of the
+ * "getMessage" method (see below).
+ */
+ protected boolean specialConstructor;
+
+ /**
+ * This is the last token that has been consumed successfully. If
+ * this object has been created due to a parse error, the token
+ * followng this token will (therefore) be the first error token.
+ */
+ public Token currentToken;
+
+ /**
+ * Each entry in this array is an array of integers. Each array
+ * of integers represents a sequence of tokens (by their ordinal
+ * values) that is expected at this point of the parse.
+ */
+ public int[][] expectedTokenSequences;
+
+ /**
+ * This is a reference to the "tokenImage" array of the generated
+ * parser within which the parse error occurred. This array is
+ * defined in the generated ...Constants interface.
+ */
+ public String[] tokenImage;
+
+ /**
+ * This method has the standard behavior when this object has been
+ * created using the standard constructors. Otherwise, it uses
+ * "currentToken" and "expectedTokenSequences" to generate a
parse
+ * error message and returns it. If this object has been created
+ * due to a parse error, and you do not catch it (it gets thrown
+ * from the parser), then this method is called during the printing
+ * of the final stack trace, and hence the correct error message
+ * gets displayed.
+ */
+ public String getMessage() {
+ if (!specialConstructor) {
+ return super.getMessage();
+ }
+ String expected = "";
+ int maxSize = 0;
+ for (int i = 0; i < expectedTokenSequences.length; i++) {
+ if (maxSize < expectedTokenSequences[i].length) {
+ maxSize = expectedTokenSequences[i].length;
+ }
+ for (int j = 0; j < expectedTokenSequences[i].length; j++) {
+ expected += tokenImage[expectedTokenSequences[i][j]] + " ";
+ }
+ if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
+ expected += "...";
+ }
+ expected += eol + " ";
+ }
+ String retval = "Encountered \"";
+ Token tok = currentToken.next;
+ for (int i = 0; i < maxSize; i++) {
+ if (i != 0) retval += " ";
+ if (tok.kind == 0) {
+ retval += tokenImage[0];
+ break;
+ }
+ retval += add_escapes(tok.image);
+ tok = tok.next;
+ }
+ retval += "\" at line " + currentToken.next.beginLine + ", column
" + currentToken.next.beginColumn + "." + eol;
+ if (expectedTokenSequences.length == 1) {
+ retval += "Was expecting:" + eol + " ";
+ } else {
+ retval += "Was expecting one of:" + eol + " ";
+ }
+ retval += expected;
+ return retval;
+ }
+
+ /**
+ * The end of line string for this machine.
+ */
+ protected String eol = System.getProperty("line.separator",
"\n");
+
+ /**
+ * Used to convert raw characters to their escaped version
+ * when these raw version cannot be used as part of an ASCII
+ * string literal.
+ */
+ protected String add_escapes(String str) {
+ StringBuffer retval = new StringBuffer();
+ char ch;
+ for (int i = 0; i < str.length(); i++) {
+ switch (str.charAt(i))
+ {
+ case 0 :
+ continue;
+ case '\b':
+ retval.append("\\b");
+ continue;
+ case '\t':
+ retval.append("\\t");
+ continue;
+ case '\n':
+ retval.append("\\n");
+ continue;
+ case '\f':
+ retval.append("\\f");
+ continue;
+ case '\r':
+ retval.append("\\r");
+ continue;
+ case '\"':
+ retval.append("\\\"");
+ continue;
+ case '\'':
+ retval.append("\\\'");
+ continue;
+ case '\\':
+ retval.append("\\\\");
+ continue;
+ default:
+ if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+ String s = "0000" + Integer.toString(ch, 16);
+ retval.append("\\u" + s.substring(s.length() - 4,
s.length()));
+ } else {
+ retval.append(ch);
+ }
+ continue;
+ }
+ }
+ return retval.toString();
+ }
+
+}
Index: xemacs-packages/jde/java/src/jde/debugger/expr/Token.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/expr/Token.java,v
retrieving revision 1.1
diff -u -r1.1 Token.java
--- xemacs-packages/jde/java/src/jde/debugger/expr/Token.java 2000/08/13 13:36:58 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/expr/Token.java 2001/08/15 05:27:50
@@ -1,81 +1,81 @@
-/* Generated By:JavaCC: Do not edit this line. Token.java Version 0.7pre3 */
-package jde.debugger.expr;
-
-/**
- * Describes the input token stream.
- */
-
-public class Token {
-
- /**
- * An integer that describes the kind of this token. This numbering
- * system is determined by JavaCCParser, and a table of these numbers is
- * stored in the file ...Constants.java.
- */
- public int kind;
-
- /**
- * beginLine and beginColumn describe the position of the first character
- * of this token; endLine and endColumn describe the position of the
- * last character of this token.
- */
- public int beginLine, beginColumn, endLine, endColumn;
-
- /**
- * The string image of the token.
- */
- public String image;
-
- /**
- * A reference to the next regular (non-special) token from the input
- * stream. If this is the last token from the input stream, or if the
- * token manager has not read tokens beyond this one, this field is
- * set to null. This is true only if this token is also a regular
- * token. Otherwise, see below for a description of the contents of
- * this field.
- */
- public Token next;
-
- /**
- * This field is used to access special tokens that occur prior to this
- * token, but after the immediately preceding regular (non-special) token.
- * If there are no such special tokens, this field is set to null.
- * When there are more than one such special token, this field refers
- * to the last of these special tokens, which in turn refers to the next
- * previous special token through its specialToken field, and so on
- * until the first special token (whose specialToken field is null).
- * The next fields of special tokens refer to other special tokens that
- * immediately follow it (without an intervening regular token). If there
- * is no such token, this field is null.
- */
- public Token specialToken;
-
- /**
- * Returns the image.
- */
- public final String toString()
- {
- return image;
- }
-
- /**
- * Returns a new Token object, by default. However, if you want, you
- * can create and return subclass objects based on the value of ofKind.
- * Simply add the cases to the switch for all those special cases.
- * For example, if you have a subclass of Token called IDToken that
- * you want to create if ofKind is ID, simlpy add something like :
- *
- * case MyParserConstants.ID : return new IDToken();
- *
- * to the following switch statement. Then you can cast matchedToken
- * variable to the appropriate type and use it in your lexical actions.
- */
- public static final Token newToken(int ofKind)
- {
- switch(ofKind)
- {
- default : return new Token();
- }
- }
-
-}
+/* Generated By:JavaCC: Do not edit this line. Token.java Version 0.7pre3 */
+package jde.debugger.expr;
+
+/**
+ * Describes the input token stream.
+ */
+
+public class Token {
+
+ /**
+ * An integer that describes the kind of this token. This numbering
+ * system is determined by JavaCCParser, and a table of these numbers is
+ * stored in the file ...Constants.java.
+ */
+ public int kind;
+
+ /**
+ * beginLine and beginColumn describe the position of the first character
+ * of this token; endLine and endColumn describe the position of the
+ * last character of this token.
+ */
+ public int beginLine, beginColumn, endLine, endColumn;
+
+ /**
+ * The string image of the token.
+ */
+ public String image;
+
+ /**
+ * A reference to the next regular (non-special) token from the input
+ * stream. If this is the last token from the input stream, or if the
+ * token manager has not read tokens beyond this one, this field is
+ * set to null. This is true only if this token is also a regular
+ * token. Otherwise, see below for a description of the contents of
+ * this field.
+ */
+ public Token next;
+
+ /**
+ * This field is used to access special tokens that occur prior to this
+ * token, but after the immediately preceding regular (non-special) token.
+ * If there are no such special tokens, this field is set to null.
+ * When there are more than one such special token, this field refers
+ * to the last of these special tokens, which in turn refers to the next
+ * previous special token through its specialToken field, and so on
+ * until the first special token (whose specialToken field is null).
+ * The next fields of special tokens refer to other special tokens that
+ * immediately follow it (without an intervening regular token). If there
+ * is no such token, this field is null.
+ */
+ public Token specialToken;
+
+ /**
+ * Returns the image.
+ */
+ public final String toString()
+ {
+ return image;
+ }
+
+ /**
+ * Returns a new Token object, by default. However, if you want, you
+ * can create and return subclass objects based on the value of ofKind.
+ * Simply add the cases to the switch for all those special cases.
+ * For example, if you have a subclass of Token called IDToken that
+ * you want to create if ofKind is ID, simlpy add something like :
+ *
+ * case MyParserConstants.ID : return new IDToken();
+ *
+ * to the following switch statement. Then you can cast matchedToken
+ * variable to the appropriate type and use it in your lexical actions.
+ */
+ public static final Token newToken(int ofKind)
+ {
+ switch(ofKind)
+ {
+ default : return new Token();
+ }
+ }
+
+}
Index: xemacs-packages/jde/java/src/jde/debugger/expr/TokenMgrError.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/expr/TokenMgrError.java,v
retrieving revision 1.1
diff -u -r1.1 TokenMgrError.java
--- xemacs-packages/jde/java/src/jde/debugger/expr/TokenMgrError.java 2000/08/13
13:36:59 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/expr/TokenMgrError.java 2001/08/15
05:27:50
@@ -1,133 +1,133 @@
-/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 0.7pre2 */
-package jde.debugger.expr;
-
-public class TokenMgrError extends Error
-{
- /*
- * Ordinals for various reasons why an Error of this type can be thrown.
- */
-
- /**
- * Lexical error occured.
- */
- static final int LEXICAL_ERROR = 0;
-
- /**
- * An attempt wass made to create a second instance of a static token manager.
- */
- static final int STATIC_LEXER_ERROR = 1;
-
- /**
- * Tried to change to an invalid lexical state.
- */
- static final int INVALID_LEXICAL_STATE = 2;
-
- /**
- * Detected (and bailed out of) an infinite loop in the token manager.
- */
- static final int LOOP_DETECTED = 3;
-
- /**
- * Indicates the reason why the exception is thrown. It will have
- * one of the above 4 values.
- */
- int errorCode;
-
- /**
- * Replaces unprintable characters by their espaced (or unicode escaped)
- * equivalents in the given string
- */
- protected static final String addEscapes(String str) {
- StringBuffer retval = new StringBuffer();
- char ch;
- for (int i = 0; i < str.length(); i++) {
- switch (str.charAt(i))
- {
- case 0 :
- continue;
- case '\b':
- retval.append("\\b");
- continue;
- case '\t':
- retval.append("\\t");
- continue;
- case '\n':
- retval.append("\\n");
- continue;
- case '\f':
- retval.append("\\f");
- continue;
- case '\r':
- retval.append("\\r");
- continue;
- case '\"':
- retval.append("\\\"");
- continue;
- case '\'':
- retval.append("\\\'");
- continue;
- case '\\':
- retval.append("\\\\");
- continue;
- default:
- if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
- String s = "0000" + Integer.toString(ch, 16);
- retval.append("\\u" + s.substring(s.length() - 4,
s.length()));
- } else {
- retval.append(ch);
- }
- continue;
- }
- }
- return retval.toString();
- }
-
- /**
- * Returns a detailed message for the Error when it is thrown by the
- * token manager to indicate a lexical error.
- * Parameters :
- * EOFSeen : indicates if EOF caused the lexicl error
- * curLexState : lexical state in which this error occured
- * errorLine : line number when the error occured
- * errorColumn : column number when the error occured
- * errorAfter : prefix that was seen before this error occured
- * curchar : the offending character
- * Note: You can customize the lexical error message by modifying this method.
- */
- private static final String LexicalError(boolean EOFSeen, int lexState, int errorLine,
int errorColumn, String errorAfter, char curChar) {
- return("Lexical error at line " +
- errorLine + ", column " +
- errorColumn + ". Encountered: " +
- (EOFSeen ? "<EOF> " : ("\"" +
addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar
+ "), ") +
- "after : \"" + addEscapes(errorAfter) + "\"");
- }
-
- /**
- * You can also modify the body of this method to customize your error messages.
- * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
- * of end-users concern, so you can return something like :
- *
- * "Internal Error : Please file a bug report .... "
- *
- * from this method for such cases in the release version of your parser.
- */
- public String getMessage() {
- return super.getMessage();
- }
-
- /*
- * Constructors of various flavors follow.
- */
-
- public TokenMgrError() {
- }
-
- public TokenMgrError(String message, int reason) {
- super(message);
- errorCode = reason;
- }
-
- public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn,
String errorAfter, char curChar, int reason) {
- this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar),
reason);
- }
-}
+/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 0.7pre2 */
+package jde.debugger.expr;
+
+public class TokenMgrError extends Error
+{
+ /*
+ * Ordinals for various reasons why an Error of this type can be thrown.
+ */
+
+ /**
+ * Lexical error occured.
+ */
+ static final int LEXICAL_ERROR = 0;
+
+ /**
+ * An attempt wass made to create a second instance of a static token manager.
+ */
+ static final int STATIC_LEXER_ERROR = 1;
+
+ /**
+ * Tried to change to an invalid lexical state.
+ */
+ static final int INVALID_LEXICAL_STATE = 2;
+
+ /**
+ * Detected (and bailed out of) an infinite loop in the token manager.
+ */
+ static final int LOOP_DETECTED = 3;
+
+ /**
+ * Indicates the reason why the exception is thrown. It will have
+ * one of the above 4 values.
+ */
+ int errorCode;
+
+ /**
+ * Replaces unprintable characters by their espaced (or unicode escaped)
+ * equivalents in the given string
+ */
+ protected static final String addEscapes(String str) {
+ StringBuffer retval = new StringBuffer();
+ char ch;
+ for (int i = 0; i < str.length(); i++) {
+ switch (str.charAt(i))
+ {
+ case 0 :
+ continue;
+ case '\b':
+ retval.append("\\b");
+ continue;
+ case '\t':
+ retval.append("\\t");
+ continue;
+ case '\n':
+ retval.append("\\n");
+ continue;
+ case '\f':
+ retval.append("\\f");
+ continue;
+ case '\r':
+ retval.append("\\r");
+ continue;
+ case '\"':
+ retval.append("\\\"");
+ continue;
+ case '\'':
+ retval.append("\\\'");
+ continue;
+ case '\\':
+ retval.append("\\\\");
+ continue;
+ default:
+ if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+ String s = "0000" + Integer.toString(ch, 16);
+ retval.append("\\u" + s.substring(s.length() - 4,
s.length()));
+ } else {
+ retval.append(ch);
+ }
+ continue;
+ }
+ }
+ return retval.toString();
+ }
+
+ /**
+ * Returns a detailed message for the Error when it is thrown by the
+ * token manager to indicate a lexical error.
+ * Parameters :
+ * EOFSeen : indicates if EOF caused the lexicl error
+ * curLexState : lexical state in which this error occured
+ * errorLine : line number when the error occured
+ * errorColumn : column number when the error occured
+ * errorAfter : prefix that was seen before this error occured
+ * curchar : the offending character
+ * Note: You can customize the lexical error message by modifying this method.
+ */
+ private static final String LexicalError(boolean EOFSeen, int lexState, int errorLine,
int errorColumn, String errorAfter, char curChar) {
+ return("Lexical error at line " +
+ errorLine + ", column " +
+ errorColumn + ". Encountered: " +
+ (EOFSeen ? "<EOF> " : ("\"" +
addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar
+ "), ") +
+ "after : \"" + addEscapes(errorAfter) + "\"");
+ }
+
+ /**
+ * You can also modify the body of this method to customize your error messages.
+ * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
+ * of end-users concern, so you can return something like :
+ *
+ * "Internal Error : Please file a bug report .... "
+ *
+ * from this method for such cases in the release version of your parser.
+ */
+ public String getMessage() {
+ return super.getMessage();
+ }
+
+ /*
+ * Constructors of various flavors follow.
+ */
+
+ public TokenMgrError() {
+ }
+
+ public TokenMgrError(String message, int reason) {
+ super(message);
+ errorCode = reason;
+ }
+
+ public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn,
String errorAfter, char curChar, int reason) {
+ this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar),
reason);
+ }
+}
Index: xemacs-packages/jde/java/src/jde/debugger/spec/AccessWatchpointSpec.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/spec/AccessWatchpointSpec.java,v
retrieving revision 1.1
diff -u -r1.1 AccessWatchpointSpec.java
--- xemacs-packages/jde/java/src/jde/debugger/spec/AccessWatchpointSpec.java 2000/08/13
13:39:22 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/spec/AccessWatchpointSpec.java 2001/08/15
05:27:51
@@ -1,37 +1,37 @@
-
-package jde.debugger.spec;
-
-import jde.debugger.*;
-
-import com.sun.jdi.*;
-import com.sun.jdi.request.*;
-
-/**
- * AccessWatchpointSpec.java
- * <p>
- *
- * <p>
- * Created: Tue Aug 3 15:34:14 1999
- *
- * @author Amit Kumar
- * @since 0.1
- */
-
-public class AccessWatchpointSpec extends WatchpointSpec {
-
- public AccessWatchpointSpec(Application app, ReferenceTypeSpec refSpec,
- String fieldName) {
- super(app, refSpec, fieldName);
- }
-
- boolean resolve(ReferenceType refType) throws JDEException {
- Field field = refType.fieldByName(fieldName);
- if (field == null) {
- throw new JDEException("'"+fieldName+"' does not exist in the
class");
- }
- EventRequest er =
refType.virtualMachine().eventRequestManager().createAccessWatchpointRequest(field);
- setRequest(er);
- return true;
- }
-
-} // AccessWatchpointSpec
+
+package jde.debugger.spec;
+
+import jde.debugger.*;
+
+import com.sun.jdi.*;
+import com.sun.jdi.request.*;
+
+/**
+ * AccessWatchpointSpec.java
+ * <p>
+ *
+ * <p>
+ * Created: Tue Aug 3 15:34:14 1999
+ *
+ * @author Amit Kumar
+ * @since 0.1
+ */
+
+public class AccessWatchpointSpec extends WatchpointSpec {
+
+ public AccessWatchpointSpec(DebuggeeProcess proc, ReferenceTypeSpec refSpec,
+ String fieldName) {
+ super(proc, refSpec, fieldName);
+ }
+
+ boolean resolve(ReferenceType refType) throws JDEException {
+ Field field = refType.fieldByName(fieldName);
+ if (field == null) {
+ throw new JDEException("'"+fieldName+"' does not exist in the
class");
+ }
+ EventRequest er =
refType.virtualMachine().eventRequestManager().createAccessWatchpointRequest(field);
+ setRequest(er);
+ return true;
+ }
+
+} // AccessWatchpointSpec
Index: xemacs-packages/jde/java/src/jde/debugger/spec/BreakpointSpec.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/spec/BreakpointSpec.java,v
retrieving revision 1.1
diff -u -r1.1 BreakpointSpec.java
--- xemacs-packages/jde/java/src/jde/debugger/spec/BreakpointSpec.java 2000/08/13
13:39:22 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/spec/BreakpointSpec.java 2001/08/15
05:27:51
@@ -1,30 +1,30 @@
-
-package jde.debugger.spec;
-
-import jde.debugger.*;
-
-import com.sun.jdi.*;
-import com.sun.jdi.request.*;
-
-/**
- * BreakpointSpec.java
- * <p>
- *
- * <p>
- * Created: Thu Jul 15 12:59:42 1999
- *
- * @author Amit Kumar
- * @since 0.1
- */
-
-abstract public class BreakpointSpec extends EventRequestSpec {
-
- public BreakpointSpec(Application app, ReferenceTypeSpec spec) {
- super(app, spec);
- }
-
- void setRequest(BreakpointRequest request) {
- super.setRequest(request);
- }
-
-} // BreakpointSpec
+
+package jde.debugger.spec;
+
+import jde.debugger.*;
+
+import com.sun.jdi.*;
+import com.sun.jdi.request.*;
+
+/**
+ * BreakpointSpec.java
+ * <p>
+ *
+ * <p>
+ * Created: Thu Jul 15 12:59:42 1999
+ *
+ * @author Amit Kumar
+ * @since 0.1
+ */
+
+abstract public class BreakpointSpec extends EventRequestSpec {
+
+ public BreakpointSpec(DebuggeeProcess proc, ReferenceTypeSpec spec) {
+ super(proc, spec);
+ }
+
+ void setRequest(BreakpointRequest request) {
+ super.setRequest(request);
+ }
+
+} // BreakpointSpec
Index: xemacs-packages/jde/java/src/jde/debugger/spec/EventRequestSpec.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/spec/EventRequestSpec.java,v
retrieving revision 1.1
diff -u -r1.1 EventRequestSpec.java
--- xemacs-packages/jde/java/src/jde/debugger/spec/EventRequestSpec.java 2000/08/13
13:39:23 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/spec/EventRequestSpec.java 2001/08/15
05:27:51
@@ -1,356 +1,362 @@
-
-package jde.debugger.spec;
-
-import jde.debugger.*;
-
-import com.sun.jdi.*;
-import com.sun.jdi.event.*;
-import com.sun.jdi.request.*;
-
-import java.util.*;
-
-/**
- * EventRequestSpec.java
- * <p>
- * A request specification. This is used for watchpoints, exception-catches,
- * and breakpoints, and provides a mechanism for implementing deferral.
- * <p>
- * The intuition is that the user should be allowed to specify things like
- * breakpoints, even though the corresponding classes haven't been loaded
- * yet.
- * <p>
- * When the user does a, for example, "break on_line test.Test 42", jdebug
- * tries to find if test.Test has been loaded. If it has, it tries to set
- * the breakpoint, and sends an error on failure.
- * <p>
- * If, however, no class matching test.Test exists, jdebug places this
- * "spec" in a list, and each time a class is prepared, matches the class
- * with the spec. If the spec matches, it tries to set the breakpoint /
- * watchpoint / exception-catch. If it works, fine, else it sends the
- * error over to jde.
- * <p>
- * This also allows for neat things like setting breakpoints on source file
- * + line number combinations, since each reference type (given it was
- * compiled with debug info) also contains the source file name in it.
- * <p>
- * Information that would normally be stuck right into the actual requests,
- * for example a thread filter, is stored in the spec until the time it can
- * resolve the request. At that time, it is set in {@link #setRequest}.
- * <p>
- * XXX
- * <p>
- * Note that as of now, when the doc is being written, there is no way of
- * ascertaining if the user mistyped the referencetype name/pattern, since
- * jdebug will just wait <i>ad infinitum</i> for that class to be prepared.
- * <p>
- * Created: Thu Jul 15 12:17:34 1999
- *
- * @author Amit Kumar
- * @since 0.1
- */
-
-abstract public class EventRequestSpec implements Protocol {
-
- private final Long myID;
-
- /**
- * While setting some specs, the user is allowed to specify a boolean
- * expression that must evaluate to true if the event is to be passed
- * on to the user. This expression is stored in the EventRequest object
- * as a property. On an event, the EventRequest object is also passed,
- * and the property can then be extracted, evaluated, and
- * handled correspondingly
- */
- public static final Object expressionKey = "expr";
- private String expr = null;
- public void setExpression(String expr) {
- this.expr = expr;
- if (request != null)
- request.putProperty(expressionKey, expr);
- }
-
- /**
- * For specs that allow for it,
- * the {@link #thread thread} object is either null, a Long, or a
- * String. Depending on the type, it is matched at the time the
- * breakpoint is hit. If it matches the thread, the breakpoint is
- * deemed non-hit.
- */
- public static final Object threadKey = "thread";
- private Object thread = null;
- public void setThread(Object thread) {
- this.thread = thread;
- if (request != null)
- request.putProperty(threadKey, thread);
- }
-
- /**
- * Determines the suspend policy for the corresponding event. See
- * {@link jde.debugger.EventHandler EventHandler} for more details
- * <p>
- * Note that the request needs to be disabled for us to be able to
- * do this
- */
- private int suspendPolicy = EventRequest.SUSPEND_ALL; // the default
- public void setSuspendPolicy(int policy) {
- this.suspendPolicy = policy;
- if (request != null) {
- request.setSuspendPolicy(policy);
- // System.out.println("XXX:"+((request.suspendPolicy() ==
EventRequest.SUSPEND_NONE)?"none":"not none"));
- }
- }
-
- /**
- * Stores a list of class filters that are to be applied to the event
- * request when it gets resolved. This will restrict any events from
- * being reported only if they match the class filters.
- * <p>
- * Not all event-requests support class filters. This filters will be
- * silently ignored for event-requests that do not support them.
- */
- private List classFilters = null;
- public void setClassFilters(List filters) {
- this.classFilters = filters;
- if (request != null)
- installClassFilters(request);
- }
-
- /**
- * Install class filters.
- * Note that the request needs to be disabled for us to be able to
- * do this
- */
- private void installClassFilters(EventRequest request) {
- if (classFilters == null) return;
- Iterator iter = classFilters.iterator();
- while (iter.hasNext()) {
- String f = iter.next().toString();
- if (request instanceof ClassPrepareRequest) {
- ((ClassPrepareRequest)request).addClassFilter(f);
- } else if (request instanceof ClassUnloadRequest) {
- ((ClassUnloadRequest)request).addClassFilter(f);
- } else if (request instanceof ExceptionRequest) {
- ((ExceptionRequest)request).addClassFilter(f);
- } else if (request instanceof WatchpointRequest) {
- ((WatchpointRequest)request).addClassFilter(f);
- }
- }
- }
-
-
- /**
- * Stores a list of class exclusion filters that are to be applied to
- * the event
- * request when it gets resolved. This will restrict any events from
- * being reported only if they do <b>not</b> match the class ex-filters.
- * <p>
- * Not all event-requests support class ex-filters. This filters will be
- * silently ignored for event-requests that do not support them.
- */
- private List classExFilters = null;
- public void setClassExFilters(List filters) {
- this.classExFilters = filters;
- if (request != null)
- installClassExFilters(request);
- }
-
- /**
- * Install class exclusion filters.
- * Note that the request needs to be disabled for us to be able to
- * do this
- */
- private void installClassExFilters(EventRequest request) {
- if (classExFilters == null) return;
- Iterator iter = classExFilters.iterator();
- while (iter.hasNext()) {
- String f = iter.next().toString();
- if (request instanceof ClassPrepareRequest) {
- ((ClassPrepareRequest)request).addClassExclusionFilter(f);
- } else if (request instanceof ClassUnloadRequest) {
- ((ClassUnloadRequest)request).addClassExclusionFilter(f);
- } else if (request instanceof ExceptionRequest) {
- ((ExceptionRequest)request).addClassExclusionFilter(f);
- } else if (request instanceof WatchpointRequest) {
- ((WatchpointRequest)request).addClassExclusionFilter(f);
- }
- }
- }
-
-
-
- /**
- * Unlike the original javadt (from which most of the spec code comes,
- * we do not maintain three spec states, ie, resolved, unresolved, and
- * error. In our case, on an error, we simply remove the spec from the
- * list of specs being maintained by the application, and inform the
- * jde of this fact (that there was an error resolving the spec)
- * (using app.removeSpecAndInformJDE(this))
- * <p>
- * XXX see if the above needs to be changed
- * <p>
- * Consequently, we only need keep track of if we're resolved yet or
- * not.
- */
- boolean isResolved = false;
-
- /**
- * Used to cross-reference the EventRequest to its
- * spec.
- */
- static public final Object specPropertyKey = "spec";
-
- /** The Application for which we're toiling so much */
- final Application app;
-
- /**
- * The reference type spec for this event request spec: this should
- * match the ReferenceType for the spec to be
- * "resolved"
- */
- ReferenceTypeSpec refSpec;
-
- /**
- * The EventRequest corresponding to this spec. This
- * is set when the spec resolves successfully.
- */
- EventRequest request = null;
-
- public EventRequestSpec(Application app, ReferenceTypeSpec refSpec) {
- this.app = app;
- this.refSpec = refSpec;
- myID = app.generateObjectID();
- }
-
- /** get the id corresponding to this spec */
- public Long getID() { return myID; }
-
- /**
- * sets the request up. This is called when a resolve succedes.
- */
- void setRequest(EventRequest request) {
- this.request = request;
- // put a link to this spec in the request itself. a sort of
- // cross referencing
- request.putProperty(specPropertyKey, this);
- request.putProperty(threadKey, thread);
- request.putProperty(expressionKey, expr);
- request.setSuspendPolicy(suspendPolicy);
- installClassFilters(request);
- installClassExFilters(request);
- // System.out.println("YYY:"+((request.suspendPolicy() ==
EventRequest.SUSPEND_NONE)?"none":"not none"));
-
- request.enable();
- app.informJDEInstallSuccessful(this);
-
- }
-
- public EventRequest getEventRequest() { return request; }
-
- /**
- * This function is called to resolve an {@link EventRequestSpec} when
- * the ReferenceType is known to match
- * <p>
- * if any errors occur at any time during resolution of the event-
- * requestspec, it's entry in the {@link EventRequestSpecList} is
- * removed, and jde
- * informed about it (through
- * {@link jde.debugger.Application#removeSpecAndInformJDE}
- * <p>
- * @return true if the resolution was successful
- */
- abstract boolean resolve(ReferenceType refType) throws JDEException;
-
- /**
- * This function is called after each new class is loaded. If this
- * spec hasn't been resolved yet, it's attempted to be resolved. the
- * handling is almost exactly the same as that in
- * {@link #attemptImmediateResolve}
- * <p>
- * <b>Important Note:</b> This method will <i>always</i> go
through
- * without raising any exceptions. As a result of trying to resolve,
- * an exception might be raised, but that'll only result in the
- * removal of the erring spec from the list, and possibly a message
- * to the jde.
- */
- public void attemptResolve(ReferenceType refType) {
- if (!isResolved() && refSpec.matches(refType)) {
- try {
- if (resolve(refType))
- setIsResolved();
- } catch (JDEException ex) {
- app.removeSpecAndInformJDE(this, ex.getMessage());
- } catch (Exception ex) {
- Debug.printIf(ex);
- app.removeSpecAndInformJDE(this, "Error resolving spec: "+ex.toString());
- }
- }
- }
-
- /**
- * Attempts to resolve the eventRequestSpec immediately. There are
- * three possibilities:
- * <ul>
- * <li> The corresponding class hasn't been loaded. the method returns
- * normally.
- * <li> The class has been loaded, and the resolution is successful.
- * The method returns normally, having set the isResolved flag in this
- * class
- * <li> The class has been loaded, but there was an error trying to
- * resolve this spec. An exception is raised, and is caught in this
- * method. This spec is then removed from the spec list kept in the
- * Application object, and jde informed that this spec could not be
- * resolved, so that the UI can take appropriate actions (for example
- * removing the highlighting of a breakpoint)
- * </ul>
- */
- void attemptImmediateResolve(VirtualMachine vm) {
- Iterator iter = vm.allClasses().iterator();
- while (iter.hasNext()) {
- ReferenceType refType = (ReferenceType)iter.next();
- if (refSpec.matches(refType)) {
- try {
- if (resolve(refType)) {
- setIsResolved();
- }
- } catch (JDEException ex) {
- app.removeSpecAndInformJDE(this, ex.getMessage());
- } catch (Exception ex) {
- app.removeSpecAndInformJDE(this, "Error resolving spec");
- }
- }
- }
- }
-
- /**
- * @return true if this spec has been resolved.
- */
- public boolean isResolved() {
- return isResolved;
- }
-
- /**
- * set resolved status
- */
- public void setIsResolved() {
- isResolved = true;
- }
-
- boolean isJavaIdentifier(String s) {
- if (s.length() == 0) {
- return false;
- }
-
- if (! Character.isJavaIdentifierStart(s.charAt(0))) {
- return false;
- }
-
- for (int i = 1; i < s.length(); i++) {
- if (! Character.isJavaIdentifierPart(s.charAt(i))) {
- return false;
- }
- }
-
- return true;
- }
-
-} // EventRequestSpec
+
+package jde.debugger.spec;
+
+import jde.debugger.*;
+
+import com.sun.jdi.*;
+import com.sun.jdi.event.*;
+import com.sun.jdi.request.*;
+
+import java.util.*;
+
+/**
+ * EventRequestSpec.java
+ * <p>
+ * A request specification. This is used for watchpoints, exception-catches,
+ * and breakpoints, and provides a mechanism for implementing deferral.
+ * <p>
+ * The intuition is that the user should be allowed to specify things like
+ * breakpoints, even though the corresponding classes haven't been loaded
+ * yet.
+ * <p>
+ * When the user does a, for example, "break on_line test.Test 42", jdebug
+ * tries to find if test.Test has been loaded. If it has, it tries to set
+ * the breakpoint, and sends an error on failure.
+ * <p>
+ * If, however, no class matching test.Test exists, jdebug places this
+ * "spec" in a list, and each time a class is prepared, matches the class
+ * with the spec. If the spec matches, it tries to set the breakpoint /
+ * watchpoint / exception-catch. If it works, fine, else it sends the
+ * error over to jde.
+ * <p>
+ * This also allows for neat things like setting breakpoints on source file
+ * + line number combinations, since each reference type (given it was
+ * compiled with debug info) also contains the source file name in it.
+ * <p>
+ * Information that would normally be stuck right into the actual requests,
+ * for example a thread filter, is stored in the spec until the time it can
+ * resolve the request. At that time, it is set in {@link #setRequest}.
+ * <p>
+ * XXX
+ * <p>
+ * Note that as of now, when the doc is being written, there is no way of
+ * ascertaining if the user mistyped the referencetype name/pattern, since
+ * jdebug will just wait <i>ad infinitum</i> for that class to be prepared.
+ * <p>
+ * Created: Thu Jul 15 12:17:34 1999
+ *
+ * @author Amit Kumar
+ * @since 0.1
+ */
+
+abstract public class EventRequestSpec implements Protocol {
+
+ private final Long myID;
+
+ /**
+ * While setting some specs, the user is allowed to specify a boolean
+ * expression that must evaluate to true if the event is to be passed
+ * on to the user. This expression is stored in the EventRequest object
+ * as a property. On an event, the EventRequest object is also passed,
+ * and the property can then be extracted, evaluated, and
+ * handled correspondingly
+ */
+ public static final Object expressionKey = "expr";
+ private String expr = null;
+ public void setExpression(String expr) {
+ this.expr = expr;
+ if (request != null)
+ request.putProperty(expressionKey, expr);
+ }
+
+ /**
+ * For specs that allow for it,
+ * the {@link #thread thread} object is either null, a Long, or a
+ * String. Depending on the type, it is matched at the time the
+ * breakpoint is hit. If it matches the thread, the breakpoint is
+ * deemed non-hit.
+ */
+ public static final Object threadKey = "thread";
+ private Object thread = null;
+ public void setThread(Object thread) {
+ this.thread = thread;
+ if (request != null)
+ request.putProperty(threadKey, thread);
+ }
+
+ /**
+ * Determines the suspend policy for the corresponding event. See
+ * {@link jde.debugger.EventHandler EventHandler} for more details
+ * <p>
+ * Note that the request needs to be disabled for us to be able to
+ * do this
+ */
+ private int suspendPolicy = EventRequest.SUSPEND_ALL; // the default
+ public void setSuspendPolicy(int policy) {
+ this.suspendPolicy = policy;
+ if (request != null) {
+ request.setSuspendPolicy(policy);
+ // System.out.println("XXX:"+((request.suspendPolicy() ==
EventRequest.SUSPEND_NONE)?"none":"not none"));
+ }
+ }
+
+ /**
+ * Stores a list of class filters that are to be applied to the event
+ * request when it gets resolved. This will restrict any events from
+ * being reported only if they match the class filters.
+ * <p>
+ * Not all event-requests support class filters. This filters will be
+ * silently ignored for event-requests that do not support them.
+ */
+ private List classFilters = null;
+ public void setClassFilters(List filters) {
+ this.classFilters = filters;
+ if (request != null)
+ installClassFilters(request);
+ }
+
+ /**
+ * Install class filters.
+ * Note that the request needs to be disabled for us to be able to
+ * do this
+ */
+ private void installClassFilters(EventRequest request) {
+ if (classFilters == null) return;
+ Iterator iter = classFilters.iterator();
+ while (iter.hasNext()) {
+ String f = iter.next().toString();
+ if (request instanceof ClassPrepareRequest) {
+ ((ClassPrepareRequest)request).addClassFilter(f);
+ } else if (request instanceof ClassUnloadRequest) {
+ ((ClassUnloadRequest)request).addClassFilter(f);
+ } else if (request instanceof ExceptionRequest) {
+ ((ExceptionRequest)request).addClassFilter(f);
+ } else if (request instanceof WatchpointRequest) {
+ ((WatchpointRequest)request).addClassFilter(f);
+ }
+ }
+ }
+
+
+ /**
+ * Stores a list of class exclusion filters that are to be applied to
+ * the event
+ * request when it gets resolved. This will restrict any events from
+ * being reported only if they do <b>not</b> match the class ex-filters.
+ * <p>
+ * Not all event-requests support class ex-filters. This filters will be
+ * silently ignored for event-requests that do not support them.
+ */
+ private List classExFilters = null;
+ public void setClassExFilters(List filters) {
+ this.classExFilters = filters;
+ if (request != null)
+ installClassExFilters(request);
+ }
+
+ /**
+ * Install class exclusion filters.
+ * Note that the request needs to be disabled for us to be able to
+ * do this
+ */
+ private void installClassExFilters(EventRequest request) {
+ if (classExFilters == null) return;
+ Iterator iter = classExFilters.iterator();
+ while (iter.hasNext()) {
+ String f = iter.next().toString();
+ if (request instanceof ClassPrepareRequest) {
+ ((ClassPrepareRequest)request).addClassExclusionFilter(f);
+ } else if (request instanceof ClassUnloadRequest) {
+ ((ClassUnloadRequest)request).addClassExclusionFilter(f);
+ } else if (request instanceof ExceptionRequest) {
+ ((ExceptionRequest)request).addClassExclusionFilter(f);
+ } else if (request instanceof WatchpointRequest) {
+ ((WatchpointRequest)request).addClassExclusionFilter(f);
+ }
+ }
+ }
+
+
+
+ /**
+ * Unlike the original javadt (from which most of the spec code comes,
+ * we do not maintain three spec states, ie, resolved, unresolved, and
+ * error. In our case, on an error, we simply remove the spec from the
+ * list of specs being maintained by the application, and inform the
+ * jde of this fact (that there was an error resolving the spec)
+ * (using app.removeSpecAndInformJDE(this))
+ * <p>
+ * XXX see if the above needs to be changed
+ * <p>
+ * Consequently, we only need keep track of if we're resolved yet or
+ * not.
+ */
+ boolean isResolved = false;
+
+ /**
+ * Used to cross-reference the EventRequest to its
+ * spec.
+ */
+ static public final Object specPropertyKey = "spec";
+
+ /** The Process for which we're toiling so much */
+ final DebuggeeProcess proc;
+
+ final Integer procID;
+
+ final JDE jde;
+
+ /**
+ * The reference type spec for this event request spec: this should
+ * match the ReferenceType for the spec to be
+ * "resolved"
+ */
+ ReferenceTypeSpec refSpec;
+
+ /**
+ * The EventRequest corresponding to this spec. This
+ * is set when the spec resolves successfully.
+ */
+ EventRequest request = null;
+
+ public EventRequestSpec(DebuggeeProcess proc, ReferenceTypeSpec refSpec) {
+ this.proc = proc;
+ procID = proc.getId();
+ jde = JDE.getJDE();
+ this.refSpec = refSpec;
+ myID = proc.generateObjectID();
+ }
+
+ /** get the id corresponding to this spec */
+ public Long getID() { return myID; }
+
+ /**
+ * sets the request up. This is called when a resolve succedes.
+ */
+ void setRequest(EventRequest request) {
+ this.request = request;
+ // put a link to this spec in the request itself. a sort of
+ // cross referencing
+ request.putProperty(specPropertyKey, this);
+ request.putProperty(threadKey, thread);
+ request.putProperty(expressionKey, expr);
+ request.setSuspendPolicy(suspendPolicy);
+ installClassFilters(request);
+ installClassExFilters(request);
+ // System.out.println("YYY:"+((request.suspendPolicy() ==
EventRequest.SUSPEND_NONE)?"none":"not none"));
+
+ request.enable();
+ proc.informJDEInstallSuccessful(this);
+
+ }
+
+ public EventRequest getEventRequest() { return request; }
+
+ /**
+ * This function is called to resolve an {@link EventRequestSpec} when
+ * the ReferenceType is known to match
+ * <p>
+ * if any errors occur at any time during resolution of the event-
+ * requestspec, it's entry in the {@link EventRequestSpecList} is
+ * removed, and jde
+ * informed about it (through
+ * {@link jde.debugger.Application#removeSpecAndInformJDE}
+ * <p>
+ * @return true if the resolution was successful
+ */
+ abstract boolean resolve(ReferenceType refType) throws JDEException;
+
+ /**
+ * This function is called after each new class is loaded. If this
+ * spec hasn't been resolved yet, it's attempted to be resolved. the
+ * handling is almost exactly the same as that in
+ * {@link #attemptImmediateResolve}
+ * <p>
+ * <b>Important Note:</b> This method will <i>always</i> go
through
+ * without raising any exceptions. As a result of trying to resolve,
+ * an exception might be raised, but that'll only result in the
+ * removal of the erring spec from the list, and possibly a message
+ * to the jde.
+ */
+ public void attemptResolve(ReferenceType refType) {
+ if (!isResolved() && refSpec.matches(refType)) {
+ try {
+ if (resolve(refType))
+ setIsResolved();
+ } catch (JDEException ex) {
+ proc.removeSpecAndInformJDE(this, ex.getMessage());
+ } catch (Exception ex) {
+ Debug.printIf(ex);
+ proc.removeSpecAndInformJDE(this, "Error resolving spec: "+ex.toString());
+ }
+ }
+ }
+
+ /**
+ * Attempts to resolve the eventRequestSpec immediately. There are
+ * three possibilities:
+ * <ul>
+ * <li> The corresponding class hasn't been loaded. the method returns
+ * normally.
+ * <li> The class has been loaded, and the resolution is successful.
+ * The method returns normally, having set the isResolved flag in this
+ * class
+ * <li> The class has been loaded, but there was an error trying to
+ * resolve this spec. An exception is raised, and is caught in this
+ * method. This spec is then removed from the spec list kept in the
+ * Application object, and jde informed that this spec could not be
+ * resolved, so that the UI can take appropriate actions (for example
+ * removing the highlighting of a breakpoint)
+ * </ul>
+ */
+ void attemptImmediateResolve(VirtualMachine vm) {
+ Iterator iter = vm.allClasses().iterator();
+ while (iter.hasNext()) {
+ ReferenceType refType = (ReferenceType)iter.next();
+ if (refSpec.matches(refType)) {
+ try {
+ if (resolve(refType)) {
+ setIsResolved();
+ }
+ } catch (JDEException ex) {
+ proc.removeSpecAndInformJDE(this, ex.getMessage());
+ } catch (Exception ex) {
+ proc.removeSpecAndInformJDE(this, "Error resolving spec");
+ }
+ }
+ }
+ }
+
+ /**
+ * @return true if this spec has been resolved.
+ */
+ public boolean isResolved() {
+ return isResolved;
+ }
+
+ /**
+ * set resolved status
+ */
+ public void setIsResolved() {
+ isResolved = true;
+ }
+
+ boolean isJavaIdentifier(String s) {
+ if (s.length() == 0) {
+ return false;
+ }
+
+ if (! Character.isJavaIdentifierStart(s.charAt(0))) {
+ return false;
+ }
+
+ for (int i = 1; i < s.length(); i++) {
+ if (! Character.isJavaIdentifierPart(s.charAt(i))) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+} // EventRequestSpec
Index: xemacs-packages/jde/java/src/jde/debugger/spec/EventRequestSpecList.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/spec/EventRequestSpecList.java,v
retrieving revision 1.1
diff -u -r1.1 EventRequestSpecList.java
--- xemacs-packages/jde/java/src/jde/debugger/spec/EventRequestSpecList.java 2000/08/13
13:39:23 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/spec/EventRequestSpecList.java 2001/08/15
05:27:51
@@ -1,155 +1,155 @@
-
-package jde.debugger.spec;
-
-import jde.debugger.*;
-
-import com.sun.jdi.*;
-import com.sun.jdi.event.*;
-import com.sun.jdi.request.*;
-
-import java.util.*;
-
-/**
- * EventRequestSpecList.java
- * <p>
- * Maintains a list of all the "specs", ie requests by the user for
- * notification of a particular type of event. Not all commands create
- * specs: watchpoints, breakpoints, and exception catches do.
- * <p>
- * See {@link EventRequestSpec} for more details.
- * <p>
- * Created: Thu Jul 15 11:26:23 1999
- *
- * @author Amit Kumar
- * @since 0.1
- */
-
-public class EventRequestSpecList {
-
- /**
- * a Hashmap of all the {@link EventRequestSpec}s for the application,
- * specID -> spec
- */
- private Map eventRequestSpecs =
- Collections.synchronizedMap(new HashMap());
-
- /** The application for which we're maintaining the specs */
- private final Application app;
-
- public EventRequestSpecList(Application app) {
- this.app = app;
- }
-
- // public void setupInitialRequests() {
-
- // ExceptionRequest erequest = em.createExceptionRequest(null, false, true);
- // erequest.setSuspendPolicy(EventRequest.SUSPEND_NONE);
- // erequest.enable();
- // }
-
- /**
- * Resolve all deferred eventRequests waiting for 'refType'. This is
- * called when a new reference type is prepared. We iterate through
- * all the requestspecs, calling their
- * {@link EventRequestSpec#attemptResolve(ReferenceType) attemptResolve}
- * methods.
- *
- * @param refType The reference type that was recently prepared
- */
- public void resolve(ReferenceType refType) {
- synchronized(eventRequestSpecs) {
- Iterator iter = eventRequestSpecs.values().iterator();
- while (iter.hasNext()) {
- ((EventRequestSpec)iter.next()).attemptResolve(refType);
- }
- }
- }
-
- /** Install a new event request spec */
- public void install(EventRequestSpec ers) {
- synchronized (eventRequestSpecs) {
- eventRequestSpecs.put(ers.getID(), ers);
- }
- if (app.getVM() != null) {
- ers.attemptImmediateResolve(app.getVM());
- }
- }
-
- /** Delete an existing event request spec */
- public void delete(EventRequestSpec ers) {
- EventRequest request = ers.getEventRequest();
- synchronized (eventRequestSpecs) {
- eventRequestSpecs.remove(ers.getID());
- }
- if (request != null) {
- request.virtualMachine().eventRequestManager()
- .deleteEventRequest(request);
- }
- }
-
- /** remove a spec based on its specID */
- public void removeSpec(Long specID)
- throws JDEException {
- synchronized (eventRequestSpecs) {
- if (!eventRequestSpecs.containsKey(specID))
- throw new JDEException("'"+specID+"' doesn't exist");
- delete((EventRequestSpec)eventRequestSpecs.get(specID));
- }
- }
-
- public EventRequestSpec createExceptionIntercept(String classPattern,
- boolean notifyCaught,
- boolean notifyUncaught){
- ReferenceTypeSpec refSpec =
- new PatternReferenceTypeSpec(classPattern);
- EventRequestSpec ers =
- new ExceptionSpec(app, refSpec, notifyCaught, notifyUncaught);
- return ers;
- }
-
- public WatchpointSpec createAccessWatchpoint
- (String classPattern, String m) {
- ReferenceTypeSpec refSpec =
- new PatternReferenceTypeSpec(classPattern);
- WatchpointSpec ers =
- new AccessWatchpointSpec(app, refSpec, m);
- return ers;
- }
-
- public WatchpointSpec createModificationWatchpoint
- (String classPattern, String m) {
- ReferenceTypeSpec refSpec =
- new PatternReferenceTypeSpec(classPattern);
- WatchpointSpec ers =
- new ModificationWatchpointSpec(app, refSpec, m);
- return ers;
- }
-
- public EventRequestSpec createClassLineBreakpoint
- (String classPattern, int line) {
- ReferenceTypeSpec refSpec =
- new PatternReferenceTypeSpec(classPattern);
- EventRequestSpec ers =
- new LineBreakpointSpec(app, refSpec, line);
- return ers;
- }
-
- public EventRequestSpec createSourceLineBreakpoint
- (String sourceName, int line) {
- ReferenceTypeSpec refSpec =
- new SourceNameReferenceTypeSpec(sourceName, line);
- EventRequestSpec ers =
- new LineBreakpointSpec(app, refSpec, line);
- return ers;
- }
-
- public EventRequestSpec createMethodBreakpoint
- (String classPattern, String methodId, List methodArgs) {
- ReferenceTypeSpec refSpec =
- new PatternReferenceTypeSpec(classPattern);
- EventRequestSpec e =
- new MethodBreakpointSpec(app, refSpec, methodId, methodArgs);
- return e;
- }
-
-} // EventRequestSpecList
+
+package jde.debugger.spec;
+
+import jde.debugger.*;
+
+import com.sun.jdi.*;
+import com.sun.jdi.event.*;
+import com.sun.jdi.request.*;
+
+import java.util.*;
+
+/**
+ * EventRequestSpecList.java
+ * <p>
+ * Maintains a list of all the "specs", ie requests by the user for
+ * notification of a particular type of event. Not all commands create
+ * specs: watchpoints, breakpoints, and exception catches do.
+ * <p>
+ * See {@link EventRequestSpec} for more details.
+ * <p>
+ * Created: Thu Jul 15 11:26:23 1999
+ *
+ * @author Amit Kumar
+ * @since 0.1
+ */
+
+public class EventRequestSpecList {
+
+ /**
+ * a Hashmap of all the {@link EventRequestSpec}s for the application,
+ * specID -> spec
+ */
+ private Map eventRequestSpecs =
+ Collections.synchronizedMap(new HashMap());
+
+ /** The process for which we're maintaining the specs */
+ private final DebuggeeProcess proc;
+
+ public EventRequestSpecList(DebuggeeProcess proc) {
+ this.proc = proc;
+ }
+
+ // public void setupInitialRequests() {
+
+ // ExceptionRequest erequest = em.createExceptionRequest(null, false, true);
+ // erequest.setSuspendPolicy(EventRequest.SUSPEND_NONE);
+ // erequest.enable();
+ // }
+
+ /**
+ * Resolve all deferred eventRequests waiting for 'refType'. This is
+ * called when a new reference type is prepared. We iterate through
+ * all the requestspecs, calling their
+ * {@link EventRequestSpec#attemptResolve(ReferenceType) attemptResolve}
+ * methods.
+ *
+ * @param refType The reference type that was recently prepared
+ */
+ public void resolve(ReferenceType refType) {
+ synchronized(eventRequestSpecs) {
+ Iterator iter = eventRequestSpecs.values().iterator();
+ while (iter.hasNext()) {
+ ((EventRequestSpec)iter.next()).attemptResolve(refType);
+ }
+ }
+ }
+
+ /** Install a new event request spec */
+ public void install(EventRequestSpec ers) {
+ synchronized (eventRequestSpecs) {
+ eventRequestSpecs.put(ers.getID(), ers);
+ }
+ if (proc.getVM() != null) {
+ ers.attemptImmediateResolve(proc.getVM());
+ }
+ }
+
+ /** Delete an existing event request spec */
+ public void delete(EventRequestSpec ers) {
+ EventRequest request = ers.getEventRequest();
+ synchronized (eventRequestSpecs) {
+ eventRequestSpecs.remove(ers.getID());
+ }
+ if (request != null) {
+ request.virtualMachine().eventRequestManager()
+ .deleteEventRequest(request);
+ }
+ }
+
+ /** remove a spec based on its specID */
+ public void removeSpec(Long specID)
+ throws JDEException {
+ synchronized (eventRequestSpecs) {
+ if (!eventRequestSpecs.containsKey(specID))
+ throw new JDEException("'"+specID+"' doesn't exist");
+ delete((EventRequestSpec)eventRequestSpecs.get(specID));
+ }
+ }
+
+ public EventRequestSpec createExceptionIntercept(String classPattern,
+ boolean notifyCaught,
+ boolean notifyUncaught){
+ ReferenceTypeSpec refSpec =
+ new PatternReferenceTypeSpec(classPattern);
+ EventRequestSpec ers =
+ new ExceptionSpec(proc, refSpec, notifyCaught, notifyUncaught);
+ return ers;
+ }
+
+ public WatchpointSpec createAccessWatchpoint
+ (String classPattern, String m) {
+ ReferenceTypeSpec refSpec =
+ new PatternReferenceTypeSpec(classPattern);
+ WatchpointSpec ers =
+ new AccessWatchpointSpec(proc, refSpec, m);
+ return ers;
+ }
+
+ public WatchpointSpec createModificationWatchpoint
+ (String classPattern, String m) {
+ ReferenceTypeSpec refSpec =
+ new PatternReferenceTypeSpec(classPattern);
+ WatchpointSpec ers =
+ new ModificationWatchpointSpec(proc, refSpec, m);
+ return ers;
+ }
+
+ public EventRequestSpec createClassLineBreakpoint
+ (String classPattern, int line) {
+ ReferenceTypeSpec refSpec =
+ new PatternReferenceTypeSpec(classPattern);
+ EventRequestSpec ers =
+ new LineBreakpointSpec(proc, refSpec, line);
+ return ers;
+ }
+
+ public EventRequestSpec createSourceLineBreakpoint
+ (String sourceName, int line) {
+ ReferenceTypeSpec refSpec =
+ new SourceNameReferenceTypeSpec(sourceName, line);
+ EventRequestSpec ers =
+ new LineBreakpointSpec(proc, refSpec, line);
+ return ers;
+ }
+
+ public EventRequestSpec createMethodBreakpoint
+ (String classPattern, String methodId, List methodArgs) {
+ ReferenceTypeSpec refSpec =
+ new PatternReferenceTypeSpec(classPattern);
+ EventRequestSpec e =
+ new MethodBreakpointSpec(proc, refSpec, methodId, methodArgs);
+ return e;
+ }
+
+} // EventRequestSpecList
Index: xemacs-packages/jde/java/src/jde/debugger/spec/ExceptionSpec.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/spec/ExceptionSpec.java,v
retrieving revision 1.1
diff -u -r1.1 ExceptionSpec.java
--- xemacs-packages/jde/java/src/jde/debugger/spec/ExceptionSpec.java 2000/08/13
13:39:23 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/spec/ExceptionSpec.java 2001/08/15
05:27:51
@@ -1,39 +1,39 @@
-
-package jde.debugger.spec;
-
-import jde.debugger.*;
-
-import com.sun.jdi.*;
-import com.sun.jdi.request.*;
-
-/**
- * ExceptionSpec.java
- * <p>
- *
- * <p>
- * Created: Mon Aug 2 17:01:35 1999
- *
- * @author Amit Kumar
- * @since 0.1
- */
-
-public class ExceptionSpec extends EventRequestSpec {
-
- boolean notifyCaught;
-
- boolean notifyUncaught;
-
- public ExceptionSpec(Application app, ReferenceTypeSpec spec,
- boolean notifyCaught, boolean notifyUncaught) {
- super(app, spec);
- this.notifyCaught = notifyCaught;
- this.notifyUncaught = notifyUncaught;
- }
-
- public boolean resolve(ReferenceType refType) {
- ExceptionRequest er =
refType.virtualMachine().eventRequestManager().createExceptionRequest(refType,
notifyCaught, notifyUncaught);
- super.setRequest(er);
- return true;
- }
-
-} // ExceptionSpec
+
+package jde.debugger.spec;
+
+import jde.debugger.*;
+
+import com.sun.jdi.*;
+import com.sun.jdi.request.*;
+
+/**
+ * ExceptionSpec.java
+ * <p>
+ *
+ * <p>
+ * Created: Mon Aug 2 17:01:35 1999
+ *
+ * @author Amit Kumar
+ * @since 0.1
+ */
+
+public class ExceptionSpec extends EventRequestSpec {
+
+ boolean notifyCaught;
+
+ boolean notifyUncaught;
+
+ public ExceptionSpec(DebuggeeProcess proc, ReferenceTypeSpec spec,
+ boolean notifyCaught, boolean notifyUncaught) {
+ super(proc, spec);
+ this.notifyCaught = notifyCaught;
+ this.notifyUncaught = notifyUncaught;
+ }
+
+ public boolean resolve(ReferenceType refType) {
+ ExceptionRequest er =
refType.virtualMachine().eventRequestManager().createExceptionRequest(refType,
notifyCaught, notifyUncaught);
+ super.setRequest(er);
+ return true;
+ }
+
+} // ExceptionSpec
Index: xemacs-packages/jde/java/src/jde/debugger/spec/LineBreakpointSpec.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/spec/LineBreakpointSpec.java,v
retrieving revision 1.1
diff -u -r1.1 LineBreakpointSpec.java
--- xemacs-packages/jde/java/src/jde/debugger/spec/LineBreakpointSpec.java 2000/08/13
13:39:23 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/spec/LineBreakpointSpec.java 2001/08/15
05:27:51
@@ -1,75 +1,75 @@
-
-package jde.debugger.spec;
-
-import jde.debugger.*;
-
-import com.sun.jdi.*;
-import com.sun.jdi.request.*;
-
-import java.util.*;
-
-/**
- * LineBreakpointSpec.java
- * <p>
- *
- * <p>
- * Created: Thu Jul 15 13:00:34 1999
- *
- * @author Amit Kumar
- * @since 0.1
- */
-
-public class LineBreakpointSpec extends BreakpointSpec {
-
- private int lineNumber;
-
- public LineBreakpointSpec(Application app, ReferenceTypeSpec refSpec,
- int line) {
- super(app, refSpec);
- this.lineNumber = line;
- }
-
- boolean resolve(ReferenceType refType) throws JDEException {
- if (!(refType instanceof ClassType)) {
- // remove spec from list of current specs
- throw new JDEException("'"+refType+"' is not a
Class");
- }
- Location location = getLocation((ClassType)refType);
- BreakpointRequest br =
refType.virtualMachine().eventRequestManager().createBreakpointRequest(location);
-
- setRequest(br);
- return true;
- }
-
- private Location getLocation(ClassType clazz) throws JDEException {
- Location location = null;
- try {
- List locs = null;
- try {
- locs = clazz.locationsOfLine(lineNumber);
- } catch (InvalidLineNumberException ex) {
- throw new JDEException("Line #"+lineNumber+" does not
exist in "+clazz+".");
- }
- if (locs.size() == 0) {
- // remove spec from list of current specs
- throw new JDEException("Line #"+lineNumber+" does not
exist int "+clazz+".");
- }
- // XXX handle multiple locations
- location = (Location)locs.get(0);
- if (location.method() == null) {
- // remove spec from list of current specs
- throw new JDEException("Line #"+lineNumber+" does not
correspond to a method in "+
- clazz + ".");
- }
- } catch (AbsentInformationException e) {
- // remove spec from list of current specs
- throw new JDEException("Line Information missing for Class
'"+clazz+"'");
- }
- return location;
- }
-
- public int getLineNumber() {
- return lineNumber;
- }
-
-} // LineBreakpointSpec
+
+package jde.debugger.spec;
+
+import jde.debugger.*;
+
+import com.sun.jdi.*;
+import com.sun.jdi.request.*;
+
+import java.util.*;
+
+/**
+ * LineBreakpointSpec.java
+ * <p>
+ *
+ * <p>
+ * Created: Thu Jul 15 13:00:34 1999
+ *
+ * @author Amit Kumar
+ * @since 0.1
+ */
+
+public class LineBreakpointSpec extends BreakpointSpec {
+
+ private int lineNumber;
+
+ public LineBreakpointSpec(DebuggeeProcess proc, ReferenceTypeSpec refSpec,
+ int line) {
+ super(proc, refSpec);
+ this.lineNumber = line;
+ }
+
+ boolean resolve(ReferenceType refType) throws JDEException {
+ if (!(refType instanceof ClassType)) {
+ // remove spec from list of current specs
+ throw new JDEException("'"+refType+"' is not a
Class");
+ }
+ Location location = getLocation((ClassType)refType);
+ BreakpointRequest br =
refType.virtualMachine().eventRequestManager().createBreakpointRequest(location);
+
+ setRequest(br);
+ return true;
+ }
+
+ private Location getLocation(ClassType clazz) throws JDEException {
+ Location location = null;
+ try {
+ List locs = null;
+ try {
+ locs = clazz.locationsOfLine(lineNumber);
+ } catch (InvalidLineNumberException ex) {
+ throw new JDEException("Line #"+lineNumber+" does not
exist in "+clazz+".");
+ }
+ if (locs.size() == 0) {
+ // remove spec from list of current specs
+ throw new JDEException("Line #"+lineNumber+" does not
exist int "+clazz+".");
+ }
+ // XXX handle multiple locations
+ location = (Location)locs.get(0);
+ if (location.method() == null) {
+ // remove spec from list of current specs
+ throw new JDEException("Line #"+lineNumber+" does not
correspond to a method in "+
+ clazz + ".");
+ }
+ } catch (AbsentInformationException e) {
+ // remove spec from list of current specs
+ throw new JDEException("Line Information missing for Class
'"+clazz+"'");
+ }
+ return location;
+ }
+
+ public int getLineNumber() {
+ return lineNumber;
+ }
+
+} // LineBreakpointSpec
Index: xemacs-packages/jde/java/src/jde/debugger/spec/MethodBreakpointSpec.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/spec/MethodBreakpointSpec.java,v
retrieving revision 1.1
diff -u -r1.1 MethodBreakpointSpec.java
--- xemacs-packages/jde/java/src/jde/debugger/spec/MethodBreakpointSpec.java 2000/08/13
13:39:23 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/spec/MethodBreakpointSpec.java 2001/08/15
05:27:51
@@ -1,245 +1,245 @@
-
-package jde.debugger.spec;
-
-import jde.debugger.*;
-
-import com.sun.jdi.*;
-import com.sun.jdi.request.*;
-
-import java.util.*;
-
-/**
- * MethodBreakpointSpec.java
- * <p>
- * Funnily, it seems this class actually supports setting breakpoints in
- * a particular method of an arbitrary filename! since it's very weird, it's
- * not supported. Let us know if you require such a feature...
- * <p>
- * Created: Thu Jul 15 15:52:45 1999
- *
- * @author Amit Kumar
- * @since 0.1
- */
-
-public class MethodBreakpointSpec extends BreakpointSpec {
-
- String methodName;
- List methodArgs;
-
- public MethodBreakpointSpec(Application app, ReferenceTypeSpec refSpec,
- String methodName, List methodArgs) {
- super(app, refSpec);
- this.methodName = methodName;
- this.methodArgs = methodArgs;
- }
-
- boolean resolve(ReferenceType refType) throws JDEException {
- if (!isValidMethodName(methodName)) {
- throw new JDEException("'"+methodName+"' is not a
valid method name.");
- }
- if (!(refType instanceof ClassType)) {
- throw new JDEException("'"+refType+"' is not a
Class");
- }
- Location location = getLocation((ClassType)refType);
- if (location == null) {
- throw new JDEException("Can't set breakpoint on an abstract/native
method");
- }
- BreakpointRequest br =
refType.virtualMachine().eventRequestManager().createBreakpointRequest(location);
-
- setRequest(br);
- return true;
- }
-
- private Location getLocation(ClassType clazz) throws JDEException {
- Method method = findMatchingMethod(clazz);
- Location location = method.location();
- return location;
- }
-
- public String getMethodName() {
- return methodName;
- }
-
- public List getMethodArgs() {
- return methodArgs;
- }
-
- public String toString() {
- StringBuffer buffer = new StringBuffer("break in_method ");
- if (refSpec instanceof SourceNameReferenceTypeSpec) {
- buffer.append(((SourceNameReferenceTypeSpec)refSpec).getSourceName());
- } else if (refSpec instanceof PatternReferenceTypeSpec) {
- buffer.append(((PatternReferenceTypeSpec)refSpec).getClassPattern());
- }
- buffer.append(" "+methodName+" ");
- if (methodArgs != null) {
- Iterator iter = methodArgs.iterator();
- boolean first = true;
- buffer.append('(');
- while (iter.hasNext()) {
- if (!first) {
- buffer.append(',');
- }
- buffer.append((String)iter.next());
- first = false;
- }
- buffer.append(")");
- }
- return buffer.toString();
- }
-
- private boolean isValidMethodName(String s) {
- return isJavaIdentifier(s) ||
- s.equals("<init>") ||
- s.equals("<clinit>");
- }
-
- /*
- * Compare a method's argument types with a Vector of type names.
- * Return true if each argument type has a name identical to the
- * corresponding string in the vector and if the number of
- * arguments in the method matches the number of names passed
- */
- private boolean compareArgTypes(Method method, List nameList) {
- List argTypeNames = method.argumentTypeNames();
-
-
- // If argument counts differ, we can stop here
- if (argTypeNames.size() != nameList.size()) {
- return false;
- }
-
- // Compare each argument type's name
- for (int i=0; i<argTypeNames.size(); ++i) {
- String comp1 = (String)argTypeNames.get(i);
- String comp2 = (String)nameList.get(i);
- if (! comp1.equals(comp2)) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Remove unneeded spaces and expand class names to fully
- * qualified names, if necessary and possible.
- */
- private String normalizeArgTypeName(String name)
- throws JDEException {
- /*
- * Separate the type name from any array modifiers,
- * stripping whitespace after the name ends
- */
- int i = 0;
- StringBuffer typePart = new StringBuffer();
- StringBuffer arrayPart = new StringBuffer();
- name = name.trim();
- while (i < name.length()) {
- char c = name.charAt(i);
- if (Character.isWhitespace(c) || c == '[') {
- break; // name is complete
- }
- typePart.append(c);
- i++;
- }
- while (i < name.length()) {
- char c = name.charAt(i);
- if ( (c == '[') || (c == ']') ) {
- arrayPart.append(c);
- } else if (!Character.isWhitespace(c)) {
- throw new JDEException("At least one of the arguments of method
'"+methodName+"' is invalid.");
- }
- i++;
- }
- name = typePart.toString();
-
- /*
- * When there's no sign of a package name already,
- * try to expand the
- * the name to a fully qualified class name
- */
- if ((name.indexOf('.') == -1) || name.startsWith("*.")) {
- try {
- List refs = app.findClassesMatchingPattern(name);
- // if more than one class match, take the first, but
- // inform anyways.
- if (refs.size() > 0) {
- name = ((ReferenceType)(refs.get(0))).name();
- // warn
- if (refs.size() > 1) {
- app.signal(WARNING, "(Method Breakpoint Warning) More than one classes matched
resolving an argument for method '"+methodName+"'. Defaulting to the
first match.");
- }
- }
- } catch (IllegalArgumentException e) {
- // We'll try the name as is
- }
- }
- name += arrayPart.toString();
- return name;
- }
-
- /*
- * Attempt an unambiguous match of the method name and
- * argument specification to a method. If no arguments
- * are specified, the method must not be overloaded.
- * Otherwise, the argument types much match exactly
- */
- private Method findMatchingMethod(ClassType clazz)
- throws JDEException {
-
- // Normalize the argument string once before looping below.
- List argTypeNames = null;
- if (methodArgs != null) {
- argTypeNames = new ArrayList(methodArgs.size());
- Iterator iter = methodArgs.iterator();
- while (iter.hasNext()) {
- String name = (String)iter.next();
- name = normalizeArgTypeName(name);
- argTypeNames.add(name);
- }
- }
-
- // Check each method in the class for matches
- Iterator iter = clazz.methods().iterator();
- Method firstMatch = null; // first method with matching name
- Method exactMatch = null; // (only) method with same name & sig
- int matchCount = 0; // > 1 implies overload
- while (iter.hasNext()) {
- Method candidate = (Method)iter.next();
-
- if (candidate.name().equals(getMethodName())) {
- matchCount++;
-
- // Remember the first match in case it is the only one
- if (matchCount == 1) {
- firstMatch = candidate;
- }
-
- // If argument types were specified, check against candidate
- if ((argTypeNames != null)
- && compareArgTypes(candidate, argTypeNames) == true) {
- exactMatch = candidate;
- break;
- }
- }
- }
-
- // Determine method for breakpoint
- Method method = null;
- if (exactMatch != null) {
- // Name and signature match
- method = exactMatch;
- } else if ((argTypeNames == null) && (matchCount > 0)) {
- // At least one name matched and no arg types were specified
- if (matchCount == 1) {
- method = firstMatch; // Only one match; safe to use it
- } else {
- throw new JDEException("Ambiguous method
'"+methodName+"'. Specify arguments.");
- }
- } else {
- throw new JDEException("No method named
'"+methodName+"' in class.");
- }
- return method;
- }
-
-} // MethodBreakpointSpec
+
+package jde.debugger.spec;
+
+import jde.debugger.*;
+
+import com.sun.jdi.*;
+import com.sun.jdi.request.*;
+
+import java.util.*;
+
+/**
+ * MethodBreakpointSpec.java
+ * <p>
+ * Funnily, it seems this class actually supports setting breakpoints in
+ * a particular method of an arbitrary filename! since it's very weird, it's
+ * not supported. Let us know if you require such a feature...
+ * <p>
+ * Created: Thu Jul 15 15:52:45 1999
+ *
+ * @author Amit Kumar
+ * @since 0.1
+ */
+
+public class MethodBreakpointSpec extends BreakpointSpec {
+
+ String methodName;
+ List methodArgs;
+
+ public MethodBreakpointSpec(DebuggeeProcess proc, ReferenceTypeSpec refSpec,
+ String methodName, List methodArgs) {
+ super(proc, refSpec);
+ this.methodName = methodName;
+ this.methodArgs = methodArgs;
+ }
+
+ boolean resolve(ReferenceType refType) throws JDEException {
+ if (!isValidMethodName(methodName)) {
+ throw new JDEException("'"+methodName+"' is not a
valid method name.");
+ }
+ if (!(refType instanceof ClassType)) {
+ throw new JDEException("'"+refType+"' is not a
Class");
+ }
+ Location location = getLocation((ClassType)refType);
+ if (location == null) {
+ throw new JDEException("Can't set breakpoint on an abstract/native
method");
+ }
+ BreakpointRequest br =
refType.virtualMachine().eventRequestManager().createBreakpointRequest(location);
+
+ setRequest(br);
+ return true;
+ }
+
+ private Location getLocation(ClassType clazz) throws JDEException {
+ Method method = findMatchingMethod(clazz);
+ Location location = method.location();
+ return location;
+ }
+
+ public String getMethodName() {
+ return methodName;
+ }
+
+ public List getMethodArgs() {
+ return methodArgs;
+ }
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer("break in_method ");
+ if (refSpec instanceof SourceNameReferenceTypeSpec) {
+ buffer.append(((SourceNameReferenceTypeSpec)refSpec).getSourceName());
+ } else if (refSpec instanceof PatternReferenceTypeSpec) {
+ buffer.append(((PatternReferenceTypeSpec)refSpec).getClassPattern());
+ }
+ buffer.append(" "+methodName+" ");
+ if (methodArgs != null) {
+ Iterator iter = methodArgs.iterator();
+ boolean first = true;
+ buffer.append('(');
+ while (iter.hasNext()) {
+ if (!first) {
+ buffer.append(',');
+ }
+ buffer.append((String)iter.next());
+ first = false;
+ }
+ buffer.append(")");
+ }
+ return buffer.toString();
+ }
+
+ private boolean isValidMethodName(String s) {
+ return isJavaIdentifier(s) ||
+ s.equals("<init>") ||
+ s.equals("<clinit>");
+ }
+
+ /*
+ * Compare a method's argument types with a Vector of type names.
+ * Return true if each argument type has a name identical to the
+ * corresponding string in the vector and if the number of
+ * arguments in the method matches the number of names passed
+ */
+ private boolean compareArgTypes(Method method, List nameList) {
+ List argTypeNames = method.argumentTypeNames();
+
+
+ // If argument counts differ, we can stop here
+ if (argTypeNames.size() != nameList.size()) {
+ return false;
+ }
+
+ // Compare each argument type's name
+ for (int i=0; i<argTypeNames.size(); ++i) {
+ String comp1 = (String)argTypeNames.get(i);
+ String comp2 = (String)nameList.get(i);
+ if (! comp1.equals(comp2)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Remove unneeded spaces and expand class names to fully
+ * qualified names, if necessary and possible.
+ */
+ private String normalizeArgTypeName(String name)
+ throws JDEException {
+ /*
+ * Separate the type name from any array modifiers,
+ * stripping whitespace after the name ends
+ */
+ int i = 0;
+ StringBuffer typePart = new StringBuffer();
+ StringBuffer arrayPart = new StringBuffer();
+ name = name.trim();
+ while (i < name.length()) {
+ char c = name.charAt(i);
+ if (Character.isWhitespace(c) || c == '[') {
+ break; // name is complete
+ }
+ typePart.append(c);
+ i++;
+ }
+ while (i < name.length()) {
+ char c = name.charAt(i);
+ if ( (c == '[') || (c == ']') ) {
+ arrayPart.append(c);
+ } else if (!Character.isWhitespace(c)) {
+ throw new JDEException("At least one of the arguments of method
'"+methodName+"' is invalid.");
+ }
+ i++;
+ }
+ name = typePart.toString();
+
+ /*
+ * When there's no sign of a package name already,
+ * try to expand the
+ * the name to a fully qualified class name
+ */
+ if ((name.indexOf('.') == -1) || name.startsWith("*.")) {
+ try {
+ List refs = proc.findClassesMatchingPattern(name);
+ // if more than one class match, take the first, but
+ // inform anyways.
+ if (refs.size() > 0) {
+ name = ((ReferenceType)(refs.get(0))).name();
+ // warn
+ if (refs.size() > 1) {
+ jde.signal(procID, WARNING, "(Method Breakpoint Warning) More than one classes
matched resolving an argument for method '"+methodName+"'. Defaulting to
the first match.");
+ }
+ }
+ } catch (IllegalArgumentException e) {
+ // We'll try the name as is
+ }
+ }
+ name += arrayPart.toString();
+ return name;
+ }
+
+ /*
+ * Attempt an unambiguous match of the method name and
+ * argument specification to a method. If no arguments
+ * are specified, the method must not be overloaded.
+ * Otherwise, the argument types much match exactly
+ */
+ private Method findMatchingMethod(ClassType clazz)
+ throws JDEException {
+
+ // Normalize the argument string once before looping below.
+ List argTypeNames = null;
+ if (methodArgs != null) {
+ argTypeNames = new ArrayList(methodArgs.size());
+ Iterator iter = methodArgs.iterator();
+ while (iter.hasNext()) {
+ String name = (String)iter.next();
+ name = normalizeArgTypeName(name);
+ argTypeNames.add(name);
+ }
+ }
+
+ // Check each method in the class for matches
+ Iterator iter = clazz.methods().iterator();
+ Method firstMatch = null; // first method with matching name
+ Method exactMatch = null; // (only) method with same name & sig
+ int matchCount = 0; // > 1 implies overload
+ while (iter.hasNext()) {
+ Method candidate = (Method)iter.next();
+
+ if (candidate.name().equals(getMethodName())) {
+ matchCount++;
+
+ // Remember the first match in case it is the only one
+ if (matchCount == 1) {
+ firstMatch = candidate;
+ }
+
+ // If argument types were specified, check against candidate
+ if ((argTypeNames != null)
+ && compareArgTypes(candidate, argTypeNames) == true) {
+ exactMatch = candidate;
+ break;
+ }
+ }
+ }
+
+ // Determine method for breakpoint
+ Method method = null;
+ if (exactMatch != null) {
+ // Name and signature match
+ method = exactMatch;
+ } else if ((argTypeNames == null) && (matchCount > 0)) {
+ // At least one name matched and no arg types were specified
+ if (matchCount == 1) {
+ method = firstMatch; // Only one match; safe to use it
+ } else {
+ throw new JDEException("Ambiguous method
'"+methodName+"'. Specify arguments.");
+ }
+ } else {
+ throw new JDEException("No method named
'"+methodName+"' in class.");
+ }
+ return method;
+ }
+
+} // MethodBreakpointSpec
Index: xemacs-packages/jde/java/src/jde/debugger/spec/ModificationWatchpointSpec.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/spec/ModificationWatchpointSpec.java,v
retrieving revision 1.1
diff -u -r1.1 ModificationWatchpointSpec.java
---
xemacs-packages/jde/java/src/jde/debugger/spec/ModificationWatchpointSpec.java 2000/08/13
13:39:23 1.1
+++
xemacs-packages/jde/java/src/jde/debugger/spec/ModificationWatchpointSpec.java 2001/08/15
05:27:51
@@ -1,36 +1,36 @@
-
-package jde.debugger.spec;
-
-import jde.debugger.*;
-
-import com.sun.jdi.*;
-import com.sun.jdi.request.*;
-
-/**
- * ModificationWatchpointSpec.java
- * <p>
- *
- * <p>
- * Created: Tue Aug 3 15:42:41 1999
- *
- * @author Amit Kumar
- * @since 0.1
- */
-
-public class ModificationWatchpointSpec extends WatchpointSpec {
-
- public ModificationWatchpointSpec(Application app, ReferenceTypeSpec refSpec, String
fieldName) {
- super(app, refSpec, fieldName);
- }
-
- boolean resolve(ReferenceType refType) throws JDEException {
- Field field = refType.fieldByName(fieldName);
- if (field == null) {
- throw new JDEException("'"+fieldName+"' does not exist in the
class");
- }
- EventRequest er =
refType.virtualMachine().eventRequestManager().createModificationWatchpointRequest(field);
- setRequest(er);
- return true;
- }
-
-} // ModificationWatchpointSpec
+
+package jde.debugger.spec;
+
+import jde.debugger.*;
+
+import com.sun.jdi.*;
+import com.sun.jdi.request.*;
+
+/**
+ * ModificationWatchpointSpec.java
+ * <p>
+ *
+ * <p>
+ * Created: Tue Aug 3 15:42:41 1999
+ *
+ * @author Amit Kumar
+ * @since 0.1
+ */
+
+public class ModificationWatchpointSpec extends WatchpointSpec {
+
+ public ModificationWatchpointSpec(DebuggeeProcess proc, ReferenceTypeSpec refSpec,
String fieldName) {
+ super(proc, refSpec, fieldName);
+ }
+
+ boolean resolve(ReferenceType refType) throws JDEException {
+ Field field = refType.fieldByName(fieldName);
+ if (field == null) {
+ throw new JDEException("'"+fieldName+"' does not exist in the
class");
+ }
+ EventRequest er =
refType.virtualMachine().eventRequestManager().createModificationWatchpointRequest(field);
+ setRequest(er);
+ return true;
+ }
+
+} // ModificationWatchpointSpec
Index: xemacs-packages/jde/java/src/jde/debugger/spec/PatternReferenceTypeSpec.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/spec/PatternReferenceTypeSpec.java,v
retrieving revision 1.1
diff -u -r1.1 PatternReferenceTypeSpec.java
---
xemacs-packages/jde/java/src/jde/debugger/spec/PatternReferenceTypeSpec.java 2000/08/13
13:39:23 1.1
+++
xemacs-packages/jde/java/src/jde/debugger/spec/PatternReferenceTypeSpec.java 2001/08/15
05:27:51
@@ -1,85 +1,85 @@
-
-package jde.debugger.spec;
-
-import jde.debugger.*;
-
-import com.sun.jdi.*;
-
-import java.util.*;
-
-/**
- * PatternReferenceTypeSpec.java
- *
- *
- * Created: Mon Jul 19 12:47:26 1999
- *
- * @author Amit Kumar
- * @since 0.1
- */
-
-public class PatternReferenceTypeSpec implements ReferenceTypeSpec {
-
- final String classPattern;
- final boolean isWild;
-
- public PatternReferenceTypeSpec(String classPattern) {
- // XXX should we check the validity of the class name as
- // suggested in the checkClassName doc below?
- isWild = classPattern.startsWith("*.");
- if (isWild) {
- this.classPattern = classPattern.substring(1);
- } else {
- this.classPattern = classPattern;
- }
- }
-
- public String getClassPattern() { return classPattern; }
-
- public boolean matches(ReferenceType refType) {
- if (isWild) {
- return refType.name().endsWith(classPattern);
- } else {
- return refType.name().equals(classPattern);
- }
- }
-
- private void checkClassName(String className) throws JDEException {
- // Do stricter checking of class name validity on deferred
- // because if the name is invalid, it will
- // never match a future loaded class, and we'll be silent
- // about it.
- StringTokenizer tokenizer = new StringTokenizer(className, ".");
- boolean first = true;
- while (tokenizer.hasMoreTokens()) {
- String token = tokenizer.nextToken();
- // Each dot-separated piece must be a valid identifier
- // and the first token can also be "*". (Note that
- // numeric class ids are not permitted. They must
- // match a loaded class.)
- if (!isJavaIdentifier(token) && !(first &&
token.equals("*"))) {
- throw new JDEException("(Class Pattern Resolution Error) Invalid
pattern '"+className+"'");
- }
- first = false;
- }
- }
-
- private boolean isJavaIdentifier(String s) {
- if (s.length() == 0) {
- return false;
- }
- if (! Character.isJavaIdentifierStart(s.charAt(0))) {
- return false;
- }
- for (int i = 1; i < s.length(); i++) {
- if (! Character.isJavaIdentifierPart(s.charAt(i))) {
- return false;
- }
- }
- return true;
- }
-
- public String toString() {
- return isWild? "*." + classPattern : classPattern;
- }
-
-} // PatternReferenceTypeSpec
+
+package jde.debugger.spec;
+
+import jde.debugger.*;
+
+import com.sun.jdi.*;
+
+import java.util.*;
+
+/**
+ * PatternReferenceTypeSpec.java
+ *
+ *
+ * Created: Mon Jul 19 12:47:26 1999
+ *
+ * @author Amit Kumar
+ * @since 0.1
+ */
+
+public class PatternReferenceTypeSpec implements ReferenceTypeSpec {
+
+ final String classPattern;
+ final boolean isWild;
+
+ public PatternReferenceTypeSpec(String classPattern) {
+ // XXX should we check the validity of the class name as
+ // suggested in the checkClassName doc below?
+ isWild = classPattern.startsWith("*.");
+ if (isWild) {
+ this.classPattern = classPattern.substring(1);
+ } else {
+ this.classPattern = classPattern;
+ }
+ }
+
+ public String getClassPattern() { return classPattern; }
+
+ public boolean matches(ReferenceType refType) {
+ if (isWild) {
+ return refType.name().endsWith(classPattern);
+ } else {
+ return refType.name().equals(classPattern);
+ }
+ }
+
+ private void checkClassName(String className) throws JDEException {
+ // Do stricter checking of class name validity on deferred
+ // because if the name is invalid, it will
+ // never match a future loaded class, and we'll be silent
+ // about it.
+ StringTokenizer tokenizer = new StringTokenizer(className, ".");
+ boolean first = true;
+ while (tokenizer.hasMoreTokens()) {
+ String token = tokenizer.nextToken();
+ // Each dot-separated piece must be a valid identifier
+ // and the first token can also be "*". (Note that
+ // numeric class ids are not permitted. They must
+ // match a loaded class.)
+ if (!isJavaIdentifier(token) && !(first &&
token.equals("*"))) {
+ throw new JDEException("(Class Pattern Resolution Error) Invalid
pattern '"+className+"'");
+ }
+ first = false;
+ }
+ }
+
+ private boolean isJavaIdentifier(String s) {
+ if (s.length() == 0) {
+ return false;
+ }
+ if (! Character.isJavaIdentifierStart(s.charAt(0))) {
+ return false;
+ }
+ for (int i = 1; i < s.length(); i++) {
+ if (! Character.isJavaIdentifierPart(s.charAt(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public String toString() {
+ return isWild? "*." + classPattern : classPattern;
+ }
+
+} // PatternReferenceTypeSpec
Index: xemacs-packages/jde/java/src/jde/debugger/spec/ReferenceTypeSpec.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/spec/ReferenceTypeSpec.java,v
retrieving revision 1.1
diff -u -r1.1 ReferenceTypeSpec.java
--- xemacs-packages/jde/java/src/jde/debugger/spec/ReferenceTypeSpec.java 2000/08/13
13:39:23 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/spec/ReferenceTypeSpec.java 2001/08/15
05:27:51
@@ -1,23 +1,23 @@
-
-package jde.debugger.spec;
-
-import com.sun.jdi.*;
-
-/**
- * ReferenceTypeSpec.java
- *
- *
- * Created: Mon Jul 19 13:19:23 1999
- *
- * @author Amit Kumar
- * @since 0.1
- */
-
-public interface ReferenceTypeSpec {
-
- /**
- * @return true if the ref type matches this spec
- */
- public boolean matches(ReferenceType refType);
-
-} // ReferenceTypeSpec
+
+package jde.debugger.spec;
+
+import com.sun.jdi.*;
+
+/**
+ * ReferenceTypeSpec.java
+ *
+ *
+ * Created: Mon Jul 19 13:19:23 1999
+ *
+ * @author Amit Kumar
+ * @since 0.1
+ */
+
+public interface ReferenceTypeSpec {
+
+ /**
+ * @return true if the ref type matches this spec
+ */
+ public boolean matches(ReferenceType refType);
+
+} // ReferenceTypeSpec
Index: xemacs-packages/jde/java/src/jde/debugger/spec/SourceNameReferenceTypeSpec.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/spec/SourceNameReferenceTypeSpec.java,v
retrieving revision 1.1
diff -u -r1.1 SourceNameReferenceTypeSpec.java
---
xemacs-packages/jde/java/src/jde/debugger/spec/SourceNameReferenceTypeSpec.java 2000/08/13
13:39:24 1.1
+++
xemacs-packages/jde/java/src/jde/debugger/spec/SourceNameReferenceTypeSpec.java 2001/08/15
05:27:51
@@ -1,64 +1,64 @@
-
-package jde.debugger.spec;
-
-import jde.debugger.*;
-
-import com.sun.jdi.*;
-
-import java.util.*;
-
-/**
- * SourceNameReferenceTypeSpec.java
- *
- *
- * Created: Mon Jul 19 13:52:21 1999
- *
- * @author Amit Kumar
- * @since 0.1
- */
-
-public class SourceNameReferenceTypeSpec implements ReferenceTypeSpec {
-
- final String sourceName;
- final int lineNumber;
-
- public SourceNameReferenceTypeSpec(String src, int line) {
- sourceName = src;
- lineNumber = line;
- }
-
- public String getSourceName() {
- return sourceName;
- }
-
- /**
- * Does the specified ReferenceType match this spec.
- */
- public boolean matches(ReferenceType refType) {
- try {
- if (refType.sourceName().equals(sourceName)) {
- try {
- // Jdebug.theDebugger.signalDebug("Matching " +
- // refType.sourceName() + ", " + lineNumber);
- List locs = refType.locationsOfLine(lineNumber);
- // Jdebug.theDebugger.signalDebug(" Matched");
- // if we don't throw an exception then it was found
-
- return (locs.size() > 0) ? true : false;
-
- } catch(AbsentInformationException exc) {
- } catch(ObjectCollectedException exc) {
- } catch(InvalidLineNumberException exc) {
- } catch(ClassNotPreparedException exc) {
- // -- should not happen, so don't catch this ---
- }
- }
- } catch(AbsentInformationException exc) {
- // for sourceName(), fall through
- }
- return false;
- }
-
-public String toString() { return sourceName+" "+lineNumber; }
-
-} // SourceNameReferenceTypeSpec
+
+package jde.debugger.spec;
+
+import jde.debugger.*;
+
+import com.sun.jdi.*;
+
+import java.util.*;
+
+/**
+ * SourceNameReferenceTypeSpec.java
+ *
+ *
+ * Created: Mon Jul 19 13:52:21 1999
+ *
+ * @author Amit Kumar
+ * @since 0.1
+ */
+
+public class SourceNameReferenceTypeSpec implements ReferenceTypeSpec {
+
+ final String sourceName;
+ final int lineNumber;
+
+ public SourceNameReferenceTypeSpec(String src, int line) {
+ sourceName = src;
+ lineNumber = line;
+ }
+
+ public String getSourceName() {
+ return sourceName;
+ }
+
+ /**
+ * Does the specified ReferenceType match this spec.
+ */
+ public boolean matches(ReferenceType refType) {
+ try {
+ if (refType.sourceName().equals(sourceName)) {
+ try {
+ // Jdebug.theDebugger.signalDebug("Matching " +
+ // refType.sourceName() + ", " + lineNumber);
+ List locs = refType.locationsOfLine(lineNumber);
+ // Jdebug.theDebugger.signalDebug(" Matched");
+ // if we don't throw an exception then it was found
+
+ return (locs.size() > 0) ? true : false;
+
+ } catch(AbsentInformationException exc) {
+ } catch(ObjectCollectedException exc) {
+ } catch(InvalidLineNumberException exc) {
+ } catch(ClassNotPreparedException exc) {
+ // -- should not happen, so don't catch this ---
+ }
+ }
+ } catch(AbsentInformationException exc) {
+ // for sourceName(), fall through
+ }
+ return false;
+ }
+
+public String toString() { return sourceName+" "+lineNumber; }
+
+} // SourceNameReferenceTypeSpec
Index: xemacs-packages/jde/java/src/jde/debugger/spec/WatchpointSpec.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/debugger/spec/WatchpointSpec.java,v
retrieving revision 1.1
diff -u -r1.1 WatchpointSpec.java
--- xemacs-packages/jde/java/src/jde/debugger/spec/WatchpointSpec.java 2000/08/13
13:39:24 1.1
+++ xemacs-packages/jde/java/src/jde/debugger/spec/WatchpointSpec.java 2001/08/15
05:27:51
@@ -1,47 +1,47 @@
-
-package jde.debugger.spec;
-
-import jde.debugger.*;
-
-import com.sun.jdi.*;
-import com.sun.jdi.request.*;
-
-/**
- * WatchpointSpec.java
- * <p>
- *
- * <p>
- * Created: Tue Aug 3 15:25:42 1999
- *
- * @author Amit Kumar
- * @since 0.1
- */
-
-abstract public class WatchpointSpec extends EventRequestSpec {
-
- /**
- * For certain specs that need it, the object ID (for whatever need)
- * is stored in the objectID
- */
- public static final Object objectIDKey = "objectID";
- Long objectID = null;
- public void setObjectID(Long objectID) {
- this.objectID = objectID;
- if (request != null)
- request.putProperty(objectIDKey, objectID);
- }
-
- String fieldName;
-
- public WatchpointSpec(Application app, ReferenceTypeSpec refSpec,
- String fieldName) {
- super(app, refSpec);
- this.fieldName = fieldName;
- }
-
- void setRequest(EventRequest request) {
- request.putProperty(objectIDKey, objectID);
- super.setRequest(request);
- }
-
-} // WatchpointSpec
+
+package jde.debugger.spec;
+
+import jde.debugger.*;
+
+import com.sun.jdi.*;
+import com.sun.jdi.request.*;
+
+/**
+ * WatchpointSpec.java
+ * <p>
+ *
+ * <p>
+ * Created: Tue Aug 3 15:25:42 1999
+ *
+ * @author Amit Kumar
+ * @since 0.1
+ */
+
+abstract public class WatchpointSpec extends EventRequestSpec {
+
+ /**
+ * For certain specs that need it, the object ID (for whatever need)
+ * is stored in the objectID
+ */
+ public static final Object objectIDKey = "objectID";
+ Long objectID = null;
+ public void setObjectID(Long objectID) {
+ this.objectID = objectID;
+ if (request != null)
+ request.putProperty(objectIDKey, objectID);
+ }
+
+ String fieldName;
+
+ public WatchpointSpec(DebuggeeProcess proc, ReferenceTypeSpec refSpec,
+ String fieldName) {
+ super(proc, refSpec);
+ this.fieldName = fieldName;
+ }
+
+ void setRequest(EventRequest request) {
+ request.putProperty(objectIDKey, objectID);
+ super.setRequest(request);
+ }
+
+} // WatchpointSpec
Index: xemacs-packages/jde/java/src/jde/util/Completion.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/util/Completion.java,v
retrieving revision 1.1
diff -u -r1.1 Completion.java
--- xemacs-packages/jde/java/src/jde/util/Completion.java 2000/08/13 13:41:45 1.1
+++ xemacs-packages/jde/java/src/jde/util/Completion.java 2001/08/15 05:27:52
@@ -1,7 +1,9 @@
/*
* Completion.java
- * Copyright (C) 1999 Rodrigo Reyes (reyes(a)chez.com)
+ * Copyright (C) 1999, 2001 Rodrigo Reyes (reyes(a)chez.com)
*
+ * $Revision: 1.5 $
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -23,6 +25,7 @@
import java.lang.reflect.Field;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
+import java.lang.reflect.Member;
/**
* This class provides completion facilities.
@@ -32,17 +35,139 @@
public class Completion {
- private static void listClassInfo(Class c)
+ /**
+ * Tests whether a class is an ancestor of another class.
+ * This method prints "t" to standard out if the class is an ancestor
+ * of the other class. If the class is not an ancestor or either class
+ * cannot be found, this method prints nil to standard out.
+ * @param ancestor Name of the ancestor class
+ * @param child Name of the supposed child class
+ */
+ public static void isAncestorOf( String ancestor, String child)
{
+ try
+ {
+ Class classAncestor = Class.forName( ancestor );
+ Class classChild = Class.forName( child );
+ if( classAncestor.isAssignableFrom( classChild ) )
+ System.out.println( "t" );
+ else
+ System.out.println( "nil" );
+ }//try
+ catch( Exception ex)
+ {
+ System.out.println( "nil" );
+ }//catch
+ }//met
+
+ /**
+ *Returns true if the Member is accessible to the specified level of protection.
+ *@param member the Member to check
+ *@param level the level of protection. 0 means accessible to a class that inherits from
the class whose
+ *member is a member. 1 means accessible as a private only field.
+ *@return if the Member is accessible to the specified level of protection.
+ */
+ private static boolean isAccessible( Member member, int level)
+ {
+ switch(level)
+ {
+ case 0: return Modifier.isProtected( member.getModifiers() );
+
+ case 1: return Modifier.isPrivate( member.getModifiers() );
+
+ default: return false;
+ }//switch
+ }//met
+
+ private static void listClassInfo(Class c, int level)
+ {
System.out.println("(list ");
+
+ System.out.print("(list ");
+ //We first get all the public fields
+ Field[] fields = c.getFields();
+ for (int index=0; index<fields.length; index++) {
+ Field field = fields[index];
+ System.out.print("(list \""+field.getName()+"\"
\""+
+ className(field.getType())+"\")");
+ }
+ //we add the protected/private fields depending on the access level
+ fields = c.getDeclaredFields();
+ for (int index=0; index<fields.length; index++) {
+ Field field = fields[index];
+ if (isAccessible( field, level))
+ System.out.print("(list \""+field.getName()+"\"
\""+
+ className(field.getType())+"\")");
+ }
+ System.out.println(")");
+
+
+ System.out.print("(list ");
+ //we first get all the public constructors
+ Constructor[] constrs = c.getConstructors();
+ for (int index=0; index<constrs.length; index++) {
+ Constructor constructor = constrs[index];
+ System.out.print("(list \"");
+ System.out.print(constructor.getName()+"\" ");
+ listClassArray(constructor.getParameterTypes());
+ System.out.print(")");
+ }
+ constrs = c.getDeclaredConstructors();
+ for (int index=0; index<constrs.length; index++) {
+ Constructor constructor = constrs[index];
+ if( isAccessible( constructor,level) )
+ {
+ System.out.print("(list \"");
+ System.out.print(constructor.getName()+"\" ");
+ listClassArray(constructor.getParameterTypes());
+ System.out.print(")");
+ }
+ }
+ System.out.print(")");
+
+
+
+ System.out.println("(list ");
+ Method[] methods = c.getMethods();
+ for (int index=0; index<methods.length; index++) {
+ Method method = methods[index];
+ System.out.print("(list \"");
+ System.out.print(method.getName()+"\" \"");
+ System.out.print(className(method.getReturnType()) + "\" ");
+ listClassArray(method.getParameterTypes());
+ System.out.print(")");
+ }
+ methods = c.getDeclaredMethods();
+ for (int index=0; index<methods.length; index++) {
+ Method method = methods[index];
+ if (isAccessible( method, level))
+ {
+ System.out.print("(list \"");
+ System.out.print(method.getName()+"\" \"");
+ System.out.print(className(method.getReturnType()) + "\" ");
+ listClassArray(method.getParameterTypes());
+ System.out.print(")");
+ }
+ }
+ System.out.println(")");
+
+ System.out.println(")");
+ return;
+ }
+
+ private static void listClassInfo(Class c)
+ {
+ System.out.println("(list ");
+
Field[] fields = c.getFields();
System.out.print("(list ");
for (int index=0; index<fields.length; index++) {
Field field = fields[index];
if (Modifier.isPublic(field.getModifiers()))
- System.out.print("\""+field.getName()+"\" ");
+ System.out.print("(list \""+field.getName()+"\"
\""+
+ className(field.getType())+"\")");
}
System.out.println(")");
@@ -89,7 +214,17 @@
Class c = Class.forName(className);
if (c != null)
listClassInfo(c);
- } catch (ClassNotFoundException cnfe) { }
+ } catch (ClassNotFoundException cnfe) {System.out.println("nil");}
+ }
+
+ public static void getClassInfo(String className, int accessLevel)
+ {
+ try {
+
+ Class c = Class.forName(className);
+ if (c != null)
+ listClassInfo(c,accessLevel);
+ } catch (ClassNotFoundException cnfe) {System.out.println("nil");}
}
/**
@@ -98,7 +233,7 @@
*
* @param className a value of type 'String'
*/
- public static void getClassInfo(String className, String[]imports)
+ public static void getClassInfo(String className, String[]imports, int accessLevel)
{
// System.out.println("length : " + imports.length);
for (int i=0; i<imports.length; i++)
@@ -108,7 +243,7 @@
Class c = Class.forName(name);
if (c != null)
{
- listClassInfo(c);
+ listClassInfo(c,accessLevel);
}
} catch (ClassNotFoundException cnfe) { }
@@ -140,8 +275,14 @@
/*
* $Log: Completion.java,v $
- * Revision 1.1 2000/08/13 13:41:45 michaels
- * Initial checkin.
+ * Revision 1.5 2000/08/10 08:46:25 paulk
+ * Now outputs nil if class info not found.
+ *
+ * Revision 1.4 2000/08/01 07:44:49 paulk
+ * Adds an isAncestorOf method. Now gets private and protected methods and fields. Thanks
to Stephan Nicolas.
+ *
+ * Revision 1.3 2000/07/27 04:49:52 paulk
+ * Now returns the type as well as name of each public field of a class. Thanks to
Stephane Nicolas <s.nicolas(a)videotron.ca>.
*
* Revision 1.2 2000/02/09 04:48:41 paulk
* Now uses Modifier.isPublic() to test whether a class's fields,
Index: xemacs-packages/jde/java/src/jde/util/JdeUtilities.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/util/JdeUtilities.java,v
retrieving revision 1.2
diff -u -r1.2 JdeUtilities.java
--- xemacs-packages/jde/java/src/jde/util/JdeUtilities.java 2001/02/12 06:36:04 1.2
+++ xemacs-packages/jde/java/src/jde/util/JdeUtilities.java 2001/08/15 05:27:52
@@ -1,6 +1,6 @@
/*
* JdeUtilities.java
- * $Revision: 1.2 $
+ * $Revision: 1.5 $
*
* Copyright (C) 1999-2000 Len Trigg (trigg(a)cs.waikato.ac.nz)
* Copyright (C) 1999-2000 Paul Kinnucan (paulk(a)mathworks.com)
@@ -36,7 +36,7 @@
*
* @author Len Trigg (trigg(a)cs.waikato.ac.nz)
* @author Paul Kinnucan (paulk(a)mathworks.com)
- * @version $Revision: 1.2 $
+ * @version $Revision: 1.5 $
*/
public class JdeUtilities {
@@ -234,9 +234,6 @@
/*
* $Log: JdeUtilities.java,v $
- * Revision 1.2 2001/02/12 06:36:04 paulk
- * Updated for JDE-2.2.7.
- *
* Revision 1.5 2000/12/19 04:16:38 paulk
* Now handles case where a directory is unreadable. Thanks to Michael Duvigneau
<5duvigne(a)informatik.uni-hamburg.de> for diagnosing this error.
*
cvs server: Diffing xemacs-packages/jde/java/src/jde/wizards
Index: xemacs-packages/jde/java/src/jde/wizards/ClassRegistry.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/wizards/ClassRegistry.java,v
retrieving revision 1.1
diff -u -r1.1 ClassRegistry.java
--- xemacs-packages/jde/java/src/jde/wizards/ClassRegistry.java 2000/08/13 13:42:14 1.1
+++ xemacs-packages/jde/java/src/jde/wizards/ClassRegistry.java 2001/08/15 05:27:52
@@ -2,8 +2,8 @@
* Copyright (c) Eric D. Friedman 1998. All Rights Reserved.
* Copyright (c) Paul Kinnucan 1998. All Rights Reserved.
*
- * $Revision: 1.1 $
- * $Date: 2000/08/13 13:42:14 $
+ * $Revision: 1.2 $
+ * $Date: 1998/11/01 03:49:32 $
*
* InterfaceFactory is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -26,7 +26,7 @@
* Defines interface for class registries.
*
* @author Eric D. Friedman
- * @version $Revision: 1.1 $
+ * @version $Revision: 1.2 $
*/
public interface ClassRegistry
Index: xemacs-packages/jde/java/src/jde/wizards/DefaultNameFactory.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/wizards/DefaultNameFactory.java,v
retrieving revision 1.2
diff -u -r1.2 DefaultNameFactory.java
--- xemacs-packages/jde/java/src/jde/wizards/DefaultNameFactory.java 2001/02/12
06:42:17 1.2
+++ xemacs-packages/jde/java/src/jde/wizards/DefaultNameFactory.java 2001/08/15 05:27:52
@@ -3,7 +3,7 @@
* Copyright (c) Paul Kinnucan 1998. All Rights Reserved.
*
* $Revision: 1.2 $
- * $Date: 2001/02/12 06:42:17 $
+ * $Date: 1998/11/01 03:51:05 $
*
* InterfaceFactory is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
Index: xemacs-packages/jde/java/src/jde/wizards/DelegateFactory.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/wizards/DelegateFactory.java,v
retrieving revision 1.1
diff -u -r1.1 DelegateFactory.java
--- xemacs-packages/jde/java/src/jde/wizards/DelegateFactory.java 2001/02/12
06:40:59 1.1
+++ xemacs-packages/jde/java/src/jde/wizards/DelegateFactory.java 2001/08/15 05:27:52
@@ -3,8 +3,8 @@
* Copyright (c) Paul Kinnucan 2000. All Rights Reserved.
* Copyright (c) Charles Hart 2000. All Rights Reserved.
*
- * $Revision: 1.1 $
- * $Date: 2001/02/12 06:40:59 $
+ * $Revision: 1.3 $
+ * $Date: 2000/08/03 04:31:20 $
*
* DelegateFactory is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -37,7 +37,7 @@
* multiple interfaces when invoked from the command line.
*
* @author Charles Hart, Eric D. Friedman, and Paul Kinnucan
- * @version $Revision: 1.1 $
+ * @version $Revision: 1.3 $
*/
public class DelegateFactory extends MethodFactory
@@ -276,9 +276,6 @@
/*
* $Log: DelegateFactory.java,v $
- * Revision 1.1 2001/02/12 06:40:59 paulk
- * Initial XEmacs version.
- *
* Revision 1.3 2000/08/03 04:31:20 paulk
* Add support for generating a see secton in the Javadoc comment for a method. Thanks to
raffael.herzog(a)comartis.com
*
Index: xemacs-packages/jde/java/src/jde/wizards/ImportWizard.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/wizards/ImportWizard.java,v
retrieving revision 1.1
diff -u -r1.1 ImportWizard.java
--- xemacs-packages/jde/java/src/jde/wizards/ImportWizard.java 2000/08/13 13:42:14 1.1
+++ xemacs-packages/jde/java/src/jde/wizards/ImportWizard.java 2001/08/15 05:27:52
@@ -206,9 +206,6 @@
/*
* $Log: ImportWizard.java,v $
- * Revision 1.1 2000/08/13 13:42:14 michaels
- * Initial checkin.
- *
* Revision 1.4 1999/06/17 17:49:27 paulk
* Added change log to end of file.
*
Index: xemacs-packages/jde/java/src/jde/wizards/InterfaceFactory.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/wizards/InterfaceFactory.java,v
retrieving revision 1.2
diff -u -r1.2 InterfaceFactory.java
--- xemacs-packages/jde/java/src/jde/wizards/InterfaceFactory.java 2001/02/12
06:42:17 1.2
+++ xemacs-packages/jde/java/src/jde/wizards/InterfaceFactory.java 2001/08/15 05:27:52
@@ -2,8 +2,8 @@
* Copyright (c) Eric D. Friedman 1998. All Rights Reserved.
* Copyright (c) Paul Kinnucan 1998. All Rights Reserved.
*
- * $Revision: 1.2 $
- * $Date: 2001/02/12 06:42:17 $
+ * $Revision: 1.6 $
+ * $Date: 2000/08/01 08:23:22 $
*
* InterfaceFactory is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -36,7 +36,7 @@
* multiple interfaces when invoked from the command line.
*
* @author Eric D. Friedman and Paul Kinnucan
- * @version $Revision: 1.2 $
+ * @version $Revision: 1.6 $
*/
public class InterfaceFactory extends MethodFactory
@@ -255,9 +255,6 @@
/*
* $Log: InterfaceFactory.java,v $
- * Revision 1.2 2001/02/12 06:42:17 paulk
- * Updated for JDE 2.2.7.
- *
* Revision 1.6 2000/08/01 08:23:22 paulk
* Fixes bug in dump method. Thanks to Eric Friedman, eric(a)hfriedman.rdsl.lmi.net.
*
Index: xemacs-packages/jde/java/src/jde/wizards/MethodFactory.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/wizards/MethodFactory.java,v
retrieving revision 1.1
diff -u -r1.1 MethodFactory.java
--- xemacs-packages/jde/java/src/jde/wizards/MethodFactory.java 2000/08/13 13:42:15 1.1
+++ xemacs-packages/jde/java/src/jde/wizards/MethodFactory.java 2001/08/15 05:27:52
@@ -2,8 +2,8 @@
* Copyright (c) Eric D. Friedman 1998. All Rights Reserved.
* Copyright (c) Paul Kinnucan 1998. All Rights Reserved.
*
- * $Revision: 1.1 $
- * $Date: 2000/08/13 13:42:15 $
+ * $Revision: 1.2 $
+ * $Date: 1998/11/10 00:48:07 $
*
* InterfaceFactory is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -36,7 +36,7 @@
* multiple interfaces when invoked from the command line.
*
* @author Eric D. Friedman and Paul Kinnucan
- * @version $Revision: 1.1 $
+ * @version $Revision: 1.2 $
*/
public class MethodFactory
Index: xemacs-packages/jde/java/src/jde/wizards/MethodOverrideFactory.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/wizards/MethodOverrideFactory.java,v
retrieving revision 1.1
diff -u -r1.1 MethodOverrideFactory.java
--- xemacs-packages/jde/java/src/jde/wizards/MethodOverrideFactory.java 2000/08/13
13:42:15 1.1
+++ xemacs-packages/jde/java/src/jde/wizards/MethodOverrideFactory.java 2001/08/15
05:27:52
@@ -1,8 +1,8 @@
/*
* Copyright (c) Paul Kinnucan 1998. All Rights Reserved.
*
- * $Revision: 1.1 $
- * $Date: 2000/08/13 13:42:15 $
+ * $Revision: 1.3 $
+ * $Date: 2001/04/27 04:11:37 $
*
* MethodOverrideFactory is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -33,7 +33,7 @@
* superclass.
*
* @author Paul Kinnucan
- * @version $Revision: 1.1 $
+ * @version $Revision: 1.3 $
*/
public class MethodOverrideFactory extends MethodFactory
@@ -89,14 +89,11 @@
try {
Class baseClass = Class.forName(baseClassName);
- Class rootClass = Class.forName("java.lang.Object");
- while (! baseClass.equals(rootClass)) {
+ while (baseClass != null) {
- Class superclass = baseClass.getSuperclass();
+ Vector methods = overrideFactory.getMethods(baseClass, methodName);
- Vector methods = overrideFactory.getMethods(superclass, methodName);
-
int n = methods.size();
if (n > 0) {
@@ -113,7 +110,7 @@
overrideFactory.candidates.addElement(s);
}
}
- baseClass = superclass;
+ baseClass = baseClass.getSuperclass();
}
int n = overrideFactory.candidates.size();
@@ -130,8 +127,8 @@
}
else
println("(error \"Could not find any method named " +
- methodName + " in any superclass of " +
- baseClassName + "\")");
+ methodName + " in " + baseClassName +
+ " or any of its superclasses.\")");
}
catch (ClassNotFoundException ee) {
@@ -182,6 +179,13 @@
super.flush();
candidates.removeAllElements();
}
+
+ public static void main (String[] args) {
+
+
getCandidateSignatures("jde.ui.design.command.Command","getName");
+
+ } // end of main ()
+
} // MethodOverrideFactory
Index: xemacs-packages/jde/java/src/jde/wizards/NameFactory.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/wizards/NameFactory.java,v
retrieving revision 1.2
diff -u -r1.2 NameFactory.java
--- xemacs-packages/jde/java/src/jde/wizards/NameFactory.java 2001/02/12 06:42:17 1.2
+++ xemacs-packages/jde/java/src/jde/wizards/NameFactory.java 2001/08/15 05:27:52
@@ -3,7 +3,7 @@
* Copyright (c) Paul Kinnucan 1998. All Rights Reserved.
*
* $Revision: 1.2 $
- * $Date: 2001/02/12 06:42:17 $
+ * $Date: 1998/11/01 03:47:47 $
*
* InterfaceFactory is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
Index: xemacs-packages/jde/java/src/jde/wizards/Signature.java
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/jde/java/src/jde/wizards/Signature.java,v
retrieving revision 1.2
diff -u -r1.2 Signature.java
--- xemacs-packages/jde/java/src/jde/wizards/Signature.java 2001/02/12 06:42:17 1.2
+++ xemacs-packages/jde/java/src/jde/wizards/Signature.java 2001/08/15 05:27:53
@@ -2,8 +2,8 @@
* Copyright (c) Eric D. Friedman 1998. All Rights Reserved.
* Copyright (c) Paul Kinnucan 1998. All Rights Reserved.
*
- * $Revision: 1.2 $
- * $Date: 2001/02/12 06:42:17 $
+ * $Revision: 1.7 $
+ * $Date: 2000/08/03 04:28:41 $
*
* InterfaceFactory is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -29,7 +29,7 @@
* Defines a method signature.
*
* @author Eric D. Friedman
- * @version $Revision: 1.2 $
+ * @version $Revision: 1.7 $
*/
public class Signature
@@ -432,9 +432,6 @@
/*
* $Log: Signature.java,v $
- * Revision 1.2 2001/02/12 06:42:17 paulk
- * Updated for JDE 2.2.7.
- *
* Revision 1.7 2000/08/03 04:28:41 paulk
* Add support for generating a see secton in the Javadoc comment for a method. Thanks to
raffael.herzog(a)comartis.com
*
Index: xemacs-packages/jde/lisp/beanshell.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/beanshell.el,v
retrieving revision 1.4
diff -u -r1.4 beanshell.el
--- xemacs-packages/jde/lisp/beanshell.el 2001/02/25 04:45:07 1.4
+++ xemacs-packages/jde/lisp/beanshell.el 2001/08/15 05:27:53
@@ -1,5 +1,5 @@
;;; beanshell.el
-;; $Revision: 1.4 $
+;; $Revision: 1.23 $
;; Author: Paul Kinnucan <paulk(a)mathworks.com>
;; Maintainer: Paul Kinnucan
@@ -46,9 +46,19 @@
variable should be a list of strings, each of which represents an
argument. When customizing this variable, use a separate text field
for each argument."
- :group 'jde-run-options
+ :group 'bsh
:type '(repeat (string :tag "Argument")))
+(defcustom bsh-startup-directory ""
+ "Path of directory in which to start the beanshell.
+The path may start with a tilde (~) indication your
+home directory and may include environment variables.
+If this variable is the null string (the default),
+the beanshell starts in the directory of the current
+buffer."
+ :group 'bsh
+ :type 'directory)
+
(defun bsh()
"*Starts BeanShell, a Java interpreter developed by Pat Niemeyer."
@@ -90,17 +100,23 @@
"-classpath"
(jde-build-classpath
(append
+ (if jde-global-classpath
+ jde-global-classpath
+ (let ((cp (getenv "CLASSPATH")))
+ (if (stringp cp)
+ (split-string cp jde-classpath-separator))))
(list
(expand-file-name "bsh-commands" jde-java-directory)
(expand-file-name "lib/jde.jar" jde-java-directory)
- (expand-file-name "lib/bsh.jar" jde-java-directory))
- (if jde-global-classpath
- jde-global-classpath
- (split-string (getenv "CLASSPATH")
- jde-classpath-separator))))))
- (dir (if (buffer-file-name)
- (file-name-directory (buffer-file-name))
- default-directory)))
+ (expand-file-name "lib/bsh.jar" jde-java-directory)))
+ 'jde-global-classpath)))
+ (dir (cond
+ ((not (string= bsh-startup-directory ""))
+ (jde-normalize-path 'bsh-startup-directory))
+ ((buffer-file-name)
+ (file-name-directory (buffer-file-name)))
+ (t
+ default-directory))))
(setq vm-args (append vm-args bsh-vm-args))
(setq vm-args (append vm-args (list "bsh.Interpreter")))
@@ -208,8 +224,20 @@
(provide 'beanshell);
;; $Log: beanshell.el,v $
-;; Revision 1.4 2001/02/25 04:45:07 paulk
-;; Fixed bug in handling CLASSPATH environment variable.
+;; Revision 1.23 2001/05/19 02:39:18 paulk
+;; Put jde-global-classpath first on the classpath to facilitate debugging of Java code
run in hthe Beanshell.
+;;
+;; Revision 1.22 2001/04/16 05:33:20 paulk
+;; Normalized paths. Thanks to Nick Sieger.
+;;
+;; Revision 1.21 2001/03/21 20:46:34 paulk
+;; Updated bsh-internal to handle case where both jde-global-classpath and CLASSPATH
environment variable are nil. Thanks to Toru TAKAHASHI <torutk(a)alles.or.jp> for
reporting this bug and supply an initial version of a fix.
+;;
+;; Revision 1.20 2001/03/01 05:01:28 paulk
+;; Adds the customization variable bsh-startup-directory.
+;;
+;; Revision 1.19 2001/02/25 04:23:12 paulk
+;; Fixed bug in processing CLASSPATH environment variable.
;;
;; Revision 1.18 2001/02/03 07:44:26 paulk
;; Now uses jde-build-classpath to build BeanShell classpath. This allows enviromnent
variables in the classpath.
Index: xemacs-packages/jde/lisp/java.bnf
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/java.bnf,v
retrieving revision 1.2
diff -u -r1.2 java.bnf
--- xemacs-packages/jde/lisp/java.bnf 2001/02/12 05:38:22 1.2
+++ xemacs-packages/jde/lisp/java.bnf 2001/08/15 05:27:53
@@ -4,7 +4,7 @@
#
# Author: Paul F. Kinnucan, Jr. <paulk(a)mathworks.com>
# Augmented by David Ponce <david(a)dponce.com>
-# $Id: java.bnf,v 1.2 2001/02/12 05:38:22 paulk Exp $
+# $Id: java.bnf,v 1.17 2001/01/17 18:22:15 paulk Exp $
#
# java.bnf is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -431,9 +431,6 @@
;
# $Log: java.bnf,v $
-# Revision 1.2 2001/02/12 05:38:22 paulk
-# JDE 2.2.7
-#
# Revision 1.17 2001/01/17 18:22:15 paulk
# Changed the definition of formal_parameter_list to improve performance (less
# backtracking) when parsing parameters in method and constructor
Index: xemacs-packages/jde/lisp/jde-bug.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/jde-bug.el,v
retrieving revision 1.2
diff -u -r1.2 jde-bug.el
--- xemacs-packages/jde/lisp/jde-bug.el 2001/02/12 05:38:22 1.2
+++ xemacs-packages/jde/lisp/jde-bug.el 2001/08/15 05:27:54
@@ -1,11 +1,11 @@
;;; jde-bug.el -- JDEbug Interface
-;; $Revision: 1.2 $ $Date: 2001/02/12 05:38:22 $
+;; $Revision: 1.61 $ $Date: 2001/04/23 04:55:52 $
;; Author: Paul Kinnucan <paulk(a)mathworks.com>
;; Maintainer: Paul Kinnucan
;; Keywords: java, tools
-;; Copyright (C) 1997, 1998, 1999, 2000 Paul Kinnucan.
+;; Copyright (C) 1997, 1998, 1999, 2000, 2001 Paul Kinnucan.
;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
@@ -143,8 +143,8 @@
:type 'string)
-(defcustom jde-bug-debugger-command-timeout 10
- "*Length of time the JDE waits for a response from the debugger to a
command."
+(defcustom jde-bug-debugger-command-timeout 30
+ "*Length of time in seconds the JDE waits for a response from the debugger to a
command."
:group 'jde-bug
:type 'integer)
@@ -1422,6 +1422,16 @@
:initform "access"
:documentation
"Watch type: field access or modification.")
+ (object-class :initarg :object-class
+ :type string
+ :initform ""
+ :documentation
+ "Default value of class to watch.")
+ (field :initarg :field
+ :type string
+ :initform ""
+ :documentation
+ "Default value of the field to watch.")
(object-class-widget :initarg :object-class-widget
:documentation
"Widget specifying class of objects to watch.")
@@ -1466,6 +1476,7 @@
(oset this object-class-widget
(widget-create
'editable-field
+ :value (oref this object-class)
:format " %t: %v\n %h \n\n"
:size 40
:tag "Class"
@@ -1476,6 +1487,7 @@
(oset this field-name-widget
(widget-create
'editable-field
+ :value (oref this field)
:format " %t: %v\n %h \n\n"
:size 40
:tag "Field name"
@@ -1510,7 +1522,7 @@
(widget-create
'(choice
:tag "Thread Suspension Policy"
- :value "none"
+ :value "all"
:format " %t: %[Options%] %v %h\n\n"
:doc "Specify which threads to suspend on field access or modification."
(const "all")
@@ -1540,8 +1552,7 @@
(string
:format "%t: %v"
:size 40
- :tag "Filter"))))
- )
+ :tag "Filter")))))
(defmethod jde-dialog-ok ((this jde-bug-watch-field-dialog))
(let* ((obj-class (widget-value (oref this object-class-widget)))
@@ -1588,15 +1599,26 @@
"Request that the debugger watch for access of a
field of an object or class of objects."
(interactive)
- (let ((dialog (jde-bug-watch-field-dialog "watch field dialog")))
+ (let ((dialog
+ (jde-bug-watch-field-dialog
+ "watch field dialog"
+ :object-class (concat
+ "*."
+ (car (jde-parse-get-innermost-class-at-point)))
+ :field (thing-at-point 'symbol))))
(jde-dialog-show dialog)))
(defun jde-bug-watch-field-modification ()
"Request that the debugger watch for modifiction of a
field of an object or class of objects."
(interactive)
- (let ((dialog (jde-bug-watch-field-dialog "watch field dialog"
- :watch-type "modification")))
+ (let ((dialog (jde-bug-watch-field-dialog
+ "watch field dialog"
+ :watch-type "modification"
+ :object-class (concat
+ "*."
+ (car (jde-parse-get-innermost-class-at-point)))
+ :field (thing-at-point 'symbol))))
(jde-dialog-show dialog)))
@@ -2167,7 +2189,8 @@
(error "jde-bug-jpda-directory variable is not set.")
nil)
((not (file-exists-p
- (expand-file-name "lib/jpda.jar" jde-bug-jpda-directory)))
+ (expand-file-name "lib/jpda.jar" (jde-normalize-path
+ 'jde-bug-jpda-directory))))
(error "Cannot find JPDA jar file at %s"
(expand-file-name "lib/jpda.jar" jde-bug-jpda-directory))
nil)
@@ -2219,7 +2242,7 @@
(succeededp t))
(jde-dbs-proc-set-add jde-dbs-the-process-registry process)
(if (not (string= jde-bug-jre-home ""))
- (oset launch :jre-home jde-bug-jre-home))
+ (oset launch :jre-home (jde-normalize-path 'jde-bug-jre-home)))
(oset jde-dbs-the-process-registry :target-process process)
(when (not (jde-dbs-cmd-exec launch))
(jde-dbs-proc-move-to-morgue process)
@@ -2587,8 +2610,17 @@
(provide 'jde-bug)
;; $Log: jde-bug.el,v $
-;; Revision 1.2 2001/02/12 05:38:22 paulk
-;; JDE 2.2.7
+;; Revision 1.61 2001/04/23 04:55:52 paulk
+;; The watchpoint command now defaults to the field at point and to "all" as
the program suspension policy when a field is accessed or modified.
+;;
+;; Revision 1.60 2001/04/16 05:43:47 paulk
+;; Normalized paths. Thanks to Nick Sieger.
+;;
+;; Revision 1.59 2001/04/02 02:49:50 paulk
+;; Increased default debugger command timeout factor to 30 seconds.
+;;
+;; Revision 1.58 2001/03/13 03:54:00 paulk
+;; Update copyright.
;;
;; Revision 1.57 2000/12/18 05:22:45 paulk
;; *** empty log message ***
Index: xemacs-packages/jde/lisp/jde-compile.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/jde-compile.el,v
retrieving revision 1.4
diff -u -r1.4 jde-compile.el
--- xemacs-packages/jde/lisp/jde-compile.el 2001/02/20 05:29:19 1.4
+++ xemacs-packages/jde/lisp/jde-compile.el 2001/08/15 05:27:54
@@ -1,5 +1,5 @@
;;; jde-compile.el -- Integrated Development Environment for Java.
-;; $Revision: 1.4 $ $Date: 2001/02/20 05:29:19 $
+;; $Revision: 1.14 $ $Date: 2001/04/16 05:47:33 $
;; Author: Paul Kinnucan <paulk(a)mathworks.com>
;; Maintainer: Paul Kinnucan
@@ -85,7 +85,7 @@
is in the package demos\\awt, the class files would be placed in directory
C:\\users\\dac\\classes\\demos\\awt."
:group 'jde-compile-options
- :type 'file)
+ :type 'directory)
(defcustom jde-compile-option-deprecation nil
"*Warn use or override of a deprecated member or class.
@@ -273,23 +273,6 @@
:group 'jde-compile-options
:type 'boolean)
-;; Cygwin style paths will not be understood by the java tools. Call
-;; jde-convert-cygwin-path before passing path information to a
-;; java tool.
-(defun jde-build-path-arg (path-type path-list quote)
-"Build a path argument from a list of paths."
- (let ((path
- (mapconcat (lambda (x) x) path-list jde-classpath-separator)))
- ;; CFH - Call jde-convert-cygwin-path to handle cygwin paths
- (setq path (jde-convert-cygwin-path path jde-classpath-separator))
- (if quote
- (setq path (concat "\"" path "\"")))
- (setq path (concat path-type " " path))))
-
-
-(defun jde-build-classpath-arg (path-list quote)
-"Build a classpath from a list of paths."
- (jde-build-path-arg "-classpath" path-list quote))
(defun jde-get-compile-options ()
"Constructs a command-line argument string for compiler.
@@ -302,18 +285,22 @@
(if jde-compile-option-classpath
(setq options
(jde-build-classpath-arg
- jde-compile-option-classpath jde-quote-classpath))
+ jde-compile-option-classpath
+ jde-quote-classpath
+ 'jde-compile-option-classpath))
(if jde-global-classpath
(setq options
(jde-build-classpath-arg
- jde-global-classpath jde-quote-classpath))))
+ jde-global-classpath
+ jde-quote-classpath
+ 'jde-global-classpath))))
(if jde-compile-option-sourcepath
(setq options
(concat options " "
(jde-build-path-arg
"-sourcepath"
- jde-compile-option-sourcepath
+ 'jde-compile-option-sourcepath
jde-quote-classpath))))
(if jde-compile-option-bootclasspath
@@ -321,7 +308,7 @@
(concat options " "
(jde-build-path-arg
"-bootclasspath"
- jde-compile-option-bootclasspath
+ 'jde-compile-option-bootclasspath
jde-quote-classpath))))
(if jde-compile-option-extdirs
@@ -329,7 +316,7 @@
(concat options " "
(jde-build-path-arg
"-extdirs"
- jde-compile-option-extdirs
+ 'jde-compile-option-extdirs
jde-quote-classpath))))
;; Debug option.
@@ -366,7 +353,7 @@
(setq options
(concat options
" -d "
- (jde-normalize-path jde-compile-option-directory))))
+ (jde-normalize-path 'jde-compile-option-directory))))
(if jde-compile-option-deprecation
(setq options (concat options " -deprecation")))
@@ -468,8 +455,17 @@
;; Change History
;; $Log: jde-compile.el,v $
-;; Revision 1.4 2001/02/20 05:29:19 paulk
-;; JDE 2.27 updates
+;; Revision 1.14 2001/04/16 05:47:33 paulk
+;; Normalized paths. Thanks to Nick Sieger.
+;;
+;; Revision 1.13 2001/04/11 03:23:18 paulk
+;; Updated to resolve relative paths relative to the project file that defines them.
Thanks to Nick Sieger.
+;;
+;; Revision 1.12 2001/04/02 02:42:58 paulk
+;; Remove extraneous definition of jde-build-classpath-arg.
+;;
+;; Revision 1.11 2001/03/13 04:03:47 paulk
+;; Changed the type of jde-compile-option-directory from string to directory to permit
path completion.
;;
;; Revision 1.10 2001/02/20 05:15:10 paulk
;; You can now use environment variables, tilde notation, and cygwin syntax in
jde-compile-option-directory path.
Index: xemacs-packages/jde/lisp/jde-complete.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/jde-complete.el,v
retrieving revision 1.2
diff -u -r1.2 jde-complete.el
--- xemacs-packages/jde/lisp/jde-complete.el 2001/02/12 05:38:24 1.2
+++ xemacs-packages/jde/lisp/jde-complete.el 2001/08/15 05:27:55
@@ -1,5 +1,5 @@
;;; jde-complete.el -- Smart completion for the JDE
-;; $Revision: 1.2 $
+;; $Revision: 1.23 $
;; Author: Rodrigo Reyes <reyes(a)chez.com>
;; Maintainers: Rodrigo Reyes, Paul Kinnucan, Howard Spector,
@@ -336,6 +336,7 @@
(setq index (1+ index)))
(substring s index)))
+;; Can this function be reimplemented to use regular expressions?
(defun jde-complete-isolate-before-matching-of-last-car (s)
"Returns the right expression that needs completion in S."
(let* ((index (length s)) stop (paren 0) (bracket 0) curcar)
@@ -357,6 +358,7 @@
(setq stop t)))
(substring s 0 index)))
+;; Can this function be reimplemented to use regular expressions?
(defun jde-complete-java-variable-at-point ()
"Returns a list (VAR PARTIAL) where VAR.PARTIAL is the partially completed method
or field
name at point. For example, suppose obj.f1.ge were the name at point. This function would
return
@@ -373,22 +375,43 @@
second-part
(bracket-count 0)
(paren-count 0))
+
+ ;; Move cursor to the beginning of the partially
+ ;; completed part of the expression, e.g., move point
+ ;; from
+ ;;
+ ;; obj.f1.ge
+ ;; ^
+ ;; to
+ ;;
+ ;; obj.f1.ge
+ ;; ^
+ ;;
(setq curcar (char-before))
(while (null found)
(cond
- ((or (and (>= curcar ?a) (<= curcar ?z))
- (and (>= curcar ?A) (<= curcar ?Z))
+ ((or (and (>= curcar ?a) (<= curcar ?z)) ; a-z
+ (and (>= curcar ?A) (<= curcar ?Z)) ; A-z
(and (>= curcar ?0) (<= curcar ?9))
(>= curcar 127)
- (member curcar '(?_ ?\\ )))
+ (member curcar '(?_ ?\\ ))) ;; _ \
(forward-char -1))
((eq ?. curcar)
(setq found (point)))
(t
(setq found t)))
(setq curcar (char-before)))
- ;;
(setq intermediate-point (point))
+ ;; Now move point to the beginning of the expression, e.g.,
+ ;; from
+ ;;
+ ;; obj.f1.ge
+ ;; ^
+ ;; to
+ ;;
+ ;; obj.f1.ge
+ ;; ^
+ ;;
(if (not (eq t found))
(progn
(setq curcar (char-before))
@@ -495,35 +518,6 @@
(+ (marker-position jde-complete-current-beginning)
(length completion))))))
-;; (defun jde-complete-popup-xemacs-completion-menu (completion-list)
-;; (let* ((items
-;; (sort
-;; ;; Change each item in the completion list from the form
-;; ;; return-value method-name(args)
-;; ;; to the form
-;; ;; method-name(args) : return-value
-;; (mapcar
-;; (lambda (completion)
-;; (let ((completion-short (nth 0 completion))
-;; (completion-long (nth 1 completion)))
-;; (if completion-long
-;; (let ((chop-pos (string-match " " completion-long)))
-;; (concat
-;; (substring completion-long (1+ chop-pos)
-;; (length completion-long))
-;; " : "
-;; (substring completion-long 0 chop-pos)))
-;; completion-short)))
-;; completion-list)
-;; 'string<))
-;; (menu
-;; (cons
-;; "Completions"
-;; (mapcar
-;; (lambda (item)
-;; (vector item (list 'jde-complete-insert-completion item)))
-;; items))))
-;; (popup-menu-and-execute-in-window menu (selected-window))))
(defun jde-complete-find-all-completions (pat lst &optional exact-match)
(let ((result nil))
@@ -752,13 +746,31 @@
;; if only one item match, return it
(car index-alist)
;; delegates menu handling to imenu :-)
- (imenu--mouse-menu index-alist
- (if jde-xemacsp
- nil
- t) ; popup the menu at mouse position
+ (imenu--mouse-menu index-alist
+ (jde-cursor-posn-as-event) ; Popup window at text cursor
(or title "Completion"))))))
(jde-complete-insert-completion name)))
+(defun jde-cursor-posn-as-event()
+ "Returns the text cursor position as an EVENT on Emacs and the
+mouse cursor position on XEmacs."
+ (if jde-xemacsp
+ (let* ((mouse-pos (mouse-pixel-position))
+ (x (car (cdr mouse-pos)))
+ (y (cdr (cdr mouse-pos))))
+ (make-event 'button-press `(button 1 modifiers nil x ,x y ,y)))
+ (let ((x (* (if jde-xemacsp (frame-width) (frame-char-width))
+ (if (and
+ (boundp 'hscroll-mode)
+ hscroll-mode)
+ (hscroll-window-column)
+ (mod (current-column) (window-width)))))
+ (y (* (if jde-xemacsp (frame-height) (frame-char-height))
+ (- (count-lines (point-min) (point))
+ (count-lines (point-min) (window-start)))))
+ (window (get-buffer-window (current-buffer))))
+ (list (list x y) window))))
+
(defun jde-complete-at-point-menu ()
"Completes the method or field name at point.
This command displays a popup menu listing the potential completions for the name
@@ -790,8 +802,11 @@
(provide 'jde-complete)
;; $Log: jde-complete.el,v $
-;; Revision 1.2 2001/02/12 05:38:24 paulk
-;; JDE 2.2.7
+;; Revision 1.23 2001/04/02 02:45:04 paulk
+;; Add some comments.
+;;
+;; Revision 1.22 2001/03/15 19:47:07 paulk
+;; Now pops up the completion menu at the text cursor position on Emacs and at the mouse
cursor position on XEmacs. I will change this to popup at the text cursor position on
XEmacs as well as soon as I can figure out how to do it. Thanks to Matt_Conway(a)i2.com for
providing the Emacs version of this enhancement.
;;
;; Revision 1.21 2001/01/25 04:31:01 paulk
;; Completion now asks user whether to import a class that it cannot find. Thanks to
Phillip Lord.
Index: xemacs-packages/jde/lisp/jde-db.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/jde-db.el,v
retrieving revision 1.3
diff -u -r1.3 jde-db.el
--- xemacs-packages/jde/lisp/jde-db.el 2001/02/12 05:38:24 1.3
+++ xemacs-packages/jde/lisp/jde-db.el 2001/08/15 05:27:55
@@ -1,5 +1,5 @@
;;; jde-db.el -- Debugger mode for jdb.
-;; $Revision: 1.3 $ $Date: 2001/02/12 05:38:24 $
+;; $Revision: 1.76 $ $Date: 2001/04/16 05:49:34 $
;; Author: Paul Kinnucan <paulk(a)mathworks.com>
;; Maintainer: Paul Kinnucan
@@ -322,16 +322,24 @@
;; Set the classpath option. Use the local
;; classpath, if set; otherwise, the global
;; classpath.
- (setq options
- (nconc
- options
- (list
- "-classpath"
- (jde-build-classpath
- (if jde-db-option-classpath
- jde-db-option-classpath
- jde-global-classpath)))))
+ (let ((classpath
+ (if jde-db-option-classpath
+ jde-db-option-classpath
+ jde-global-classpath))
+ (symbol
+ (if jde-db-option-classpath
+ 'jde-db-option-classpath
+ 'jde-global-classpath)))
+ (if classpath
+ (setq options
+ (nconc
+ options
+ (list
+ "-classpath"
+ (jde-build-classpath
+ classpath symbol))))))
+
;; Set the verbose options.
(let ((print-classes-loaded
(nth 0 jde-db-option-verbose))
@@ -533,11 +541,27 @@
;; This is a hack to accommodate reorder of message chunks
;; on Solaris at debugger startup.
(if (string-match "running ...\n" jde-db-marker-acc)
+ (setq jde-db-marker-acc
+ (concat "running ...\n"
+ (substring jde-db-marker-acc 0 (match-beginning 0))
+ (substring jde-db-marker-acc (match-end 0)))))
+
+
+ ;; This is a hack to fix reordering of message chunks on Windows 2000
+ ;; The problem is the debugger prompt - the thread name with the stack
+ ;; depth (eg main[1]) - sometimes shows up in the middle of the output
+ ;; from the command sent to the debugger.
+ ;; This seems to show up most often with step commands.
+ ;; (message "checking string %s" jde-db-marker-acc)
+ (if (string-match "^.*: \\([-a-zA-Z0-9_$]+\\[[0-9]+\\] \\)thread="
+ jde-db-marker-acc)
(setq jde-db-marker-acc
- (concat "running ...\n"
- (substring jde-db-marker-acc 0 (match-beginning 0))
- (substring jde-db-marker-acc (match-end 0)))))
-
+ (concat (match-string 1 jde-db-marker-acc)
+ (substring jde-db-marker-acc 0 (match-beginning 1))
+ (substring jde-db-marker-acc (match-end 1)))))
+ ;; (message "fixed string is %s" jde-db-marker-acc)
+
+
(let* ((output "")
(oldjdbp (if (string= (car jde-db-debugger) "oldjdb") t))
(marker-regexp
@@ -691,7 +715,8 @@
(n 0))
(while (< n len)
(let ((curr-dir
- (substitute-in-file-name (elt jde-db-source-directories n))))
+ (jde-normalize-path (elt jde-db-source-directories n)
+ 'jde-db-source-directories)))
(cond
((jde-db-contains-file-p curr-dir file)
(throw 'found curr-dir))
@@ -745,29 +770,34 @@
"See jde-db-source-directories.") f)
(if jde-xemacsp (window-buffer) nil))))
-(defun jde-find-class-source (class)
+(defun jde-find-class-source-file (class)
"*Find the source file for a specified class.
CLASS is the fully qualified name of the class. This
function searchs the source file paths specified by
`jde-db-source-directories' for the source file
corresponding to CLASS. If it finds the source file,
-it opens the file in a buffer."
- (interactive "sClass: ")
+it returns the file's path. Otherwise, it returns nil."
(string-match "^\\(\\(\\(\\w\\|[_]\\)*[.]\\)*\\)\\(\\(\\w\\|[_]\\)+$\\)"
class)
(let* ((package-name
(substring class (match-beginning 1) (match-end 1)))
(class-name
(substring class (match-beginning 4) (match-end 4)))
(file-name (concat class-name ".java"))
- (source-dir
- (jde-db-search-src-dirs
- file-name
- package-name)))
- (if source-dir
- (find-file (concat source-dir file-name))
- (message (concat "JDE error: Could not find source for %s. "
- "See `jde-db-source-directories' for more information." )
- class))))
+ (source-dir (jde-db-search-src-dirs file-name package-name)))
+ (if source-dir
+ (expand-file-name file-name source-dir)
+ (message "JDE error: Could not find source for %s. See
`jde-db-source-directories' for more information." class)
+ nil)))
+
+(defun jde-find-class-source (class)
+ "*Find the source file for a specified class.
+Calls `jde-find-class-source-file' to do the search.
+If it finds the source file, it opens the file in a buffer."
+ (interactive "sClass: ")
+ (let ((source (jde-find-class-source-file class)))
+ (when source
+ (find-file source))))
+
(defvar jde-db-minibuffer-local-map nil
"Keymap for minibuffer prompting of jdb startup command.")
@@ -901,7 +931,7 @@
(source-directory default-directory)
(working-directory (if (string= jde-run-working-directory "")
default-directory
- jde-run-working-directory)))
+ (jde-normalize-path 'jde-run-working-directory))))
(if (not (comint-check-proc debug-buf-name))
(let* ((debug-buffer (get-buffer-create debug-buf-name))
(debugger (car jde-db-debugger))
@@ -967,7 +997,7 @@
buffer."
(save-excursion
(goto-char (point-min))
- (if (re-search-forward "^[ \t]*\\<\\(package\\) *\\([^ \t\n]*\\) *;"
(point-max) t)
+ (if (re-search-forward "^[ \t]*\\<\\(package\\) +\\([^ \t\n]*\\) *;"
(point-max) t)
(concat (buffer-substring-no-properties (match-beginning 2) (match-end 2))
"."))))
@@ -1162,8 +1192,26 @@
;; Change History
;; $Log: jde-db.el,v $
-;; Revision 1.3 2001/02/12 05:38:24 paulk
-;; JDE 2.2.7
+;; Revision 1.76 2001/04/16 05:49:34 paulk
+;; Normalized paths. Thanks to Nick Sieger.
+;;
+;; Revision 1.75 2001/04/12 04:42:23 paulk
+;; Normalize jde-run-working-directory.
+;;
+;; Revision 1.74 2001/04/11 03:21:33 paulk
+;; Updated to resolve relative paths relative to the project file that defines them.
Thanks to Nick Sieger.
+;;
+;; Revision 1.73 2001/04/08 04:14:29 paulk
+;; jdb interface has been fixed to work around JDK 1.3 bug that causes the jdb command
prompt to sometimes appear in the wrong place in jdb output. Thanks to Andy Bennett
<andrew.bennett(a)ericsson.com> for this fix.
+;;
+;; Revision 1.72 2001/03/16 04:07:03 paulk
+;; Fixed regular expression for finding package in source buffer so that there must be a
space between package and the package name. This is to prevent false hits. Thanks to Rory
Molinari <molinari(a)math.lsa.umich.edu>.
+;;
+;; Revision 1.71 2001/03/13 04:14:54 paulk
+;; Split jde-find-class-source into to files, one of which returns the path of the source
file while the other opens the file in a buffer.
+;;
+;; Revision 1.70 2001/02/26 04:17:50 paulk
+;; jde-db now handles case where jde-global-classpath and jde-db-option-classpath are
nil.
;;
;; Revision 1.69 2001/02/03 08:44:56 paulk
;; Changed declaration of customized variables to allow path completion.
Index: xemacs-packages/jde/lisp/jde-dbo.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/jde-dbo.el,v
retrieving revision 1.2
diff -u -r1.2 jde-dbo.el
--- xemacs-packages/jde/lisp/jde-dbo.el 2001/02/12 05:38:24 1.2
+++ xemacs-packages/jde/lisp/jde-dbo.el 2001/08/15 05:27:56
@@ -1,11 +1,11 @@
;;; jde-dbo.el -- JDEbug output functions
-;; $Revision: 1.2 $ $Date: 2001/02/12 05:38:24 $
+;; $Revision: 1.28 $ $Date: 2001/04/23 03:58:15 $
;; Author: Paul Kinnucan <paulk(a)mathworks.com>
;; Maintainer: Paul Kinnucan
;; Keywords: java, tools
-;; Copyright (C) 1997, 1998, 1999 Paul Kinnucan.
+;; Copyright (C) 1997, 1998, 1999, 2001 Paul Kinnucan.
;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
@@ -37,6 +37,8 @@
;;; Code:
(require 'eieio)
+(require 'tree-widget)
+(require 'jde-widgets)
(defclass jde-dbo-thread ()
((id :initarg :id)
@@ -132,8 +134,8 @@
(defun jde-dbo-command-result-data (result)
(nth 2 result))
-(defun jde-dbo-report-ids-in-use (id)
-)
+(defun jde-dbo-report-ids-in-use (id-count)
+ (message "%d object ids in use." id-count))
(defun jde-dbo-init-debug-session ()
(oset jde-dbs-the-debugger started-p t))
@@ -246,20 +248,20 @@
:process process
:object-id (oref var-value id)))
(str-val (jde-dbs-cmd-exec cmd)))
- (widget-create 'jde-widget-tree :tag var-tag :value t
- (list 'jde-widget-tree :tag str-val)))
+ (widget-create 'tree-widget :tag var-tag :value t
+ (list 'tree-widget :tag str-val)))
(widget-create 'jde-widget-java-obj :tag var-tag
:process process :object-id (oref var-value :id))))
((typep var-value 'jde-dbs-java-array)
(widget-create 'jde-widget-java-array :tag var-tag
:process process :object var-value))
((typep var-value 'jde-dbs-java-primitive)
- (widget-create 'jde-widget-tree :tag var-tag :value t
- (list 'jde-widget-tree
+ (widget-create 'tree-widget :tag var-tag :value t
+ (list 'tree-widget
:tag (format "%s" (oref var-value value)))))
((typep var-value 'jde-dbs-java-null)
- (widget-create 'jde-widget-tree :tag var-tag :value t
- (list 'jde-widget-tree :tag "null")))
+ (widget-create 'tree-widget :tag var-tag :value t
+ (list 'tree-widget :tag "null")))
(t
(error "Unidentified type of local variable: %s" var-tag)))))
(use-local-map widget-keymap)
@@ -450,44 +452,66 @@
method-sig))))
(defun jde-dbo-watchpoint-hit-event (process-id process-status thread-spec request-id
&rest data)
- (let* ((thread (jde-dbo-make-thread-obj thread-spec))
+ (let ((process (jde-dbs-get-process process-id)))
+ (if process
+ (let* ((thread (jde-dbo-make-thread-obj thread-spec))
+ (thread-id (oref thread id))
+ (thread-name (oref thread name))
+ (thread-state (oref thread state))
+ (thread-status (oref thread status))
- ;; Object whose field was accessed or modified.
- (obj-spec (nth 0 data))
- (obj-class (nth 0 obj-spec))
- (obj-id (nth 1 obj-spec))
- (obj-gc-flag (nth 2 obj-spec))
- ;; Field that was accessed or modified.
- (field-spec (nth 1 data))
- (field-decl (nth 0 field-spec))
- (field-name (nth 0 field-decl))
- (field-type (nth 1 field-decl))
- (field-qual (if (> (length field-decl) 3) (nth 2 field-decl)))
- (field-value-type (nth 1 field-spec))
- (field-value (nth 2 field-spec))
- ;; Breakpoint data
- (breakpoint-spec (nth 2 data))
- (breakpoint-class (nth 0 breakpoint-spec))
- (breakpoint-file (nth 1 breakpoint-spec))
- (breakpoint-line (nth 2 breakpoint-spec))
- ;; Object match data
- (obj-match (nth 3 data))
- ;; Thread match data
- (thread-match (nth 4 data))
- ;; Expression true data
- (expression-true (nth 5 data))
- (process (jde-dbs-get-process process-id))
- )
-
- (if (string= (oref thread status) "suspended by debugger")
- (jde-dbo-show-line breakpoint-class breakpoint-file breakpoint-line))
-
- (jde-dbs-proc-display-debug-message
- process
- (format "<%s:%s> accessed or modified at line %s in %s.\n Watched field:
%s %s %s = %s\n"
- obj-class obj-id breakpoint-line breakpoint-file
- (if field-qual field-qual "") field-type field-name field-value))
- ))
+ ;; Object whose field was accessed or modified.
+ (obj-spec (nth 0 data))
+ (obj-class (nth 0 obj-spec))
+ (obj-id (nth 1 obj-spec))
+ (obj-gc-flag (nth 2 obj-spec))
+ ;; Field that was accessed or modified.
+ (field-spec (nth 1 data))
+ (field-decl (nth 0 field-spec))
+ (field-name (nth 0 field-decl))
+ (field-type (nth 1 field-decl))
+ (field-qual (if (> (length field-decl) 3) (nth 2 field-decl)))
+ (field-value-type (nth 1 field-spec))
+ (field-value (nth 2 field-spec))
+ ;; Breakpoint data
+ (breakpoint-spec (nth 2 data))
+ (breakpoint-class (nth 0 breakpoint-spec))
+ (breakpoint-file (nth 1 breakpoint-spec))
+ (breakpoint-line (nth 2 breakpoint-spec))
+ ;; Object match data
+ (obj-match (nth 3 data))
+ ;; Thread match data
+ (thread-match (nth 4 data))
+ ;; Expression true data
+ (expression-true (nth 5 data)))
+
+ (jde-dbs-proc-display-debug-message
+ process
+ (format "<%s:%s> accessed or modified at line %s in %s.\n Watched field:
%s %s %s = %s\n"
+ obj-class obj-id breakpoint-line breakpoint-file
+ (if field-qual field-qual "") field-type field-name field-value))
+
+ (if (string= thread-status "suspended by debugger")
+ (let ((state-info (oref process state-info)))
+ (if state-info
+ (progn
+ (jde-dbs-proc-state-info-set
+ state-info thread-state
+ thread-status thread-id thread-name)
+ (jde-dbo-update-locals-buf process thread-id 0)
+ (jde-dbo-update-stack process thread-id)
+ (oset process steppablep t)
+ (jde-dbo-show-line breakpoint-class breakpoint-file breakpoint-line)
+ (when jde-bug-raise-frame-p (raise-frame))
+
+ (jde-dbs-display-debug-message
+ process-id
+ (format "Stopping at line %d in %s (%s) on thread %s."
+ breakpoint-line breakpoint-class breakpoint-file thread-name)))
+ (message "Watchpoint event error: state info object missing for process
%d."
+ process-id)))))
+ (message "Watchpoint event error: process object for process %d is
missing." process-id))))
+
(defun jde-dbo-event-set (process-id process-status thread &rest events)
"Invoked when a set of debugger events occurs. EVENTS is a list of
Index: xemacs-packages/jde/lisp/jde-dbs.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/jde-dbs.el,v
retrieving revision 1.4
diff -u -r1.4 jde-dbs.el
--- xemacs-packages/jde/lisp/jde-dbs.el 2001/02/12 05:38:24 1.4
+++ xemacs-packages/jde/lisp/jde-dbs.el 2001/08/15 05:27:57
@@ -1,5 +1,5 @@
;;; jde-dbs.el -- JDEbug Session Interface Functions
-;; $Revision: 1.4 $ $Date: 2001/02/12 05:38:24 $
+;; $Revision: 1.70 $ $Date: 2001/05/23 03:35:56 $
;; Author: Paul Kinnucan <paulk(a)mathworks.com>
;; Maintainer: Paul Kinnucan
@@ -39,6 +39,7 @@
(require 'jde-dbo)
(require 'eieio)
(require 'jde-widgets)
+(require 'tree-widget)
;; Need jde-run only to get the definition for
;; save-w32-show-window macro.
@@ -86,10 +87,11 @@
:type list
:initform nil
:documentation
- "List of active processes"))
- "Class of process sets.")
+ "List of active debugee processes"))
+ "Class of debuggee process sets.")
(defmethod jde-dbs-proc-set-add ((this jde-dbs-proc-set) process)
+ "Adds a process to this debuggee process set."
(oset this :proc-alist
(cons
(cons (oref process :id) process)
@@ -162,7 +164,7 @@
target-process))
-(defvar jde-dbs-the-process-registry
+(defvar jde-dbs-the-process-registry
(jde-dbs-proc-registry "Process Registry")
"The debuggee process registry.")
@@ -198,7 +200,8 @@
(oset this proc-alist nil))
-(defvar jde-dbs-the-process-morgue (jde-dbs-proc-morgue "The JDE Process
Morgue")
+(defvar jde-dbs-the-process-morgue
+ (jde-dbs-proc-morgue "Process Morgue")
"The JDE process morgue. This morgue contains processes that are dead or
dying, for example, because they have been terminated by the user or the
debugger. Their corpses must be kept around until it is clear they are dead and
@@ -551,27 +554,18 @@
(defmethod jde-dbs-proc-get-state-reason ((this jde-dbs-proc))
(oref (oref this state-info) reason))
-; (defmethod jde-dbs-proc-display-debug-message ((this jde-dbs-proc) message)
-; (let ((buffer
-; (oref this msg-buf)))
-; (if buffer
-; (save-excursion
-; (set-buffer buffer)
-; (goto-char (point-max))
-; (insert (concat message "\n"))))))
-
(defmethod jde-dbs-proc-display-debug-message ((this jde-dbs-proc) message)
(let ((buffer
- (oref this msg-buf)))
+ (oref this msg-buf)))
(if buffer
- (save-excursion
- (let ((currbuffp (equal buffer (current-buffer))))
- (if (not currbuffp) (other-window -1))
- (set-buffer buffer)
- (goto-char (point-max))
- (insert (concat message "\n"))
- (goto-char (point-max))
- (if (not currbuffp) (other-window 1)))))))
+ (save-excursion
+ (let ((currbuffp (equal buffer (current-buffer))))
+ (if (not currbuffp) (other-window -1))
+ (set-buffer buffer)
+ (goto-char (point-max))
+ (insert (concat message "\n"))
+ (goto-char (point-max))
+ (if (not currbuffp) (other-window 1)))))))
(defmethod jde-dbs-proc-move-to-morgue ((this jde-dbs-proc))
@@ -848,7 +842,7 @@
(if (and
jde-run-working-directory
(not (string= jde-run-working-directory "")))
- jde-run-working-directory
+ (jde-normalize-path 'jde-run-working-directory)
source-directory))
(vm (jde-dbs-choose-vm))
(jde-java-directory
@@ -862,28 +856,18 @@
args
(list
"-classpath"
- (jde-convert-cygwin-path
- (if jde-bug-vm-includes-jpda-p
- (format
- (if jde-bug-debug
- "%sclasses%s%s"
- "%slib/jde.jar%s%s")
- jde-java-directory
- jde-classpath-separator
- (expand-file-name
- "lib/tools.jar" jde-bug-jdk-directory))
- (format
- (if jde-bug-debug
- "%sclasses%s%s"
- "%ssrc%s%slib/jde.jar%s%s" )
- jde-java-directory
- jde-classpath-separator
- jde-java-directory
- jde-classpath-separator
- (expand-file-name
- "lib/jpda.jar" jde-bug-jpda-directory)))
- ;; jde-classpath-separator
- ))))
+ (jde-build-classpath
+ (list
+ (expand-file-name
+ (if jde-bug-debug "classes" "lib/jde.jar")
+ jde-java-directory)
+ (if jde-bug-vm-includes-jpda-p
+ (expand-file-name
+ "lib/tools.jar"
+ (jde-normalize-path 'jde-bug-jdk-directory))
+ (expand-file-name
+ "lib/jpda.jar" (jde-normalize-path
+ 'jde-bug-jpda-directory))))))))
(if jde-bug-debug
(setq args
(append args
@@ -929,12 +913,27 @@
(bury-buffer debugger-buffer)
+ (setq jde-dbs-proc-counter 0)
+
+ (setq jde-dbs-cmd-counter 0)
+
;; Wait for response from debugger
(if (not (accept-process-output debugger-process jde-bug-debugger-command-timeout 0))
(progn
(message "Error: debugger failed to start.")
nil)
- (oref this started-p)))
+ (oref this started-p))
+
+ ;; Create a process registry for registering debuggee processes
+ ;; started by the debugger.
+ (setq jde-dbs-the-process-registry
+ (jde-dbs-proc-registry "Process Registry"))
+
+ ;; Create a registry for debuggee processes that have died but
+ ;; still may be getting messages from the debugger.
+ (setq jde-dbs-the-process-morgue
+ (jde-dbs-proc-morgue "Process Morgue")))
+
(message "An instance of the debugger is running.")
(pop-to-buffer (jde-dbs-get-app-buffer-name))
nil))
@@ -966,17 +965,21 @@
"Process that this command targets.")
(id :initarg :id
:type integer
+ :documentation
"Command id.")
(name :initarg :name
:type string
:documentation
"Name of command.")
(result :initarg :result
+ :documentation
"Result of executing command.")
(data :initarg :data
+ :documentation
"Data returned by command.")
(msg :initarg :msg
:type string
+ :documentation
"Message to display to user in debug buffer.")
)
"Super class of debugger commands.")
@@ -1072,7 +1075,9 @@
((equal (aref debugger-output curr-pos) ?\")
(if in-string-p
(if in-escape-p
- (setq in-escape-p nil)
+ (progn
+ (setq in-escape-p nil)
+ (setq in-string-p nil))
(setq in-string-p nil))
(setq in-string-p t)))
@@ -1080,17 +1085,21 @@
((and
(not in-string-p)
(equal (aref debugger-output curr-pos) ?\)))
- (if (= level 0)
- (throw 'found-lisp-form curr-pos)
- (setq level (1- level))
- (if (< level 0)
- (error "Error parsing debugger output."))))
+ (if (= level 0)
+ (throw 'found-lisp-form curr-pos)
+ (setq level (1- level))
+ (if (< level 0)
+ (error "Error parsing debugger output.")))
+ ;; (prin1 (format ") lev = %d pos = %d" level curr-pos) (current-buffer))
+ )
;; Current character = left paren
((and
(not in-string-p)
(equal (aref debugger-output curr-pos) ?\()
- (setq level (1+ level))))
+ (setq level (1+ level)))
+ ;; (prin1 (format "( lev = %d pos = %d" level curr-pos) (current-buffer))
+ )
(t
(if in-escape-p
(setq in-escape-p nil))))
@@ -1177,7 +1186,7 @@
(setq jde-dbs-command-reply nil)))))
(defun jde-dbs-asynch-output-listener (process output)
- "Listens at the jdebug socket for asynchronous debugger output."
+ "Listens for asynchronous debugger output."
(let* ((combined-output (concat jde-dbs-debugger-output output))
(parsed-output
(if (string-match "^[\n\t ]*(" combined-output)
@@ -2437,17 +2446,17 @@
(oset this name "get_threads"))
(defun jde-dbs-map-thread-to-tree (thread)
- (list (quote jde-widget-tree) :tag (concat (nth 2 thread) " thread")
+ (list (quote tree-widget) :tag (concat (nth 2 thread) " thread")
:value nil
- (list (quote jde-widget-tree) :tag (concat "id: " (number-to-string (nth 1
thread))))
- (list (quote jde-widget-tree) :tag (concat "status: " (nth 3 thread)))
- (list (quote jde-widget-tree) :tag (concat "state: " (nth 4 thread)))
+ (list (quote tree-widget) :tag (concat "id: " (number-to-string (nth 1
thread))))
+ (list (quote tree-widget) :tag (concat "status: " (nth 3 thread)))
+ (list (quote tree-widget) :tag (concat "state: " (nth 4 thread)))
(jde-dbs-map-stack-to-tree (nth 5 thread))))
(defun jde-dbs-map-threadgroup-to-tree (threadgroup)
(nconc
- (list (quote jde-widget-tree) :tag (concat (nth 2 threadgroup) " thread
group")
+ (list (quote tree-widget) :tag (concat (nth 2 threadgroup) " thread
group")
:value nil)
(mapcar
(lambda (x)
@@ -2460,18 +2469,18 @@
(defun jde-dbs-map-stack-to-tree (stack)
(nconc
- (list (quote jde-widget-tree) :tag "Stack")
+ (list (quote tree-widget) :tag "Stack")
(if (listp stack)
(mapcar
(lambda (x)
- (list (quote jde-widget-tree) :tag
+ (list (quote tree-widget) :tag
(format "%s.%s(%s:%s)" (nth 1 x) (nth 4 x) (nth 2 x)
(nth 3 x))))
stack))))
(defun jde-dbs-map-threads-to-tree (threads)
(nconc
- (list (quote jde-widget-tree) :tag "Threads")
+ (list (quote tree-widget) :tag "Threads")
(mapcar
(lambda (x)
(if (string= (nth 0 x) "Thread")
@@ -2492,6 +2501,7 @@
(set-window-buffer
(next-window (frame-first-window)) buf)
(set-buffer buf)
+ (kill-all-local-variables)
(let ((inhibit-read-only t))
(erase-buffer))
(if (not jde-xemacsp)
@@ -3265,8 +3275,30 @@
(provide 'jde-dbs)
; $Log: jde-dbs.el,v $
-; Revision 1.4 2001/02/12 05:38:24 paulk
-; JDE 2.2.7
+; Revision 1.70 2001/05/23 03:35:56 paulk
+; Supplied missing :documentation keywords in jde-dbs-cmd. Thanks to David Ponce.
+;
+; Revision 1.69 2001/05/19 02:30:25 paulk
+; JDEbug now reinitializes various variables whenever you start a debug session.
+; Previously restarting JDEbug after certain errors, for example, failure to launch
+; a process, would require restarting Emacs.
+;
+; Revision 1.68 2001/04/19 04:34:53 paulk
+; -- Converted local variables and thread buffers to use David Ponce's tree-widget.
+;
+; -- Fixed backslash bug in jde-dbs-extract-lisp-form.
+;
+; Revision 1.67 2001/04/16 05:51:29 paulk
+; Normalized paths. Thanks to Nick Sieger.
+;
+; Revision 1.66 2001/04/12 04:40:15 paulk
+; Normalize jde-run-working-directory.
+;
+; Revision 1.65 2001/04/02 02:47:19 paulk
+; Removed commented out function.
+;
+; Revision 1.64 2001/03/28 12:45:33 paulk
+; Fixed jde-dbs-debugger-start to use new centralized jde-build-classpath function.
;
; Revision 1.63 2001/01/23 07:37:43 paulk
; Removed typo from jde-dbs-proc-set-find.
Index: xemacs-packages/jde/lisp/jde-gen.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/jde-gen.el,v
retrieving revision 1.3
diff -u -r1.3 jde-gen.el
--- xemacs-packages/jde/lisp/jde-gen.el 2001/02/25 04:46:48 1.3
+++ xemacs-packages/jde/lisp/jde-gen.el 2001/08/15 05:27:58
@@ -1,5 +1,5 @@
;;; jde-gen.el -- Integrated Development Environment for Java.
-;; $Revision: 1.3 $
+;; $Revision: 1.33 $
;; Author: Paul Kinnucan <paulk(a)mathworks.com>
;; Maintainer: Paul Kinnucan
@@ -98,21 +98,22 @@
(setq i (1+ i)))
bp)))
-(defun jde-gen-get-super-class ()
- (let ((super-class (read-from-minibuffer "extends: "))
- (interface (read-from-minibuffer "implements: ")))
- (cond
- ((and
- (not (string= super-class ""))
- (not (string= interface "")))
- (concat "extends " super-class "\n"
- " implements " interface))
- ((not (string= super-class ""))
- (concat "extends " super-class))
- ((not (string= interface ""))
- (concat "implements " interface)))))
+(defun jde-gen-get-extend-class ()
+ (let ((super-class (read-from-minibuffer "extends: ")))
+ (if (not (string= super-class ""))
+ (concat "extends " super-class " "))))
+
+(defun jde-gen-get-interface-implementation ()
+ (let ((interface (read-from-minibuffer "implements: ")))
+ (if (not (string= interface ""))
+ (let ((skeleton
+ (jde-wiz-implement-interface-internal interface)))
+ (if (string=
+ skeleton
+ "Error evaluating Java expresson. See *Messages* buffer.")
+ ""
+ skeleton)))))
-
(defun jde-gen-get-package-statement ()
(let* ((package-dir (jde-package-get-package-directory))
(suggested-package-name
@@ -142,13 +143,13 @@
"\" *\" '>'n"
"\" * Created: \" (current-time-string) '>'n"
"\" *\" '>'n"
- "\" * @author <a href=\\\"mailto: \\\"\" (user-full-name)
\"</a>\"'>'n"
+ "\" * @author <a href=\\\"mailto:\" (eval user-mail-address)
\"\\\">\" (user-full-name)
\"</a>\"'>'n"
"\" * @version\" '>'n"
"\" */\" '>'n'"
"'>'n"
"\"public class \""
"(file-name-sans-extension (file-name-nondirectory buffer-file-name))"
- "\" \" (jde-gen-get-super-class)"
+ "\" \" (jde-gen-get-extend-class)"
"(if jde-gen-k&r "
"()"
@@ -167,6 +168,8 @@
"'>'p'n"
"\"}\">"
"'>'n"
+ "(jde-gen-get-interface-implementation)"
+ "'>'n"
"\"}\">"
"\"// \""
"(file-name-sans-extension (file-name-nondirectory buffer-file-name))"
@@ -211,7 +214,7 @@
"\" *\" '>'n"
"\" * Created: \" (current-time-string) '>'n"
"\" *\" '>'n"
- "\" * @author <a href=\\\"mailto: \\\"\" (user-full-name)
\"</a>\"'>'n"
+ "\" * @author <a href=\\\"mailto:\" (eval user-mail-address)
\"\\\">\" (user-full-name)
\"</a>\"'>'n"
"\" * @version\" '>'n"
"\" */\" '>'n"
"'>'n"
@@ -300,7 +303,7 @@
"\" *\" '>'n"
"\" * Created: \" (current-time-string) '>'n"
"\" *\" '>'n"
- "\" * @author <a href=\\\"mailto: \\\"\" (user-full-name)
\"</a>\"'>'n"
+ "\" * @author <a href=\\\"mailto:\" (eval user-mail-address)
\"\\\">\" (user-full-name)
\"</a>\"'>'n"
"\" * @version\" '>'n"
"\" */\" '>'n"
"'>'n"
@@ -580,10 +583,7 @@
(defcustom jde-gen-inner-class-template
'(
"(end-of-line) '& \"class \" (P \"Class name: \"
class)"
- "(P \"Superclass: \" super t)"
- "(let ((parent (jde-gen-lookup-named 'super)))"
- "(if (not (string= parent \"\"))"
- "(concat \" extends \" parent ))) "
+ "\" \" (jde-gen-get-extend-class)"
;;we open the bracket according to k&r style or not
"(if jde-gen-k&r "
@@ -600,13 +600,18 @@
"\"{\"'>'n"
"\"}\"'>'n"
+
+ "'>'n"
+ "(jde-gen-get-interface-implementation)"
+ "'>'n"
+
"\"}\" '>'n'>"
)
"*Template that creates an empty private class at point."
:group 'jde-gen
:type '(repeat string)
:set '(lambda (sym val)
- (defalias 'jde-gen-inner-class
+ (defalias 'jde-gen-inner-class-internal
(tempo-define-template
"java-inner-class"
(jde-gen-read-template val)
@@ -614,6 +619,12 @@
"Insert inner class."))
(set-default sym val)))
+(defun jde-gen-inner-class ()
+ (interactive)
+ (jde-gen-inner-class-internal)
+ (goto-char (scan-lists (point) -1 0))
+ (c-indent-exp))
+
(defcustom jde-gen-action-listener-template
'(
"'& (P \"Component name: \")"
@@ -1613,8 +1624,13 @@
(provide 'jde-gen)
;; $Log: jde-gen.el,v $
-;; Revision 1.3 2001/02/25 04:46:48 paulk
-;; Class buffer templates now prompt for package.
+;; Revision 1.33 2001/05/21 06:48:16 paulk
+;; The class buffer template now generates skeletal implementations of interfaces that
the class implements. Thanks to Javier Lopez for this enhancement.
+;;
+;; The inner class template now generates skeletal implementations of interfaces
implemented by the class.
+;;
+;; Revision 1.32 2001/03/16 03:57:37 paulk
+;; Fixed author line in javadoc comments. Thanks to Karel.Sprenger(a)compaq.com.
;;
;; Revision 1.31 2001/02/22 05:05:29 paulk
;; The class, console app, and Swing app templates now prompt you to enter a package
name. The prompt includes a suggested package name based on the location of the current
directory in the classpath.
Index: xemacs-packages/jde/lisp/jde-help.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/jde-help.el,v
retrieving revision 1.2
diff -u -r1.2 jde-help.el
--- xemacs-packages/jde/lisp/jde-help.el 2001/02/12 05:38:25 1.2
+++ xemacs-packages/jde/lisp/jde-help.el 2001/08/15 05:27:58
@@ -1,5 +1,5 @@
;;; jde-help.el
-;; $Revision: 1.2 $
+;; $Revision: 1.22 $
;; Author: Paul Kinnucan <paulk(a)mathworks.com>, Phillip Lord
<plord(a)hgmp.mrc.ac.uk>
;; Maintainer: Paul Kinnucan
@@ -26,6 +26,9 @@
(require 'jde-widgets)
(require 'eieio)
+(if (locate-library "url")
+ (autoload 'url-file-exists "url" nil nil nil))
+
(defcustom jde-help-docsets nil
"*Lists collections of HTML files documenting Java classes.
This list is used by the `jde-help-class' command to find help for
@@ -47,6 +50,15 @@
Docset directory
Directory containing the collection, e.g., d:/jdk1.2/docs/api.
+ The docset directory may be located on a remote system in which
+ case this field should specify the URL of the docset directory,
+ e.g.,
http://www.javasoft.com/j2se/1.3/docs/api. The GNU utility, wget,
+ or the w3 function `url-file-exists' must be installed on your
+ system to find javadoc pages located on
+ remote systems. Native Windows and cygwin ports of wget
+ are readily available on the Internet. Make sure that wget is
+ in Emacs `exec-path' before attempting to access documentation
+ on remote systems.
Doc lookup function
@@ -71,60 +83,72 @@
(nth 0 docset))
(defun jde-help-docset-get-dir (docset)
- (nth 1 docset))
+ (let ((path (nth 1 docset)))
+ (if (string-match "http:" path)
+ path
+ (jde-normalize-path (nth 1 docset) 'jde-help-docsets))))
(defun jde-help-docset-get-lookup-function (docset)
(nth 2 docset))
-
-(defun jde-help-lookup-java1-javadoc (class docset-dir)
- (let ((doc-path
- (concat
- (expand-file-name class docset-dir)
- ".html")))
- (if (file-exists-p doc-path)
- doc-path)))
-
-(defun jde-help-lookup-java2-javadoc (class docset-dir)
- (let ((doc-path
- (concat
- (expand-file-name
- (substitute ?/ ?. class)
- docset-dir)
- ".html")))
- (if (file-exists-p doc-path)
- doc-path)))
+(defun jde-help-find-javadoc (class docset-dir)
+ "Searches DOCSET-DIR for the javadoc HTML page
+for CLASS and, if found, returns the URL of the
+javadoc page for CLASS. This function uses
+wget to verify the existense of pages located
+on remote systems."
+ (let ((class-path
+ (concat (substitute ?/ ?. class) ".html"))
+ url)
+ (cond
+ ((string-match "http:" docset-dir)
+ (setq url (concat docset-dir "/" class-path))
+ (if (fboundp 'url-file-exists)
+ (if (not
+ (url-file-exists url))
+ (setq url nil))
+ (if (executable-find
+ (if (eq system-type 'windows-nt) "wget.exe" "wget"))
+ (if (not
+ (string-match
+ "200"
+ (shell-command-to-string
+ (concat "wget --spider " url))))
+ (setq url nil))
+ (error
+ (concat "Cannot find wget. This utility is needed "
+ "to access javadoc on remote systems.")))))
+ (t
+ (let ((doc-path
+ (expand-file-name class-path docset-dir)))
+ (if (file-exists-p doc-path)
+ (setq url (format "file://%s" doc-path))))))
+ url))
(defun jde-help-get-doc (class)
-"Gets path to the HTML file for CLASS where CLASS is a
+"Gets URL to the HTML file for CLASS where CLASS is a
qualified class name."
(if class
- (cond
- ((not jde-help-docsets)
- (error "%s" "Help error: No docsets available. See
jde-help-docsets."))
- (t
+ (if jde-help-docsets
(let ((paths
(mapcar
(lambda (docset)
(cond
((string= (jde-help-docset-get-type docset) "javadoc")
- (or
- (jde-help-lookup-java1-javadoc
- class
- (jde-help-docset-get-dir docset))
- (jde-help-lookup-java2-javadoc
+ (jde-help-find-javadoc
class
- (jde-help-docset-get-dir docset))))
+ (jde-help-docset-get-dir docset)))
(t
(apply
(jde-help-docset-get-lookup-function docset)
class
- (jde-help-docset-get-dir docset)))))
+ (list (jde-help-docset-get-dir docset))))))
jde-help-docsets)))
(setq paths (delq nil paths))
;; Return first file found.
- (if paths (car paths) paths))))))
+ (if paths (car paths) paths))
+ (error "%s" "Help error: No docsets available. See
jde-help-docsets."))))
(defun jde-help-symbol ()
@@ -171,9 +195,14 @@
(defun jde-help-show-document (doc-file)
- "Actually displays the document."
- (if (not (eq doc-file nil))
- (browse-url (format "file://%s" doc-file))))
+ "Displays DOC-FILE in the default browser."
+ (if doc-file
+ (let ((file
+ (if (or (string-match "http:" doc-file)
+ (string-match "file:" doc-file))
+ doc-file
+ (format "file://%s" doc-file))))
+ (browse-url file))))
(defun jde-help-choose-document(doc-files)
"Allows the user to select which of the possible documentation files they wish to
view."
@@ -315,8 +344,26 @@
(provide 'jde-help)
;; $Log: jde-help.el,v $
-;; Revision 1.2 2001/02/12 05:38:25 paulk
-;; JDE 2.2.7
+;; Revision 1.22 2001/04/19 04:39:41 paulk
+;; Fixed regression error caused by normalizing paths. Now checks to ensure that path is
local before trying to normalize it.
+;;
+;; Revision 1.21 2001/04/16 05:53:51 paulk
+;; Normalized paths.
+;;
+;; Revision 1.20 2001/04/08 04:11:40 paulk
+;; jde-help-find-javadoc now uses url-file-exists (from the w3 package) if it is in your
load-path. Otherwise, it uses wget. Thanks to Knut Wannheden <wannhedenk(a)post.ch>
and klaus.berndl(a)sdm.de for this fix.
+;;
+;; Revision 1.19 2001/03/29 02:46:52 paulk
+;; Replaced jde-find-exec with executable-find, which is defined by executable.el
available with both the Emacs and XEmacs distributions.
+;;
+;; Revision 1.18 2001/03/27 17:49:33 paulk
+;; Eliminate dependency on which package by including the function jde-find-exec and
replacing references to the which command with jde-find-exec. Thanks to
klaus.berndl(a)sdm.de for suggesting this change and providing the implementation of
jde-find-exec.
+;;
+;; Revision 1.17 2001/03/27 16:44:50 paulk
+;; Updated to require which package. Removed extraneous definition of
jde-help-find-javadoc. Thanks to klaus.berndl(a)sdm.de and Brad Giaccio
<bgiaccio(a)psrw.com> for reporting these problems.
+;;
+;; Revision 1.16 2001/03/12 05:30:15 paulk
+;; Can now access javadoc anywhere on the Web. Thanks to Adrian Robert
<arobert(a)polexis.com> for providing the initial version of this enhancement.
;;
;; Revision 1.15 2001/02/04 01:31:13 paulk
;; Changed declaration of customized variables to permit completion of paths.
Index: xemacs-packages/jde/lisp/jde-imenu.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/jde-imenu.el,v
retrieving revision 1.1
diff -u -r1.1 jde-imenu.el
--- xemacs-packages/jde/lisp/jde-imenu.el 2001/02/12 05:40:58 1.1
+++ xemacs-packages/jde/lisp/jde-imenu.el 2001/08/15 05:27:58
@@ -1,12 +1,12 @@
;;; jde-imenu.el --- imenu setup for the JDE
-;; $Revision: 1.1 $
+;; $Revision: 1.4 $
;; Author: Paul Kinnucan <paulk(a)mathworks.com>,
;; David Ponce <david(a)dponce.com>
;; Maintainer: Paul Kinnucan, David Ponce
;; Keywords: java, tools
-;; Copyright (C) 2000 Paul Kinnucan.
+;; Copyright (C) 2000, 2001 Paul Kinnucan.
;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
@@ -27,12 +27,28 @@
;;; Code:
+(require 'semantic-java)
(require 'semantic-imenu)
-(require 'semantic-mode)
-;;;
-;;; Global options
-;;;
+;;; Compatibility
+(cond
+ ((fboundp 'char-valid-p)
+ (defalias 'jde-imenu-char-valid-p 'char-valid-p))
+ ((fboundp 'char-int-p)
+ (defalias 'jde-imenu-char-valid-p 'char-int-p))
+ (t
+ (defun jde-imenu-char-valid-p (object)
+ "Return t if OBJECT is a valid normal character."
+ (condition-case nil
+ (progn
+ (char-to-string object)
+ t)
+ (error nil))))
+ )
+
+;;;;
+;;;; Global options
+;;;;
(defcustom jde-imenu-enable t
"*Enables creation of a classes index menu in the Emacs menubar."
@@ -79,7 +95,10 @@
"Default value of `jde-imenu-modifier-abbrev-alist'.")
(defconst jde-imenu-valid-modifiers-regexp
-
"\\b\\(public\\|protected\\|private\\|static\\|abstract\\|final\\|native\\|synchronized\\|transient\\|volatile\\|strictfp\\)\\b"
+ (concat "\\b"
+ (regexp-opt
+ (mapcar #'car jde-imenu-default-modifier-abbrev-alist) t)
+ "\\b")
"Regexp of valid Java modifiers used by
`jde-imenu-modifier-field-validate'.")
@@ -99,9 +118,10 @@
Used by `jde-imenu-modifier-abbrev-alist' customization."
(save-excursion
(let ((value (widget-value widget)))
- (if (char-valid-p value)
+ (if (jde-imenu-char-valid-p value)
nil
- (widget-put widget :error (format "Invalid character value: %S"
value))
+ (widget-put widget :error
+ (format "Invalid character value: %S" value))
widget))))
(defcustom jde-imenu-modifier-abbrev-alist
@@ -153,12 +173,12 @@
nil)))
;; global
(set-default 'semantic-imenu-sort-bucket-function
- semantic-imenu-sort-bucket-function)
+ semantic-imenu-sort-bucket-function)
(set-default sym val)))
-;;;
-;;; Helper functions
-;;;
+;;;;
+;;;; Helper functions
+;;;;
(defun jde-imenu-abbreviate-modifiers (modifiers)
"Return a string of character abbreviations for MODIFIERS or \"\" if
@@ -175,86 +195,66 @@
alist (cdr alist))
(if (member (car entry) modifiers)
(setq abbrevs
- (concat abbrevs (if (char-valid-p (cdr entry))
+ (concat abbrevs (if (jde-imenu-char-valid-p (cdr entry))
(char-to-string (cdr entry))
"")))))
(if (> (length abbrevs) 0)
- (concat abbrevs " ") ; trailing whitespace separator
+ (concat abbrevs " ") ; trailing whitespace separator
abbrevs))))
-;;;
-;;; Universal `semantic-imenu' stuff adapted to JDE's needs
-;;;
+;;;;
+;;;; Universal `semantic-imenu' stuff adapted to JDE's needs
+;;;;
-(defun jde-imenu-prototype-nonterminal (token)
+(defun jde-imenu-prototype-nonterminal (token &optional parent color)
"Return a prototype for TOKEN.
See also `semantic-prototype-nonterminal'."
(let* ((token-cat (semantic-token-token token))
- (token-name (semantic-token-name token))
- (prototyper (intern (concat "jde-imenu-prototype-"
- (symbol-name token-cat)))))
+ (prototyper (intern-soft (format "jde-imenu-prototype-%s"
+ token-cat))))
(if (fboundp prototyper)
- (funcall prototyper token)
- (message "Unknow token %S" token-cat))))
+ (funcall prototyper token parent color)
+ (semantic-java-prototype-nonterminal token parent color))))
-(defun jde-imenu-prototype-function (token)
+(defun jde-imenu-prototype-function (token &optional parent color)
"Return a function (method) prototype for TOKEN.
-See also `semantic-prototype-nonterminal'."
- (let ((name (semantic-token-name token))
- (mods (semantic-token-function-modifiers token))
- sign)
- (if jde-imenu-include-signature
- (let ((type (semantic-token-type token))
- (args (semantic-token-function-args token)))
- (setq sign (if type
- (format "%s %s(" type name)
- (format "%s(" name)))
- (while args
- (let ((arg-token (car args))
- arg-type)
- (when (semantic-token-p arg-token)
- (setq arg-type (semantic-token-type arg-token))
- (setq sign (concat sign arg-type ",")))
- (setq args (cdr args))))
- ;; remove the extra comma at end
- (if (char-equal ?, (aref sign (1- (length sign))))
- (setq sign (substring sign 0 -1)))
- (setq sign (concat sign ")")))
- (setq sign (format "%s()" name)))
- (format "%s%s" (jde-imenu-abbreviate-modifiers mods) sign)))
+See also `semantic-java-prototype-function'."
+ (let ((sign (if jde-imenu-include-signature
+ (semantic-java-prototype-function token parent color)
+ (concat (if color
+ (semantic-colorize-text
+ (semantic-token-name token) 'function)
+ (semantic-token-name token))
+ "()"))))
+ (concat (jde-imenu-abbreviate-modifiers
+ (semantic-token-function-modifiers token))
+ sign)))
-(defun jde-imenu-prototype-variable (token)
+(defun jde-imenu-prototype-variable (token &optional parent color)
"Return a variable (field) prototype for TOKEN.
-See also `semantic-prototype-nonterminal'."
- (let ((name (semantic-token-name token))
- (mods (semantic-token-variable-modifiers token)))
- (if jde-imenu-include-signature
- (setq name (concat (semantic-token-type token)
- " " name)))
- (format "%s%s" (jde-imenu-abbreviate-modifiers mods) name)))
+See also `semantic-java-prototype-variable'."
+ (let ((sign (if jde-imenu-include-signature
+ (semantic-java-prototype-variable token parent color)
+ (if color
+ (semantic-colorize-text
+ (semantic-token-name token) 'variable)
+ (semantic-token-name token)))))
+ (concat (jde-imenu-abbreviate-modifiers
+ (semantic-token-variable-modifiers token))
+ sign)))
-(defun jde-imenu-prototype-type (token)
+(defun jde-imenu-prototype-type (token &optional parent color)
"Return a type (class/interface) prototype for TOKEN.
See also `semantic-prototype-nonterminal'."
- (let ((name (semantic-token-name token))
- (type (semantic-token-type token))
- (mods (semantic-token-type-modifiers token)))
- (format "%s%s %s" (jde-imenu-abbreviate-modifiers mods) type name)))
+ (let ((sign (semantic-java-prototype-type token parent color)))
+ (concat (jde-imenu-abbreviate-modifiers
+ (semantic-token-type-modifiers token))
+ sign)))
+
+;;;;
+;;;; Specific JDE's imenu (to be replaced by semantic-imenu stuff)
+;;;;
-(defun jde-imenu-prototype-include (token)
- "Return an include (import) prototype for TOKEN.
-See also `semantic-prototype-nonterminal'."
- (semantic-token-name token))
-
-(defun jde-imenu-prototype-package (token)
- "Return a package prototype for TOKEN.
-See also `semantic-prototype-nonterminal'."
- (semantic-token-name token))
-
-;;;
-;;; Specific JDE's imenu (to be replaced by semantic-imenu stuff)
-;;;
-
(defcustom jde-imenu-include-classdef t
"*If non-nil `jde-imenu-index-class' adds *class def* items in imenu
index to go to class definition."
@@ -406,29 +406,17 @@
(setq packages (cdr packages)))
index))
-;;;
-;;; JDE's imenu setup
-;;;
+;;;;
+;;;; JDE's imenu setup
+;;;;
(defun jde-imenu-setup ()
"Setup the JDE's \"Classes\" imenu when entering jde-mode."
(when jde-imenu-enable
- ;; function to use when creating items in imenu.
- (setq semantic-imenu-summary-function
- 'semantic-prototype-nonterminal)
-
- ;; speedbar and imenu buckets name.
- (setq semantic-symbol->name-assoc-list
- '((type . "Classes")
- (variable . "Variables")
- (function . "Methods")
- (include . "Imports")
- (package . "Package")))
-
;; semantic overloaded functions
- (setq semantic-override-table
- '((prototype-nonterminal . jde-imenu-prototype-nonterminal)))
+ (semantic-install-function-overrides
+ '((prototype-nonterminal . jde-imenu-prototype-nonterminal)))
;; function to use for creating the imenu
(setq imenu-create-index-function
@@ -439,20 +427,16 @@
;; add the imenu to the menu bar for the current buffer
(imenu-add-to-menubar "Classes")
- ;; enable `semantic-minor-mode', so imenu configuration and others
- ;; semantic services will be available in the "Parse" menu.
- ;; (semantic-minor-mode 1)
))
-;; Enable which-function-mode in jde-mode (using semantic parser)
-(eval-after-load "which-func"
- '(add-to-list 'which-func-modes 'jde-mode))
-
(provide 'jde-imenu)
;; $Log: jde-imenu.el,v $
-;; Revision 1.1 2001/02/12 05:40:58 paulk
-;; Initial XEmacs version.
+;; Revision 1.4 2001/05/23 03:51:45 paulk
+;; Removed which-func support as jde-which-method is better.
+;;
+;; Revision 1.3 2001/05/19 02:35:59 paulk
+;; Updated to support semantic 1.4. Thanks to David Ponce.
;;
;; Revision 1.2 2000/11/27 06:18:39 paulk
;; Miscellaneous bug fixes and minor enhancements.
Index: xemacs-packages/jde/lisp/jde-import.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/jde-import.el,v
retrieving revision 1.1
diff -u -r1.1 jde-import.el
--- xemacs-packages/jde/lisp/jde-import.el 2001/02/12 05:42:50 1.1
+++ xemacs-packages/jde/lisp/jde-import.el 2001/08/15 05:27:59
@@ -1,15 +1,15 @@
-;;; jde-import-org.el --- Organize Java imports
+;;; jde-import.el --- Organize Java imports
-;; Copyright (C) 2000 by David Ponce
+;; Copyright (C) 2000, 2001 by David Ponce
;; Authors: David Ponce <david(a)dponce.com>
;; Paul Kinnucan <paulk(a)mathworks.com>
;; Maintainers: David Ponce <david(a)dponce.com>
;; Paul Kinnucan <paulk(a)mathworks.com>
;; Created: 15 Nov 2000
-;; Version: $Revision: 1.1 $
+;; Version: $Revision: 1.5 $
;; Keywords: java, tools
-;; VC: $Id: jde-import.el,v 1.1 2001/02/12 05:42:50 paulk Exp $
+;; VC: $Id: jde-import.el,v 1.5 2001/04/27 01:33:42 paulk Exp $
;; This file is not part of Emacs
@@ -36,9 +36,19 @@
;;; History:
;;
;; $Log: jde-import.el,v $
-;; Revision 1.1 2001/02/12 05:42:50 paulk
-;; Initial XEmacs revision.
+;; Revision 1.5 2001/04/27 01:33:42 paulk
+;; jde-import-sort now refreshes parse cache. Thanks to Robert Mecklenburg
<mecklen(a)cimsoft.com> for tthis fix.
;;
+;; Revision 1.4 2001/04/26 09:06:07 paulk
+;; -- jde-import-kill-extra-imports now refreshes the buffer's parse cache. This
fixes a bug where successive calls to the function would incorrectly remove imports.
+;;
+;; -- jde-import-kill-extra-imports now removes fully qualified imports that are not
referenced in the code.
+;;
+;; Thanks to "Javier Lopez" <jlopez(a)cellexchange.com>.
+;;
+;; Revision 1.3 2001/03/13 04:19:45 paulk
+;; Cosmetic changes.
+;;
;; Revision 1.2 2000/11/27 06:18:40 paulk
;; Miscellaneous bug fixes and minor enhancements.
;;
@@ -209,7 +219,7 @@
(and (interactive-p)
(consp current-prefix-arg)
(setq reverse t))
- (let* ((tokens (semantic-bovinate-toplevel))
+ (let* ((tokens (semantic-bovinate-toplevel t))
(depends (semantic-find-nonterminal-by-token 'include tokens)))
(if depends
(let* ((first-import-token (car depends))
@@ -310,7 +320,7 @@
(setq i 0)
(setq n (length new-imports))
(while (< i n)
- (let (deactivate-mark) t)
+ (if (not jde-xemacsp) (deactivate-mark))
(let ((new-import
(nth i new-imports)))
(progn
@@ -449,7 +459,7 @@
(and (interactive-p)
(consp current-prefix-arg)
(setq comment t))
- (let* ((tokens (semantic-bovinate-toplevel))
+ (let* ((tokens (semantic-bovinate-toplevel t))
(imports (semantic-find-nonterminal-by-token 'include tokens)))
(if (not imports)
(message "No import found")
@@ -474,14 +484,24 @@
(first-import (car imports))
extra-imports
required-imports)
- ;; Get the list of extra imports
+ ;; Get the list of extra imports
+ ;; Going to character zero so the the count-matches method work.
+ (goto-char 0)
(while imports
(let* ((import (car imports))
- (name (semantic-token-name import)))
+ (name (semantic-token-name import))
+ (classname (jde-import-get-classname name))
+ (number-of-matches (substring (count-matches classname) 0 2)))
+ (prin1 classname)
+ (prin1 number-of-matches)
(if (or
;; If name is already listed in the set
- ;; of required imports...
+ ;; of required imports...
(member name required-imports)
+ ;;or the class is not reference in the file
+ ;;and is not an import of the whole package i.e. .*
+ (and (< (string-to-number number-of-matches) 2)
+ (not (string= classname "*")))
;; or imports a class in the current package...
(and
;; make sure name is not a package import, e.g., foo.bar.*
@@ -502,7 +522,7 @@
(setq required-imports (cons name required-imports))))
(setq imports (cdr imports)))
(if (not extra-imports)
- (message "No extra imports found")
+ (message "No extra imports found")
(let ((count 0))
;; Move the point at the beginning of the first import
(goto-char (semantic-token-start first-import))
@@ -525,11 +545,23 @@
(point))))
(setq extra-imports (cdr extra-imports))))
(message "%d extra import%s removed"
- count (if (= count 1) "" "s")))))))))
+ count (if (= count 1) "" "s")))))))))
;;;;
;;;; Helper functions
;;;;
+
+(defun jde-import-get-classname(import)
+ "Takes as an argument an import i.e. java.util.Vector.
+And returns the class name. In the above example it will
+return Vector"
+ (let ((pieces (split-string import "\\.")))
+ (while pieces
+ (let* ((current (car pieces)))
+ (setq pieces (cdr pieces))
+ (if (not (string= nil current))
+ (setq class current))))
+ class))
(defun jde-import-group-of (import-token)
"Return the group IMPORT-TOKEN belongs to or nil if not found.
Index: xemacs-packages/jde/lisp/jde-java-font-lock.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/jde-java-font-lock.el,v
retrieving revision 1.1
diff -u -r1.1 jde-java-font-lock.el
--- xemacs-packages/jde/lisp/jde-java-font-lock.el 2001/02/12 05:45:05 1.1
+++ xemacs-packages/jde/lisp/jde-java-font-lock.el 2001/08/15 05:27:59
@@ -7,7 +7,7 @@
;; Paul Kinnucan <paulk(a)mathworks.com>
;; Created: September 28 1998
;; Keywords: java, tools
-;; VC: $Id: jde-java-font-lock.el,v 1.1 2001/02/12 05:45:05 paulk Exp $
+;; VC: $Id: jde-java-font-lock.el,v 1.5 2001/04/14 05:28:11 paulk Exp $
;; This file is not part of Emacs
@@ -30,61 +30,73 @@
;;
;; Adds some extra level font locking for java in `jde-mode'.
;;
-;; * Numbers are fontified with `jde-java-font-lock-number-face'.
+;; - Numbers are fontified with `jde-java-font-lock-number-face'.
;;
-;; * Modifiers are fontified with `font-lock-builtin-face'. This face
-;; is based on XEmacs `font-lock-preprocessor-face' if available.
+;; - Packages in package and import statements are fontified with
+;; `jde-java-font-lock-package-face'. Last '*' of imported packages
+;; are fontified with `jde-java-font-lock-number-face'. Last type
+;; identifiers of imported packages are fontified with
+;; `font-lock-type-face'.
;;
-;; * Keywords const and goto are fontified with
+;; - Modifiers are fontified with `jde-java-font-lock-modifier-face'.
+;;
+;; - Keywords const and goto are fontified with
;; `font-lock-warning-face'. These keywords are reserved, even
;; though they are not currently used.
;;
-;; * The keyword default is fontified with `font-lock-keyword-face'.
+;; - Keywords super, this and default are fontified with
+;; `font-lock-keyword-face'.
;;
-;; * User's defined identifiers (see variable
+;; - User's defined identifiers (see variable
;; `jde-java-font-lock-api-file') are fontified with
;; `jde-java-font-lock-api-face'.
+;;
+;; - Capitalized identifiers and special constants null, true and
+;; false are fontified with `jde-java-font-lock-constant-face'.
;;
-;; * Capitalized identifiers, text between `' in comments and javadoc
-;; tags (including non official javadoc tags) are fontified with
-;; `font-lock-constant-face'. This face is based on XEmacs
-;; `font-lock-reference-face' if available.
+;; - Text between `' in comments and javadoc tags (including non
+;; official javadoc tags) are fontified with
+;; `jde-java-font-lock-doc-tag-face'.
;;
-;; * Javadoc links (following @link tags or enclosed in HTML <a> tags)
+;; - Javadoc links (following @link tags or enclosed in HTML <a> tags)
;; are fontified with `jde-java-font-lock-link-face'
;;
-;; * Javadoc code samples (enclosed in HTML <code> tags or following
-;; @see tags) are fontified with `jde-java-font-lock-code-face'. By
-;; default, this face is based on `font-lock-builtin-face'.
+;; - Javadoc code samples (enclosed in HTML <code> tags or following
+;; @see tags) are fontified with `jde-java-font-lock-code-face'.
;;
-;; * Javadoc HTML bold style is fontified with
-;; `jde-java-font-lock-bold-face'. By default, this face is based
-;; on `bold'.
-;;
-;; * Javadoc HTML italic style is fontified with
-;; `jde-java-font-lock-italic-face'. By default, this face is based
-;; on `italic'.
-;;
-;; * Javadoc HTML underlined style is fontified with
-;; `jde-java-font-lock-underline-face'. By default, this face is
-;; based on `underline'.
-;;
-;; * Javadoc HTML preformatted style is fontified with
-;; `jde-java-font-lock-pre-face'. By default, this face is based on
-;; `default'.
+;; - Javadoc HTML bold and strong styles are fontified with
+;; `jde-java-font-lock-bold-face'.
+;;
+;; - Javadoc HTML italic and emphasized styles are fontified with
+;; `jde-java-font-lock-italic-face'.
+;;
+;; - Javadoc HTML underlined style is fontified with
+;; `jde-java-font-lock-underline-face'.
+;;
+;; - Javadoc HTML preformatted style is fontified with
+;; `jde-java-font-lock-pre-face'.
;;
;; All font-lock and jde-java-font-lock faces are individually
-;; customizable.
+;; customizable. jde-java-font-lock faces are in the customization
+;; group `jde-java-font-lock-faces' which is a sub group of
+;; `font-lock-highlighting-faces' (Emacs) or `font-lock-faces'
+;; (XEmacs).
;; This code has been tested with FSF Emacs 20.7, 21.0 and XEmacs
;; 21.1. Any comments, suggestions, bug reports or upgrade requests
;; are welcome. Please send them to the maintainers.
+;; WARNING: It seems there is byte-code compatibility issues between
+;; Emacs and XEmacs. When using Emacs byte-code on XEmacs font
+;; locking don't work correctly for some complex matchers like those
+;; used to highlight imported package name :-)
+
;;; History:
;;
;; See at end of this file.
;;; Code:
+(require 'font-lock)
(defcustom jde-use-font-lock t
"*Turn on font-locking if non-nil.
@@ -92,11 +104,27 @@
:group 'jde-project
:type 'boolean)
+(defcustom jde-java-font-lock-max-names-by-regexp
+ (if (featurep 'xemacs) 200 0)
+ "*Maximum number of user defined names that one regexp can match.
+No limit if less than 1.
+
+WARNING: It seems XEmacs search fails with a very long regexp. So the
+XEmacs default limits is 200. No limit for Emacs."
+ :group 'jde-project
+ :type 'integer)
+
;;;;
;;;; Define the faces
;;;;
-;; Create a specific face for numbers
+(defgroup jde-java-font-lock-faces nil
+ "Specific JDE faces for highlighting Java sources."
+ :prefix "jde-java-font-lock-"
+ :group (if (featurep 'xemacs)
+ 'font-lock-faces
+ 'font-lock-highlighting-faces))
+
(defface jde-java-font-lock-number-face
'((((class grayscale) (background light)) (:foreground "DimGray" :italic
t))
(((class grayscale) (background dark)) (:foreground "LightGray" :italic
t))
@@ -104,73 +132,95 @@
(((class color) (background dark)) (:foreground "LightSalmon"))
(t (:italic t)))
"Font Lock mode face used to highlight numbers."
- :group 'font-lock-highlighting-faces)
+ :group 'jde-java-font-lock-faces)
+
+(defface jde-java-font-lock-constant-face
+ '((((type tty) (class color)) (:foreground "magenta"))
+ (((class grayscale) (background light))
+ (:foreground "LightGray" :bold t :underline t))
+ (((class grayscale) (background dark))
+ (:foreground "Gray50" :bold t :underline t))
+ (((class color) (background light)) (:foreground "CadetBlue"))
+ (((class color) (background dark)) (:foreground "Aquamarine"))
+ (t (:bold t :underline t)))
+ "Font Lock mode face used to highlight constants."
+ :group 'jde-java-font-lock-faces)
-;; Create a specific face for user's defined names
(defface jde-java-font-lock-api-face
'((((class grayscale) (background light)) (:foreground "DimGray"))
(((class grayscale) (background dark)) (:foreground "LightGray"))
(((class color) (background light)) (:foreground "dark goldenrod"))
(((class color) (background dark)) (:foreground "light goldenrod")))
"Font Lock mode face used to highlight user's defined names."
- :group 'font-lock-highlighting-faces)
+ :group 'jde-java-font-lock-faces)
-;; Create a specific face for links
(defface jde-java-font-lock-link-face
'((t (:foreground "blue" :italic nil :underline t)))
"Font Lock mode face used to highlight links."
- :group 'font-lock-highlighting-faces)
+ :group 'jde-java-font-lock-faces)
-;;; Compatibility
-(if jde-xemacsp
- (progn
-
- (defvar font-lock-builtin-face 'font-lock-builtin-face
- "Face name to use for builtins.")
-
- ;; For consistency try to define the builtin face as the XEmacs
- ;; preprocessor face
- (condition-case nil
- (copy-face 'font-lock-preprocessor-face 'font-lock-builtin-face)
- (error
- (defface font-lock-builtin-face
- '((t (:foreground "blue" :italic nil :underline t)))
- "Font Lock mode face used to highlight builtins."
- :group 'font-lock-highlighting-faces)))
-
- (defvar font-lock-constant-face 'font-lock-constant-face
- "Face name to use for constant and label names.")
-
- ;; For consistency try to define the constant face as the XEmacs
- ;; reference face
- (condition-case nil
- (copy-face 'font-lock-reference-face 'font-lock-constant-face)
- (error
- (defface font-lock-constant-face
- '((((class grayscale) (background light))
- (:foreground "LightGray" :bold t :underline t))
- (((class grayscale) (background dark))
- (:foreground "Gray50" :bold t :underline t))
- (((class color) (background light)) (:foreground "CadetBlue"))
- (((class color) (background dark)) (:foreground "Aquamarine"))
- (t (:bold t :underline t)))
- "Font Lock mode face used to highlight constants and labels."
- :group 'font-lock-highlighting-faces)))
-
- ))
-
-;; Make new faces based on existing ones
-(copy-face 'bold 'jde-java-font-lock-bold-face)
-(copy-face 'italic 'jde-java-font-lock-italic-face)
-(copy-face 'underline 'jde-java-font-lock-underline-face)
-(copy-face 'default 'jde-java-font-lock-pre-face)
-(copy-face 'font-lock-builtin-face 'jde-java-font-lock-code-face)
+(defface jde-java-font-lock-package-face
+ '((((class color) (background dark)) (:foreground "steelblue1"))
+ (((class color) (background light)) (:foreground "blue3"))
+ (t (:underline t)))
+ "Font Lock Mode face used to highlight packages."
+ :group 'jde-java-font-lock-faces)
+
+(defface jde-java-font-lock-doc-tag-face
+ '((((class color) (background dark)) (:foreground "light coral"))
+ (((class color) (background light)) (:foreground "green4"))
+ (t (:bold t)))
+ "Font Lock Mode face used to highlight doc tags."
+ :group 'jde-java-font-lock-faces)
+
+(defface jde-java-font-lock-modifier-face
+ '((((type tty) (class color)) (:foreground "blue" :weight light))
+ (((class grayscale) (background light)) (:foreground "LightGray" :bold
t))
+ (((class grayscale) (background dark)) (:foreground "DimGray" :bold t))
+ (((class color) (background light)) (:foreground "Orchid"))
+ (((class color) (background dark)) (:foreground "LightSteelBlue"))
+ (t (:bold t)))
+ "Font Lock Mode face used to highlight modifiers."
+ :group 'jde-java-font-lock-faces)
+
+(defface jde-java-font-lock-bold-face
+ '((t (:bold t)))
+ "Font Lock Mode face used to highlight HTML bold text style."
+ :group 'jde-java-font-lock-faces)
+
+(defface jde-java-font-lock-italic-face
+ '((t (:italic t)))
+ "Font Lock Mode face used to highlight HTML italic text style."
+ :group 'jde-java-font-lock-faces)
+
+(defface jde-java-font-lock-underline-face
+ '((t (:underline t)))
+ "Font Lock Mode face used to highlight HTML underlined text style."
+ :group 'jde-java-font-lock-faces)
+
+(defface jde-java-font-lock-pre-face
+ '((t nil))
+ "Font Lock Mode face used to highlight HTML preformatted text style."
+ :group 'jde-java-font-lock-faces)
+
+(defface jde-java-font-lock-code-face
+ '((t nil))
+ "Font Lock Mode face used to highlight HTML program code style."
+ :group 'jde-java-font-lock-faces)
;; Define the extra font lock faces
(defvar jde-java-font-lock-number-face 'jde-java-font-lock-number-face
"Face name to use for numbers.")
+(defvar jde-java-font-lock-constant-face 'jde-java-font-lock-constant-face
+ "Face name to use for constants.")
+(defvar jde-java-font-lock-package-face 'jde-java-font-lock-package-face
+ "Face name to use for packages.")
+(defvar jde-java-font-lock-modifier-face 'jde-java-font-lock-modifier-face
+ "Face name to use for modifiers.")
(defvar jde-java-font-lock-api-face 'jde-java-font-lock-api-face
"Face name to use for user's defined names.")
+(defvar jde-java-font-lock-doc-tag-face 'jde-java-font-lock-doc-tag-face
+ "Face name to use for doc tags.")
(defvar jde-java-font-lock-link-face 'jde-java-font-lock-link-face
"Face name to use for links.")
(defvar jde-java-font-lock-bold-face 'jde-java-font-lock-bold-face
@@ -212,7 +262,7 @@
(defun jde-java-font-lock-remove-javadoc-keywords (keywords)
"Remove existing javadoc font lock keywords from KEYWORDS.
That is those with \"@\" in their matcher regexp."
- (let (kw matcher match)
+ (let (kw matcher)
(while keywords
(setq matcher (car keywords)
keywords (cdr keywords))
@@ -263,9 +313,9 @@
"Return a font lock keyword for comment enclosed in \`\'."
`((lambda (end)
(jde-java-font-lock-search-in-comment
- "`\\(.*\\)'"
+ "`\\([^']*\\)'"
end))
- 1 font-lock-constant-face t))
+ 1 jde-java-font-lock-doc-tag-face t))
(defun jde-java-font-lock-html-ahref-keyword ()
"Return a font lock keyword for HTML A HREF anchor.
@@ -276,32 +326,25 @@
end))
1 jde-java-font-lock-link-face t))
-(defun jde-java-font-lock-html-strong-keyword ()
- "Return a font lock keyword for HTML STRONG style.
-Only fontify javadoc comments."
- `((lambda (end)
- (jde-java-font-lock-search-in-javadoc
-
"<[Ss][Tt][Rr][Oo][Nn][Gg]>\\([^<]*\\)</[Ss][Tt][Rr][Oo][Nn][Gg]>"
- end))
- 1 jde-java-font-lock-bold-face t))
-
(defun jde-java-font-lock-html-bold-keyword ()
- "Return a font lock keyword for HTML B style.
+ "Return a font lock keyword for HTML B and STRONG style.
Only fontify javadoc comments."
`((lambda (end)
(jde-java-font-lock-search-in-javadoc
- "<[Bb]>\\([^<]*\\)</[Bb]>"
+ , (concat "<\\([Bb]\\|[Ss][Tt][Rr][Oo][Nn][Gg]\\)>"
+ "\\([^<]*\\)"
+ "</\\([Bb]\\|[Ss][Tt][Rr][Oo][Nn][Gg]\\)>")
end))
- 1 jde-java-font-lock-bold-face t))
+ 2 jde-java-font-lock-bold-face t))
(defun jde-java-font-lock-html-italic-keyword ()
- "Return a font lock keyword for HTML I style.
+ "Return a font lock keyword for HTML I and EM style.
Only fontify javadoc comments."
`((lambda (end)
(jde-java-font-lock-search-in-javadoc
- "<[Ii]>\\([^<]*\\)</[Ii]>"
+
"<\\([Ii]\\|[Ee][Mm]\\)>\\([^<]*\\)</\\([Ii]\\|[Ee][Mm]\\)>"
end))
- 1 jde-java-font-lock-italic-face t))
+ 2 jde-java-font-lock-italic-face t))
(defun jde-java-font-lock-html-underline-keyword ()
"Return a font lock keyword for HTML U style.
@@ -338,7 +381,7 @@
,(concat "^[ \t]*\\(/\\*\\*\\|\\*?\\)[ \t]*"
"\\(@[" jde-java-font-lock-letter-or-digit "]+\\)")
end))
- 2 font-lock-constant-face t))
+ 2 jde-java-font-lock-doc-tag-face t))
(defun jde-java-font-lock-javadoc-docroot-keyword ()
"Return a font lock keyword for javadoc @docRoot tags.
@@ -347,7 +390,7 @@
(jde-java-font-lock-search-in-javadoc
"{\\(@docRoot\\)}"
end))
- 1 font-lock-constant-face t))
+ 1 jde-java-font-lock-doc-tag-face t))
(defun jde-java-font-lock-javadoc-link-keyword ()
"Return a font lock keyword for javadoc @link tags.
@@ -356,7 +399,7 @@
(jde-java-font-lock-search-in-javadoc
"{\\(@link\\)\\>[ \t]+\\([^}]*\\)}"
end))
- (1 font-lock-constant-face t)
+ (1 jde-java-font-lock-doc-tag-face t)
(2 jde-java-font-lock-link-face t)))
(defun jde-java-font-lock-javadoc-see-ref-keyword ()
@@ -484,7 +527,7 @@
(and jde-java-font-lock-api-file
(format "%s.%semacs-%d.apicache"
jde-java-font-lock-api-file
- (if jde-xemacsp "x" "")
+ (if (featurep 'xemacs) "x" "")
emacs-major-version)))
(defconst jde-java-font-lock-api-cache-file-header
@@ -539,10 +582,7 @@
(message "jde-java-font-lock: building names cache...")
(when (setq jde-java-font-lock-api-cache
(jde-java-font-lock-api-build-regexps
- ;; WARNING: It seems XEmacs search fails with a
- ;; very long regexp. So get regexps for groups
- ;; of up to 200 names.
- (if jde-xemacsp 200 0)))
+ jde-java-font-lock-max-names-by-regexp))
;; Save regexps in cache
(with-current-buffer (find-file-noselect cache)
(erase-buffer)
@@ -573,6 +613,27 @@
(defvar java-font-lock-keywords-4 nil
"Extra level fontification keywords for JDE mode.")
+(defun jde-java-font-lock-refontify ()
+ "Update fontification of buffers in `java-mode' and `jde-mode'."
+ (let ((l (buffer-list))
+ b)
+ (while l
+ (setq b (car l)
+ l (cdr l))
+ (if (buffer-live-p b)
+ (with-current-buffer b
+ (if (and font-lock-mode
+ (memq major-mode '(java-mode jde-mode)))
+ (progn
+ (message
+ "jde-java-font-lock: updating fontification of buffer
%s..."
+ (buffer-name))
+ (font-lock-mode nil)
+ (font-lock-mode 1)
+ (message
+ "jde-java-font-lock: updating fontification of buffer
%s...done"
+ (buffer-name)))))))))
+
;;;###autoload
(defun jde-java-font-lock-setup-keywords (&optional rebuild)
"Setup font lock keywords in `java-font-lock-keywords-4'.
@@ -590,12 +651,14 @@
;; constants, Modifiers and Packages from keywords-1 will catch
;; them.
;;; Compatibility
- (if jde-xemacsp
+ (if (featurep 'xemacs)
(list
;; Special keywords and constants
- '("\\<\\(this\\|super\\)\\>" (1 font-lock-keyword-face))
- '("\\<\\(false\\|null\\|true\\)\\>" (1
font-lock-constant-face))
+ '("\\<\\(this\\|super\\)\\>"
+ (1 font-lock-keyword-face))
+ '("\\<\\(false\\|null\\|true\\)\\>"
+ (1 jde-java-font-lock-constant-face))
))
(list
@@ -626,22 +689,24 @@
"volatile"
)))
"\\)\\>")
- 'font-lock-builtin-face)
+ 'jde-java-font-lock-modifier-face)
;; Fontify package directives
- '("\\<\\(package\\)\\>[ \t]*\\(\\sw+\\)?"
+ '("\\<\\(package\\)\\>\\s-+\\(\\sw+\\)"
(1 font-lock-keyword-face)
- (2 font-lock-constant-face nil t)
+ (2 jde-java-font-lock-package-face nil t)
("\\=\\.\\(\\sw+\\)" nil nil
- (1 font-lock-constant-face nil t)))
+ (1 jde-java-font-lock-package-face nil t)))
;; Fontify import directives
- '("\\<\\(import\\)\\>[ \t]*\\(\\sw+\\)?"
+ '("\\<\\(import\\)\\>\\s-+\\(\\sw+\\)"
(1 font-lock-keyword-face)
- (2 font-lock-constant-face nil t)
+ (2 (if (equal (char-after (match-end 0)) ?\.)
+ 'jde-java-font-lock-package-face
+ 'font-lock-type-face))
("\\=\\.\\(\\*\\|\\sw+\\)" nil nil
(1 (if (equal (char-after (match-end 0)) ?\.)
- 'font-lock-constant-face
+ 'jde-java-font-lock-package-face
(if (equal (char-before (match-end 0)) ?\*)
'jde-java-font-lock-number-face
'font-lock-type-face)))))
@@ -651,7 +716,7 @@
(jde-java-font-lock-api-keywords rebuild)
;;; Compatibility
- (if jde-xemacsp
+ (if (featurep 'xemacs)
java-font-lock-keywords-2
;; Remove existing javadoc font lock keywords from FSF Emacs
;; `java-font-lock-keywords-3'
@@ -659,7 +724,7 @@
java-font-lock-keywords-3))
;;; Compatibility
- (if jde-xemacsp
+ (if (featurep 'xemacs)
nil
;; FSF Emacs don't fontify capitalized types so do it
(list
@@ -687,21 +752,29 @@
(list
;; Fontify numbers
- (cons
- (concat "\\b\\(0[xX][0-9a-fA-F]+[lL]?\\|[0-9]+\\.?[0-9]*"
- "\\([eE][-+]?[0-9]+\\)?\\([lL]\\|[fF]\\|[dD]\\)?\\)\\b")
- 'jde-java-font-lock-number-face)
- (cons
- (concat "\\b\\(\\.[0-9]+"
- "\\([eE][-+]?[0-9]+\\)?\\([lL]\\|[fF]\\|[dD]\\)?\\)\\b")
- 'jde-java-font-lock-number-face)
+ '("\\<[0-9]+[.][0-9]+\\([eE][-+]?[0-9]+\\)?[fFdD]?\\>"
+ . jde-java-font-lock-number-face)
+ '("\\<[0-9]+[.][eE][-+]?[0-9]+[fFdD]?\\>"
+ . jde-java-font-lock-number-face)
+ '("\\<[0-9]+[.][fFdD]\\>"
+ . jde-java-font-lock-number-face)
+ '("\\<[0-9]+[.]"
+ . jde-java-font-lock-number-face)
+ '("[.][0-9]+\\([eE][-+]?[0-9]+\\)?[fFdD]?\\>"
+ . jde-java-font-lock-number-face)
+ '("\\<[0-9]+[eE][-+]?[0-9]+[fFdD]?\\>"
+ . jde-java-font-lock-number-face)
+ '("\\<0[xX][0-9a-fA-F]+[lL]?\\>"
+ . jde-java-font-lock-number-face)
+ '("\\<[0-9]+[lLfFdD]?\\>"
+ . jde-java-font-lock-number-face)
;; Fontify capitalised identifiers as constant
(cons
(concat "\\(\\b[" jde-java-font-lock-capital-letter
"]+[" jde-java-font-lock-capital-letter-or-digit
"]*\\b\\)")
- '(1 font-lock-constant-face))
+ '(1 jde-java-font-lock-constant-face))
;; Fontify text between `' in comments
(jde-java-font-lock-quote-keyword))
@@ -723,11 +796,9 @@
(jde-java-font-lock-javadoc-see-ref-keyword)
;; Fontify the text of a HREF anchor
(jde-java-font-lock-html-ahref-keyword)
- ;; Fontify <strong> style text
- (jde-java-font-lock-html-strong-keyword)
- ;; Fontify <b> style text
+ ;; Fontify <b> and <strong> style text
(jde-java-font-lock-html-bold-keyword)
- ;; Fontify <i> style text
+ ;; Fontify <i> and <em> style text
(jde-java-font-lock-html-italic-keyword)
;; Fontify <u> style text
(jde-java-font-lock-html-underline-keyword)
@@ -736,51 +807,54 @@
;; Fontify <pre> style text
(jde-java-font-lock-html-pre-keyword))
- )))
+ ))
+
+ ;; Update fontification of buffers in `java-mode' and `jde-mode'
+ (and (interactive-p)
+ (jde-java-font-lock-refontify)))
+;; Setup `java-font-lock-keywords-4'
(jde-java-font-lock-setup-keywords)
-;; Setup JDE mode for font locking. Copy `font-lock-defaults' from
-;; `java-mode' and add the new `java-font-lock-keywords-4' level in
-;; `jde-mode'.
-
-(defun jde-java-font-lock-defaults (java-defaults)
- "Return a new `font-lock-defaults' value from JAVA-DEFAULTS.
-That is add the new `java-font-lock-keywords-4' level."
- (cons (append (car java-defaults) '(java-font-lock-keywords-4))
- (cdr java-defaults)))
+;; Define new defaults for Font Lock mode
+(defconst jde-java-font-lock-defaults
+ (let ((java-defaults
+ (if (featurep 'xemacs)
+ (get 'java-mode 'font-lock-defaults)
+ (cdr (assq 'java-mode font-lock-defaults-alist)))))
+ (cons (append (car java-defaults) '(java-font-lock-keywords-4))
+ (cdr java-defaults)))
+ "Defaults for Font Lock mode specified by the major mode.
+Add `java-font-lock-keywords-4' level to Java `font-lock-defaults'.")
-;;; Compatibility
-;; XEmacs
-(if jde-xemacsp
- (put 'jde-mode 'font-lock-defaults
- (jde-java-font-lock-defaults
- (get 'java-mode 'font-lock-defaults)))
-
- ;; FSF Emacs
- (add-to-list
- 'font-lock-defaults-alist
- (cons 'jde-mode
- (jde-java-font-lock-defaults
- (cdr (assq 'java-mode font-lock-defaults-alist)))))
- )
-
+;; Mode hook to setup syntax coloring. Automatically run by
+;; `jde-mode' if `jde-use-font-lock' is non-nil.
(defun jde-setup-syntax-coloring()
"Set up JDE mode syntax coloring."
- (cond (window-system
-
- ;; If not XEmacs 20.1 turn on font lock.
- ;; (XEmacs 21 has font-lock on by default.)
- (if (or
- (not jde-xemacsp)
- (not
- (and
- (eq emacs-major-version 21)
- (eq emacs-minor-version 0))))
- (turn-on-font-lock))
-
- (setq font-lock-maximum-decoration t))))
+ (if window-system
+ (progn
+ ;; Setup `font-lock-defaults'
+ (set (make-local-variable 'font-lock-defaults)
+ jde-java-font-lock-defaults)
+ ;; Use the maximum decoration available
+ (set (make-local-variable 'font-lock-maximum-decoration)
+ t)
+ ;; Turn on Font Lock Mode as needed
+ (if (and (boundp 'global-font-lock-mode)
+ (symbol-value 'global-font-lock-mode)
+ (let ((flgm (and (boundp 'font-lock-global-modes)
+ (symbol-value 'font-lock-global-modes))))
+ (or (eq flgm t)
+ (if (eq (car-safe flgm) 'not)
+ (not (memq major-mode (cdr flgm)))
+ (memq major-mode flgm)))))
+ ;; Already enabled by `global-font-lock-mode'.
+ nil
+ ;; Turn it on.
+ (turn-on-font-lock)))))
+;; To use JDE mode syntax coloring in Java mode
+(add-hook 'java-mode-hook 'jde-setup-syntax-coloring)
(provide 'jde-java-font-lock)
@@ -788,8 +862,39 @@
;;
;; $Log: jde-java-font-lock.el,v $
-;; Revision 1.1 2001/02/12 05:45:05 paulk
-;; Initial XEmacs revision.
+;; Revision 1.5 2001/04/14 05:28:11 paulk
+;; - All extra fontification added by jde-java-font-lock have a specific
+;; face. So there is less font-lock implementation dependencies,
+;; greater flexibility to setup a color theme, and fontification can be
+;; kept consistent accross Emacs flavors :-) Notice that this change
+;; may require to redo some face customization :(
+;;
+;;
+;; - For convenience all specific jde-java-font-lock faces are in the
+;; customization group `jde-java-font-lock-faces' which is a sub group
+;; of `font-lock-highlighting-faces' (Emacs) or `font-lock-faces'
+;; (XEmacs).
+;;
+;;
+;; - Better fontification of numbers and imported package names.
+;;
+;;
+;; - When used interactively the command
+;; `jde-java-font-lock-setup-keywords' automatically update
+;; fontification of all Java buffers. This is very useful when you
+;; change your API file for example!
+;;
+;;
+;; - The `jde-setup-syntax-coloring' is greatly enhanced. On Emacs, it
+;; takes care of the current `global-font-lock-mode' setting. Also, it
+;; no more use `font-lock-defaults-alist' (which is an obsolete
+;; variable on Emacs 21) but the preferred `font-lock-defaults' way to
+;; setup fontification.
+;;
+;; - Finally, jde-java-font-lock works in java-mode too and it can be
+;; used standalone if needed.
+;;
+;; Contributed by David Ponce.
;;
;; Revision 1.4 2001/01/17 18:59:03 paulk
;; Font-locking improvements from David Ponce
@@ -827,4 +932,4 @@
;; Initial revision.
;;
-;;; jde-java-font-lock.el ends here
\ No newline at end of file
+;;; jde-java-font-lock.el ends here
Index: xemacs-packages/jde/lisp/jde-java-grammar.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/jde-java-grammar.el,v
retrieving revision 1.2
diff -u -r1.2 jde-java-grammar.el
--- xemacs-packages/jde/lisp/jde-java-grammar.el 2001/02/22 12:45:16 1.2
+++ xemacs-packages/jde/lisp/jde-java-grammar.el 2001/08/15 05:27:59
@@ -1,5 +1,5 @@
;;; jde-java-grammar.el
-;; $Revision: 1.2 $
+;; $Revision: 1.4 $
;; Author: Paul Kinnucan <paulk(a)mathworks.com>
;; Maintainer: Paul Kinnucan
@@ -22,484 +22,34 @@
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
-(require 'semantic)
-(defvar jde-parse-bovine-java-grammar
- `((bovine-toplevel
- ( package_declaration)
- ( import_declaration)
- ( type_declaration)
- ) ; end bovine-toplevel
- (number
- ( symbol "[0-9]" punctuation "\\." symbol "[0-9Ee]"
punctuation "[-+]" symbol "[0-9fFdD]")
- ( symbol "[0-9]" punctuation "\\." symbol
"[0-9EefFdD]")
- ( symbol "[0-9fFdD]")
- ) ; end number
- (literal
- ( number)
- ( qualified_name)
- ( string)
- ) ; end literal
- (type
- ( reference_type
- ,(semantic-lambda
- (nth 0 vals)))
- ( primitive_type
- ,(semantic-lambda
- (nth 0 vals)))
- ) ; end type
- (primitive_type
- ( BOOLEAN)
- ( BYTE)
- ( SHORT)
- ( INT)
- ( LONG)
- ( CHAR)
- ( FLOAT)
- ( DOUBLE)
- ) ; end primitive_type
- (reference_type
- ( array_type
- ,(semantic-lambda
- (nth 0 vals)))
- ( qualified_name
- ,(semantic-lambda
- (nth 0 vals)))
- ) ; end reference_type
- (array_type
- ( primitive_type dims
- ,(semantic-lambda
- (list ( concat ( car (nth 0 vals)) ( car (nth 1 vals))))))
- ( qualified_name dims
- ,(semantic-lambda
- (list ( concat ( car (nth 0 vals)) ( car (nth 1 vals))))))
- ) ; end array_type
- (qualified_name
- ( symbol punctuation "\\." qualified_name
- ,(semantic-lambda
- (list ( concat (nth 0 vals) (nth 1 vals) ( car (nth 2 vals))))))
- ( symbol
- ,(semantic-lambda
- (list (nth 0 vals))))
- ) ; end qualified_name
- (package_declaration
- ( PACKAGE qualified_name punctuation ";"
- ,(semantic-lambda
- (nth 1 vals) (list 'package nil)))
- ) ; end package_declaration
- (import_declaration
- ( IMPORT qualified_name punctuation ";"
- ,(semantic-lambda
- (nth 1 vals) (list 'include nil)))
- ( IMPORT qualified_name punctuation "\\." punctuation "*"
punctuation ";"
- ,(semantic-lambda
- (list ( concat ( car (nth 1 vals)) (nth 2 vals) (nth 3 vals)) 'include nil)))
- ) ; end import_declaration
- (type_declaration
- ( punctuation ";")
- ( class_declaration)
- ( interface_declaration)
- ) ; end type_declaration
- (modifiers_opt
- ( modifiers
- ,(semantic-lambda
- (nth 0 vals)))
- ()
- ) ; end modifiers_opt
- (modifiers
- ( modifier modifiers
- ,(semantic-lambda
- ( cons ( car (nth 0 vals)) (nth 1 vals))))
- ( modifier
- ,(semantic-lambda
- (nth 0 vals)))
- ) ; end modifiers
- (modifier
- ( PUBLIC)
- ( PROTECTED)
- ( PRIVATE)
- ( STATIC)
- ( ABSTRACT)
- ( FINAL)
- ( NATIVE)
- ( SYNCHRONIZED)
- ( TRANSIENT)
- ( VOLATILE)
- ( STRICTFP)
- ) ; end modifier
- (class_declaration
- ( modifiers_opt CLASS qualified_name class_parents class_body
- ,(semantic-lambda
- (nth 2 vals) (list 'type "class" (nth 4 vals) (nth 3 vals) (nth 0
vals) nil)))
- ) ; end class_declaration
- (class_parents
- ( super interfaces
- ,(semantic-lambda
- ( append (nth 0 vals) (nth 1 vals))))
- ( interfaces super
- ,(semantic-lambda
- ( append (nth 1 vals) (nth 0 vals))))
- ( super
- ,(semantic-lambda
- (nth 0 vals)))
- ( interfaces
- ,(semantic-lambda
- ( cons nil (nth 0 vals))))
- ()
- ) ; end class_parents
- (super
- ( EXTENDS qualified_name
- ,(semantic-lambda
- (nth 1 vals)))
- ) ; end super
- (interfaces
- ( IMPLEMENTS qualified_name_list
- ,(semantic-lambda
- (nth 1 vals)))
- ) ; end interfaces
- (qualified_name_list
- ( qualified_name punctuation "," qualified_name_list
- ,(semantic-lambda
- ( cons ( car (nth 0 vals)) (nth 2 vals))))
- ( qualified_name
- ,(semantic-lambda
- (nth 0 vals)))
- ) ; end qualified_name_list
- (class_body
- ( semantic-list
- ,(semantic-lambda
-
- (semantic-bovinate-from-nonterminal-full (car (nth 0 vals)) (cdr (nth 0 vals))
'class_body_declarations)
- ))
- ) ; end class_body
- (class_body_declarations
- ( class_declaration
- ,(semantic-lambda
- (nth 0 vals)))
- ( interface_declaration
- ,(semantic-lambda
- (nth 0 vals)))
- ( field_declaration
- ,(semantic-lambda
- (nth 0 vals)))
- ( method_declaration
- ,(semantic-lambda
- (nth 0 vals)))
- ( constructor_declaration
- ,(semantic-lambda
- (nth 0 vals)))
- ) ; end class_body_declarations
- (field_declaration
- ( modifiers_opt type variable_declarators punctuation ";"
- ,(semantic-lambda
- (nth 2 vals) (list 'variable) (nth 1 vals) (list nil nil (nth 0 vals)
nil)))
- ) ; end field_declaration
- (variable_declarators
- ( variable_declarator variable_declarators_opt
- ,(semantic-lambda
- (nth 0 vals)))
- ) ; end variable_declarators
- (variable_declarators_opt
- ( punctuation "," variable_declarators)
- ()
- ) ; end variable_declarators_opt
- (variable_declarator
- ( variable_declarator_id variable_assign_opt
- ,(semantic-lambda
- (nth 0 vals)))
- ) ; end variable_declarator
- (variable_assign_opt
- ( punctuation "=" variable_initializer)
- ()
- ) ; end variable_assign_opt
- (variable_declarator_id
- ( symbol dims
- ,(semantic-lambda
- (list ( concat (nth 0 vals) ( car (nth 1 vals))))))
- ( symbol
- ,(semantic-lambda
- (list (nth 0 vals))))
- ) ; end variable_declarator_id
- (variable_initializer
- ( array_initializer)
- ( expression)
- ) ; end variable_initializer
- (method_declaration
- ( method_header method_body
- ,(semantic-lambda
- (nth 0 vals)))
- ) ; end method_declaration
- (method_header
- ( modifiers_opt method_type symbol formal_parameter_list_opt throws_opt
- ,(semantic-lambda
- (list (nth 2 vals) 'function) (nth 1 vals) (list (nth 3 vals) (nth 0 vals)
(nth 4 vals) nil)))
- ) ; end method_header
- (method_type
- ( VOID
- ,(semantic-lambda
- (list (nth 0 vals))))
- ( type
- ,(semantic-lambda
- (nth 0 vals)))
- ) ; end method_type
- (formal_parameter_list_opt
- ( semantic-list
- ,(lambda (vals start end)
-
- (semantic-bovinate-from-nonterminal (car (nth 0 vals)) (cdr (nth 0 vals))
'formal_parameter_list)
- ))
- ) ; end formal_parameter_list_opt
- (formal_parameter_list
- ( open-paren "(" close-paren ")"
- ,(semantic-lambda
- (list nil)))
- ( open-paren "(" formal_parameter formal_parameter_list_next
- ,(semantic-lambda
- ( cons (nth 1 vals) (nth 2 vals))))
- ) ; end formal_parameter_list
- (formal_parameter_list_next
- ( close-paren ")"
- ,(semantic-lambda
- (list nil)))
- ( punctuation "," formal_parameter formal_parameter_list_next
- ,(semantic-lambda
- ( cons (nth 1 vals) (nth 2 vals))))
- ) ; end formal_parameter_list_next
- (formal_parameter-modifier
- ( FINAL)
- ()
- ) ; end formal_parameter-modifier
- (formal_parameter
- ( formal_parameter-modifier type variable_declarator_id
- ,(semantic-lambda
- (list ( car (nth 2 vals)) 'variable ( car (nth 1 vals)) nil nil (nth 0 vals)
nil)))
- ) ; end formal_parameter
- (throws_opt
- ( throws
- ,(semantic-lambda
- (nth 0 vals)))
- ()
- ) ; end throws_opt
- (throws
- ( THROWS qualified_name_list
- ,(semantic-lambda
- (nth 1 vals)))
- ) ; end throws
- (method_body
- ( punctuation ";"
- ,(semantic-lambda
- (list nil)))
- ( block
- ,(semantic-lambda
- (list nil)))
- ) ; end method_body
- (constructor_declaration
- ( modifiers_opt symbol formal_parameter_list_opt throws_opt constructor_body
- ,(semantic-lambda
- (list (nth 1 vals) 'function nil (nth 2 vals) (nth 0 vals) (nth 3 vals)
nil)))
- ) ; end constructor_declaration
- (constructor_body
- ( block
- ,(semantic-lambda
- (list nil)))
- ) ; end constructor_body
- (interface_declaration
- ( modifiers_opt INTERFACE symbol interface_parents interface_body
- ,(semantic-lambda
- (list (nth 2 vals) 'type "interface" (nth 4 vals) (nth 3 vals)
(nth 0 vals) nil)))
- ) ; end interface_declaration
- (interface_parents
- ( EXTENDS qualified_name_list
- ,(semantic-lambda
- (nth 1 vals)))
- ()
- ) ; end interface_parents
- (interface_body
- ( semantic-list
- ,(semantic-lambda
-
- (semantic-bovinate-from-nonterminal-full (car (nth 0 vals)) (cdr (nth 0 vals))
'interface_body_declarations)
- ))
- ) ; end interface_body
- (interface_body_declarations
- ( class_declaration
- ,(semantic-lambda
- (nth 0 vals)))
- ( interface_declaration
- ,(semantic-lambda
- (nth 0 vals)))
- ( method_header punctuation ";"
- ,(semantic-lambda
- (nth 0 vals)))
- ( field_declaration
- ,(semantic-lambda
- (nth 0 vals)))
- ) ; end interface_body_declarations
- (array_initializer
- ( semantic-list "\\`{")
- ) ; end array_initializer
- (block
- ( semantic-list "\\`{")
- ) ; end block
- (primary
- ( array_creation_expression)
- ( primary_no_new_array primary_dim_opt)
- ) ; end primary
- (primary_dim_opt
- ( semantic-list "\\`\\[")
- ()
- ) ; end primary_dim_opt
- (primary_no_new_array
- ( qualified_name semantic-list "\\`(")
- ( class_instance_creation_expression)
- ( semantic-list "\\`(")
- ( array_type punctuation "\\." CLASS)
- ( literal)
- ) ; end primary_no_new_array
- (class_instance_creation_expression
- ( NEW qualified_name semantic-list "\\`(" semantic-list
"\\`{")
- ( NEW qualified_name semantic-list "\\`(")
- ) ; end class_instance_creation_expression
- (array_creation_expression
- ( NEW qualified_name dims array_initializer)
- ( NEW qualified_name dims)
- ) ; end array_creation_expression
- (dims_opt
- ( dims
- ,(semantic-lambda
- (nth 0 vals)))
- (
- ,(semantic-lambda
- (list nil)))
- ) ; end dims_opt
- (dims
- ( semantic-list "\\`\\[" dims_opt
- ,(semantic-lambda
- (list ( concat "[]" ( car (nth 1 vals))))))
- ) ; end dims
- (field_access
- ( primary punctuation "\\." symbol)
- ( qualified_name)
- ) ; end field_access
- (postfix_expression
- ( primary postfix_operator_opt)
- ) ; end postfix_expression
- (postfix_operator_opt
- ( punctuation "[-+]" punctuation "[-+]")
- ()
- ) ; end postfix_operator_opt
- (unary_expression
- ( punctuation "[-+^!]" unary_expression)
- ( punctuation "[-+]" punctuation "[-+]" unary_expression)
- ( semantic-list "\\`(" unary_expression)
- ( postfix_expression)
- ) ; end unary_expression
- (operator
- ( punctuation "[-+*/%=<>^~&|!?:.]")
- ( INSTANCEOF)
- ) ; end operator
- (operators
- ( operator operators)
- ( operator)
- ) ; end operators
- (operators_expression_opt
- ( operators expression)
- ()
- ) ; end operators_expression_opt
- (expression
- ( unary_expression operators_expression_opt)
- ) ; end expression
- )
- "Grammar used by the semantic library to parse Java source
-buffers. This grammar is a Lisp version of the BNF grammar stored in
-java.bnf. The Lisp grammar is generated automatically from the BNF
-source. For this reason, you should never modify this variable
-directly. See `bovinate' for more information.")
-
-;;; david(a)dponce.com
-(defvar jde-parse-bovine-java-keywords
- (semantic-flex-make-keyword-table
- `( ("abstract" . ABSTRACT)
- ("boolean" . BOOLEAN)
- ("break" . BREAK)
- ("byte" . BYTE)
- ("case" . CASE)
- ("catch" . CATCH)
- ("char" . CHAR)
- ("class" . CLASS)
- ("const" . CONST)
- ("continue" . CONTINUE)
- ("default" . DEFAULT)
- ("do" . DO)
- ("double" . DOUBLE)
- ("else" . ELSE)
- ("extends" . EXTENDS)
- ("final" . FINAL)
- ("finally" . FINALLY)
- ("float" . FLOAT)
- ("for" . FOR)
- ("goto" . GOTO)
- ("if" . IF)
- ("implements" . IMPLEMENTS)
- ("import" . IMPORT)
- ("instanceof" . INSTANCEOF)
- ("int" . INT)
- ("interface" . INTERFACE)
- ("long" . LONG)
- ("native" . NATIVE)
- ("new" . NEW)
- ("package" . PACKAGE)
- ("private" . PRIVATE)
- ("protected" . PROTECTED)
- ("public" . PUBLIC)
- ("return" . RETURN)
- ("short" . SHORT)
- ("static" . STATIC)
- ("strictfp" . STRICTFP)
- ("super" . SUPER)
- ("switch" . SWITCH)
- ("synchronized" . SYNCHRONIZED)
- ("this" . THIS)
- ("throw" . THROW)
- ("throws" . THROWS)
- ("transient" . TRANSIENT)
- ("try" . TRY)
- ("void" . VOID)
- ("volatile" . VOLATILE)
- ("while" . WHILE)
- ))
- "Table of Java grammar keywords. Generated automatically from the
-BNF source.")
+(require 'semantic-java)
-;;; david(a)dponce.com
(defun jde-parse-semantic-default-setup ()
"Setup the semantic bovinator for the JDE."
-;;; WARNING: the following code is automatically generated from the
-;;; BNF source. Do not modify it here! Update the BNF source
-;;; instead. See `bovinate' for more information.
- ;; Code generated from java-with-tokens.bnf
- (setq semantic-toplevel-bovine-table jde-parse-bovine-java-grammar)
- (setq semantic-flex-keywords-obarray jde-parse-bovine-java-keywords)
- (progn
- ;; Java is case sensitive
- (setq semantic-case-fold nil)
- ;; imenu & speedbar setup
- (jde-imenu-setup)
- ;; initial parsing of the current buffer
- (semantic-bovinate-toplevel)
- (jde-parse-update-after-parse)
- )
-;; End code generated from java-with-tokens.bnf
-)
+ ;; Set up the buffer for semantic parsing of the Java language.
+ ;; The following is automatically done in parent `java-mode-hook'.
+ ;;(semantic-default-java-setup)
+
+ ;; imenu & speedbar setup
+ (jde-imenu-setup)
+
+ ;; initial parsing of the current buffer
+ (semantic-bovinate-toplevel)
+ (jde-parse-update-after-parse)
+ )
+
(provide 'jde-java-grammar)
+;;; Change History:
+
;; $Log: jde-java-grammar.el,v $
-;; Revision 1.2 2001/02/22 12:45:16 youngs
-;; Fix problem with building JDE and xslt-process
+;; Revision 1.4 2001/05/19 02:35:59 paulk
+;; Updated to support semantic 1.4. Thanks to David Ponce.
;;
-;; Revision 1.1 2001/02/12 05:48:27 paulk
-;; Initial XEmacs revision.
+;; Revision 1.3 2001/02/21 05:55:38 paulk
+;; Added require for semantic package.
;;
;; Revision 1.2 2001/01/25 05:38:39 paulk
;; Changed the definition of formal_parameter_list to improve performance (less
@@ -510,4 +60,4 @@
;; Initial revision.
;;
-;; End of jde-java-grammar.el
+;; End of jde-java-grammar.el
\ No newline at end of file
Index: xemacs-packages/jde/lisp/jde-javadoc-gen.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/jde-javadoc-gen.el,v
retrieving revision 1.1
diff -u -r1.1 jde-javadoc-gen.el
--- xemacs-packages/jde/lisp/jde-javadoc-gen.el 2001/02/12 05:50:15 1.1
+++ xemacs-packages/jde/lisp/jde-javadoc-gen.el 2001/08/15 05:27:59
@@ -1,5 +1,5 @@
;;; jde-javadoc-gen.el -- Javadoc builder
-;; $Revision: 1.1 $
+;; $Revision: 1.6 $
;; Author: Sergey A Klibanov <sakliban(a)cs.wustl.edu>
;; Maintainer: Paul Kinnucan, Sergey A Klibanov
@@ -293,18 +293,17 @@
(concat
arguments " "
(jde-build-classpath-arg
- jde-global-classpath jde-quote-classpath))))
+ 'jde-global-classpath jde-quote-classpath))))
;; Insert sourcepath
(if jde-db-source-directories
(setq arguments
(concat
- arguments
- (format " -sourcepath \"%s\""
- (mapconcat
- (lambda (path) path)
- jde-db-source-directories
- path-separator)))))
+ arguments " "
+ (jde-build-path-arg
+ "-sourcepath "
+ 'jde-db-source-directories
+ jde-quote-classpath))))
;; Insert bootclasspath
@@ -314,7 +313,7 @@
arguments " "
(jde-build-path-arg
"-bootclasspath "
- jde-compile-option-bootclasspath
+ 'jde-compile-option-bootclasspath
jde-quote-classpath))))
;; Insert extdirs
@@ -322,9 +321,9 @@
(setq arguments
(concat
arguments " "
- (jde-build-path-art
+ (jde-build-path-arg
"-extdirs "
- jde-compile-option-extdirs
+ 'jde-compile-option-extdirs
jde-quote-classpath))))
;; Insert windowtitle
@@ -367,14 +366,14 @@
(setq arguments
(concat
arguments " -helpfile \""
- jde-javadoc-gen-helpfile "\" ")))
+ (jde-normalize-path 'jde-javadoc-gen-helpfile) "\" ")))
;; Insert stylesheet
(if (not (equal "" jde-javadoc-gen-stylesheetfile))
(setq arguments
(concat
arguments " -stylesheetfile \""
- jde-javadoc-gen-stylesheetfile "\" ")))
+ (jde-normalize-path 'jde-javadoc-gen-stylesheetfile) "\"
")))
;; Insert -overview
(if (not (equal "" jde-javadoc-gen-overview))
@@ -397,7 +396,7 @@
arguments " "
(jde-build-path-arg
"-docletpath "
- jde-javadoc-gen-docletpath
+ 'jde-javadoc-gen-docletpath
jde-quote-classpath))))
;; Inser -use
@@ -490,7 +489,7 @@
(lambda (packagename) (format "%s" packagename))
jde-javadoc-gen-packages " ")))
(setq arguments
- (concat arguments " " (buffer-file-name))))
+ (concat arguments " \"" (buffer-file-name) "\"")))
(setq compilation-finish-function
(lambda (buf msg)
@@ -499,7 +498,7 @@
jde-javadoc-display-doc
(string-match "finished" msg))
(browse-url-of-file
- (concat jde-javadoc-gen-destination-directory "/index.html")))))
+ (expand-file-name "index.html" jde-javadoc-gen-destination-directory)))))
(compile-internal arguments "No errors now!")))
@@ -507,8 +506,17 @@
;;
;; $Log: jde-javadoc-gen.el,v $
-;; Revision 1.1 2001/02/12 05:50:15 paulk
-;; Initial XEmacs revision.
+;; Revision 1.6 2001/04/16 05:56:42 paulk
+;; Normalize paths. Thanks to Nick Sieger.
+;;
+;; Revision 1.5 2001/04/11 03:19:43 paulk
+;; Updated to resolve relative paths relative to the project file that defines them.
Thanks to Nick Sieger.
+;;
+;; Revision 1.4 2001/03/22 18:51:33 paulk
+;; Quote buffer path argument on command line to accommodate paths with spaces in them as
permitted on Windows. Thanks to "Jeffrey Phillips"
<jeffrey.phillips(a)staffeon.com> for reporting this problem and providing a fix.
+;;
+;; Revision 1.3 2001/03/01 04:23:28 paulk
+;; Fixed incorrect generation of javadoc index path in jde-javadoc-make function.
"William G. Griswold" <wgg(a)cs.ucsd.edu> for this fix.
;;
;; Revision 1.2 2001/01/27 05:53:38 paulk
;; No longer inserts -sourcepath argument twice in the javadoc command line.
Index: xemacs-packages/jde/lisp/jde-javadoc.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/jde-javadoc.el,v
retrieving revision 1.2
diff -u -r1.2 jde-javadoc.el
--- xemacs-packages/jde/lisp/jde-javadoc.el 2001/02/12 05:38:25 1.2
+++ xemacs-packages/jde/lisp/jde-javadoc.el 2001/08/15 05:28:00
@@ -1,5 +1,5 @@
;;; jde-javadoc.el --- JDE javadoc autodoc
-;; $Revision: 1.2 $
+;; $Revision: 1.18 $
;; Copyright (C) 1998, 2000, 2001 by David Ponce
@@ -28,8 +28,8 @@
;;; Commentary:
;;
-;; This library provides a doc comment generator to help source
-;; documentation
+;; This library provides a javadoc comment checker and generator to
+;; help handling of Java source documentation.
;;; History:
;;
@@ -37,7 +37,7 @@
;;; Code:
(require 'tempo)
-(require 'semantic)
+(require 'semantic-java)
;;;; Customization
;;;; -------------
@@ -47,8 +47,8 @@
:group 'jde
:prefix "jde-javadoc-")
-;; IMPORTANT: This function must be defined before the following defcustoms
-;; because it is used in their :set clause.
+;; IMPORTANT: This function must be defined before the following
+;; defcustoms because it is used in their :set clause.
(defun jde-javadoc-define-template (sym val)
"Define a template (see `tempo-define-template').
The template name is the `symbol-name' of SYM from which the
@@ -97,9 +97,9 @@
"\"* Creates a new \" (jde-javadoc-code name) \"
instance.\""
"*Line template used to describe a constructor.
If nil the line is not inserted.
-The variable 'name' is set to the constructor name (that is the class name).
-See `jde-javadoc-autodoc-at-line' for usage. Define the template
-variable `tempo-template-jde-javadoc-describe-constructor'."
+The variable 'name' is set to the constructor name (that is the class
+name). See `jde-javadoc-autodoc-at-line' for usage. Define the
+template variable `tempo-template-jde-javadoc-describe-constructor'."
:group 'jde-javadoc
:type '(choice :tag "Template form"
(text :format "%t\n%v" :tag "String")
@@ -192,26 +192,26 @@
(repeat :tag "Lisp Expressions" (sexp :tag "")))
:set 'jde-javadoc-define-template)
-;; (defcustom jde-javadoc-version-tag-template
-;; '("* @version 1.0")
-;; "*Line template used to give a version.
-;; If nil the line is not inserted.
-;; See `jde-javadoc-autodoc-at-line' for usage. Define the template
-;; variable `tempo-template-jde-javadoc-version-tag'."
-;; :group 'jde-javadoc
-;; :type '(choice :tag "Template form"
-;; (text :format "%t\n%v" :tag "String")
-;; (repeat :tag "Lisp Expressions" (sexp :tag
"")))
-;; :set 'jde-javadoc-define-template)
+(defcustom jde-javadoc-version-tag-template
+ "\"* @version 1.0\""
+ "*Line template used to give a version.
+If nil the line is not inserted.
+See `jde-javadoc-autodoc-at-line' for usage. Define the template
+variable `tempo-template-jde-javadoc-version-tag'."
+ :group 'jde-javadoc
+ :type '(choice :tag "Template form"
+ (text :format "%t\n%v" :tag "String")
+ (repeat :tag "Lisp Expressions" (sexp :tag "")))
+ :set 'jde-javadoc-define-template)
;; (defcustom jde-javadoc-see-tag-template
;; '("* @see " ref)
;; "*Line template used to give a reference.
;; If nil the line is not inserted.
;; The variable 'ref' is set to the class or interface name.
-;; A line is inserted for each name in the 'extends' then 'implements'
clauses.
-;; See `jde-javadoc-autodoc-at-line' for usage. Define the template
-;; variable `tempo-template-jde-javadoc-see-tag'."
+;; A line is inserted for each name in the 'extends' then 'implements'
+;; clauses. See `jde-javadoc-autodoc-at-line' for usage. Define the
+;; template variable `tempo-template-jde-javadoc-see-tag'."
;; :group 'jde-javadoc
;; :type '(choice :tag "Template form"
;; (text :format "%t\n%v" :tag "String")
@@ -259,13 +259,8 @@
(and working-message
(apply #'working-dynamic-status args)))
-(defmacro jde-javadoc-skip-spaces-backward ()
- "Move point backward, skipping Java whitespaces."
- `(skip-chars-backward " \n\r\t"))
-
-(defmacro jde-javadoc-skip-spaces-forward ()
- "Move point forward, skipping Java whitespaces."
- `(skip-chars-forward " \n\r\t"))
+(defalias 'jde-javadoc-skip-spaces-forward
+ 'semantic-java-skip-spaces-forward)
(defalias 'jde-javadoc-indent-line 'c-indent-line)
@@ -315,6 +310,13 @@
(setq lines window-min-height))
(enlarge-window (- lines height)))))
+(defsubst jde-javadoc-variable-name (name)
+ "Return canonical variable name from NAME.
+That is strip any array brackets from NAME."
+ (if (string-match "\\`\\([^[]+\\)[[]" name)
+ (match-string 1 name)
+ name))
+
;;;; Text helpers
;;;; ------------
@@ -341,37 +343,8 @@
;;;; Javadoc comment parser
;;;; ----------------------
-;; tags and matchers
+;; tags and matchers (many are provided by Semantic)
;;
-(defconst jde-javadoc-line-tags
- (list
- "author"
- "version"
- "param"
- "return"
- "exception"
- "throws"
- "see"
- "since"
- "serial"
- "serialData"
- "serialField"
- "deprecated"
- )
- "Valid javadoc line tags.
-Ordered following Sun's Tag Convention at
-<http://java.sun.com/products/jdk/javadoc/writingdoccomments/index.html>")
-
-(defconst jde-javadoc-with-name-tags
- (list "exception"
- "param"
- "throws")
- "Javadoc tags which have a name.")
-
-(defconst jde-javadoc-with-ref-tags
- (list "see")
- "Javadoc tags which have a reference.")
-
(defconst jde-javadoc-desc-tag
"*DESCRIPTION*"
"Special internal tag associated to descriptions.")
@@ -385,71 +358,6 @@
"\\|[ \n\r\t]*\\*/\\)")
"Regexp matching the end of a tag or description.")
-;; Optional javadoc tags by token category
-;;
-(defconst jde-javadoc-extra-type-tags
- (list
- "version"
- "see"
- "since"
- "deprecated"
- )
- "Optional tags used in class/interface documentation.
-Ordered following Sun's Tag Convention.")
-
-(defconst jde-javadoc-extra-function-tags
- (list
- "see"
- "since"
- "serialData"
- "deprecated"
- )
- "Optional tags used in method/constructor documentation.
-Ordered following Sun's Tag Convention.")
-
-(defconst jde-javadoc-extra-variable-tags
- (list
- "see"
- "since"
- "serial"
- "serialField"
- "deprecated"
- )
- "Optional tags used in field documentation.
-Ordered following Sun's Tag Convention.")
-
-;; All javadoc tags by token category
-;;
-(defconst jde-javadoc-type-tags
- (append
- (list
- "author"
- )
- jde-javadoc-extra-type-tags)
- "Tags allowed in class/interface documentation.
-Ordered following Sun's Tag Convention.")
-
-(defconst jde-javadoc-function-tags
- (append
- (list
- "param"
- "return"
- "exception"
- "throws"
- )
- jde-javadoc-extra-function-tags)
- "Tags allowed in method/constructor documentation.
-Ordered following Sun's Tag Convention.")
-
-(defconst jde-javadoc-variable-tags
- (append
- (list
- ;; No tag required
- )
- jde-javadoc-extra-function-tags)
- "Tags allowed in field documentation.
-Ordered following Sun's Tag Convention.")
-
;; Core comment parser
;;
(defun jde-javadoc-normalize-description (desc)
@@ -504,11 +412,13 @@
(while (string-match matcher docstring i)
(jde-javadoc-dynamic-status)
(setq j (match-end 0))
- (setq i (or (string-match jde-javadoc-end-tag-regexp docstring j)
+ (setq i (or (string-match
+ jde-javadoc-end-tag-regexp docstring j)
(length docstring)))
(setq tag-val (substring docstring j i))
(cond ((eq with-key 'name)
- (setq key (and (string-match "[* \n\r\t]*\\([^ \n\r\t]+\\)"
tag-val)
+ (setq key (and (string-match
+ "[* \n\r\t]*\\([^ \n\r\t]+\\)" tag-val)
(match-string 1 tag-val))))
((eq with-key 'ref)
(setq key (jde-javadoc-normalize-ref tag-val))))
@@ -521,9 +431,9 @@
`jde-javadoc-parse-tag-values'."
(cond ((string-equal tag jde-javadoc-desc-tag)
(jde-javadoc-parse-description docstring))
- ((member tag jde-javadoc-with-name-tags)
+ ((member tag semantic-java-doc-with-name-tags)
(jde-javadoc-parse-tag-values docstring tag 'name))
- ((member tag jde-javadoc-with-ref-tags)
+ ((member tag semantic-java-doc-with-ref-tags)
(jde-javadoc-parse-tag-values docstring tag 'ref))
(t
(jde-javadoc-parse-tag-values docstring tag))
@@ -546,7 +456,9 @@
"Return the parsed documentation tree from DOCSTRING.
Result has the following form: (DOCSTRING TAG-LIST TAG-VALUE-ALIST)."
(if docstring
- (let (tag-list tag-alist l tag throws-assoc except-assoc merged-values)
+ (let (tag-list
+ tag-alist l tag
+ throws-assoc except-assoc merged-values)
(jde-javadoc-status-forms "Parsing" "done"
(jde-javadoc-dynamic-status)
(setq tag-list (jde-javadoc-parse-tag-list docstring))
@@ -561,24 +473,27 @@
(jde-javadoc-parse-tag tag docstring))
tag-alist)))
(setq l (cdr l)))
- ;; The 'throws' and 'exception' tags are equivalent, so their
- ;; values are merged to allow access to 'exception' tag using
- ;; 'throws' and vice versa.
+ ;; The 'throws' and 'exception' tags are equivalent, so
+ ;; their values are merged to allow access to 'exception'
+ ;; tag using 'throws' and vice versa.
(jde-javadoc-dynamic-status)
(setq throws-assoc (assoc "throws" tag-alist))
(jde-javadoc-dynamic-status)
(setq except-assoc (assoc "exception" tag-alist))
(when (or throws-assoc except-assoc)
(jde-javadoc-dynamic-status)
- (setq merged-values (append (cdr throws-assoc) (cdr except-assoc)))
+ (setq merged-values (append (cdr throws-assoc)
+ (cdr except-assoc)))
(jde-javadoc-dynamic-status)
(if throws-assoc
(setcdr throws-assoc merged-values)
- (setq tag-alist (cons (cons "throws" merged-values)
tag-alist)))
+ (setq tag-alist (cons (cons "throws" merged-values)
+ tag-alist)))
(jde-javadoc-dynamic-status)
(if except-assoc
(setcdr except-assoc merged-values)
- (setq tag-alist (cons (cons "exception" merged-values)
tag-alist))))
+ (setq tag-alist (cons (cons "exception" merged-values)
+ tag-alist))))
(jde-javadoc-dynamic-status t))
(list docstring tag-list tag-alist))))
@@ -600,8 +515,9 @@
"Return from DOCTREE the list of TAG values.
If optional NAME is non-nil return its specific value."
(let ((doc (cdr
- (assoc tag
- (jde-javadoc-doctree-tag-value-alist doctree)))))
+ (assoc
+ tag
+ (jde-javadoc-doctree-tag-value-alist doctree)))))
(and doc
name
(setq doc (rassoc name doc))
@@ -610,77 +526,36 @@
(defun jde-javadoc-doctree-known-tag-list (doctree)
"Return the list of known tags in DOCTREE .
-That is tags in `jde-javadoc-line-tags'."
+That is tags in `semantic-java-doc-line-tags'."
(delq nil
(mapcar (function
(lambda (tag)
- (and (member tag jde-javadoc-line-tags)
+ (and (member tag semantic-java-doc-line-tags)
tag)))
(jde-javadoc-doctree-tag-list doctree))))
(defun jde-javadoc-doctree-unknown-tag-list (doctree)
"Return the list of unknown tags in DOCTREE .
-That is tags not in `jde-javadoc-line-tags'."
+That is tags not in `semantic-java-doc-line-tags'."
(delq nil
(mapcar (function
(lambda (tag)
- (and (not (member tag jde-javadoc-line-tags))
+ (and (not (member tag semantic-java-doc-line-tags))
tag)))
(jde-javadoc-doctree-tag-list doctree))))
;;;; semantic tokens stuff
;;;; ---------------------
-(defun jde-javadoc-find-documentation (&optional token nosnarf)
- "Find documentation from TOKEN and return it as a clean string.
-Java have documentation set in a comment preceeding TOKEN's
-definition. Optional argument NOSNARF means to only return the flex
-token for it. If NOSNARF is 'flex, then only return the flex
-token. See also `semantic-find-documentation'."
- (if (or token (setq token (semantic-current-nonterminal)))
- (save-excursion
- (set-buffer (semantic-token-buffer token))
- ;; Move the point at token start
- (goto-char (semantic-token-start token))
- (jde-javadoc-skip-spaces-forward)
- ;; If the point already at "/**" (this occurs after a doc fix)
- (if (looking-at "/\\*\\*")
- nil
- ;; Skip previous spaces...
- (jde-javadoc-skip-spaces-backward)
- ;; Verify the point is after "*/" (javadoc block comment end)
- (condition-case nil
- (backward-char 2)
- (error nil))
- (when (looking-at "\\*/")
- ;; Move the point backward across the comment
- (forward-char 2) ; return just after "*/"
- (forward-comment -1) ; to skip the entire block
- ))
- ;; Verify the point is at "/**" (javadoc block comment start)
- (if (looking-at "/\\*\\*")
- (let ((p (point))
- (c (semantic-find-doc-snarf-comment 'flex)))
- (when c
- ;; Verify that the token just following the doc comment is
- ;; the current one!
- (goto-char (semantic-flex-end c))
- (jde-javadoc-skip-spaces-forward)
- (if (eq token (semantic-current-nonterminal))
- (if (eq nosnarf 'flex)
- c
- (goto-char p)
- (semantic-find-doc-snarf-comment nosnarf)))))))))
-
(defun jde-javadoc-token-doctree (token)
"Return the parsed documentation tree from TOKEN."
(jde-javadoc-parse-docstring
- (jde-javadoc-find-documentation token t)))
+ (semantic-find-documentation token t)))
(defun jde-javadoc-replace-documentation (token &optional docstring)
"Replace TOKEN documentation with DOCSTRING.
If DOCSTRING is nil just delete the existing documentation."
- (let* ((comment (jde-javadoc-find-documentation token 'flex))
+ (let* ((comment (semantic-find-documentation token 'flex))
start end)
(when comment
(set-buffer (semantic-token-buffer token))
@@ -709,7 +584,7 @@
(defun jde-javadoc-recenter-documentation (token &optional arg)
"Center TOKEN documentation in window and redisplay frame.
With ARG, put point on line ARG. See also `recenter'."
- (let ((comment (jde-javadoc-find-documentation token 'flex))
+ (let ((comment (semantic-find-documentation token 'flex))
start)
(if (not comment)
(setq start (semantic-token-start token))
@@ -721,7 +596,7 @@
(defun jde-javadoc-indent-documentation (token)
"Indent TOKEN documentation."
(save-excursion
- (let ((comment (jde-javadoc-find-documentation token 'flex))
+ (let ((comment (semantic-find-documentation token 'flex))
start end)
(when comment
(set-buffer (semantic-token-buffer token))
@@ -745,14 +620,23 @@
"Current checked buffer.
Local to checker report buffer.")
+(condition-case nil
+ (require 'jde-java-font-lock)
+ (error nil))
+
(defvar jde-javadoc-checker-report-font-lock-keywords
(list
;; References
(list "`\\(.*\\)'"
- 1 'font-lock-variable-name-face)
+ 1 'font-lock-warning-face)
;; Javadoc tags
(list "\\(@[^ \n\r\t]+\\)"
- 1 'font-lock-constant-face)
+ 1 (cond ((boundp 'jde-java-font-lock-doc-tag-face)
+ 'jde-java-font-lock-doc-tag-face)
+ ((featurep 'xemacs)
+ 'font-lock-keyword-face)
+ (t
+ 'font-lock-constant-face)))
;; Misc.
(list "\\[\\([fnpq]\\)\\]"
1 'font-lock-keyword-face)
@@ -850,30 +734,6 @@
type name count eword)
(nreverse report)))))
-(defvar jde-javadoc-tag-order-alist nil
- "Cached alist of (TAG . ORDER-NO).
-See function `jde-javadoc-ref-tag-order-alist'.")
-
-(defun jde-javadoc-ref-tag-order-alist ()
- "Associate each tag in `jde-javadoc-line-tags' with an order number.
-The result is cached in variable `jde-javadoc-tag-order-alist'."
- (or jde-javadoc-tag-order-alist
- (setq jde-javadoc-tag-order-alist
- (let ((l jde-javadoc-line-tags)
- (i 1)
- alist)
- (while l
- (jde-javadoc-dynamic-status)
- (setq alist (cons (cons (car l) i) alist)
- i (1+ i)
- l (cdr l)))
- alist))))
-
-(defmacro jde-javadoc-tag-order (tag)
- "Return TAG order number."
- `(or (cdr (assoc ,tag (jde-javadoc-ref-tag-order-alist)))
- 0))
-
;; Basic doc checkers
;;
(defun jde-javadoc-check-description (doctree)
@@ -882,40 +742,79 @@
nil
"Missing description"))
+(defun jde-javadoc-check-required-tags (doctree allowed extra
+ &rest nocheck)
+ "Return a message if DOCTREE is missing a required tag.
+ALLOWED and EXTRA are respectively the listes of allowed tags and
+optional ones. Optional arguments NOCHECK can be a listes of tags
+that are not checked."
+ (let (tag missing)
+ (while allowed
+ (setq tag (car allowed)
+ allowed (cdr allowed))
+ (or (member tag extra)
+ (member tag nocheck)
+ (let ((ignored nocheck) ignore)
+ (while (and (not ignore) ignored)
+ (setq ignore (member tag (car ignored))
+ ignored (cdr ignored)))
+ ignore)
+;; (member tag semantic-java-doc-with-name-tags)
+ (jde-javadoc-doctree-tag doctree tag)
+ (setq missing (cons tag missing))))
+ (if missing
+ (concat "Missing tag"
+ (if (> (length missing) 1) "s @" " @")
+ (mapconcat 'identity missing ", @")))))
+
+(defun jde-javadoc-check-suggest-tag-order (tag-list reference)
+ "Return a list of tags in suggested order from TAG-LIST.
+REFERENCE is the list of tags allowed."
+ (let (otl utl)
+ (while tag-list
+ (if (member (car tag-list) semantic-java-doc-line-tags)
+ (and (member (car tag-list) reference)
+ (add-to-list 'otl (car tag-list)))
+ (add-to-list 'utl (car tag-list)))
+ (setq tag-list (cdr tag-list)))
+ (append (sort otl #'semantic-java-doc-keyword-before-p)
+ (nreverse utl))))
+
(defun jde-javadoc-check-tag-ordered (doctree reference)
"Return a message if tags in DOCTREE are not correctly ordered.
REFERENCE is the list of allowed tags in correct order. See variable
-`jde-javadoc-line-tags'."
- (let* ((tag-list (jde-javadoc-doctree-known-tag-list doctree))
+`semantic-java-doc-line-tags'."
+ (let* ((tag-list (jde-javadoc-doctree-tag-list doctree))
(tag (car tag-list))
(l (cdr tag-list))
(ok t))
(while (and l ok)
(jde-javadoc-dynamic-status)
- (setq ok (<= (jde-javadoc-tag-order tag)
- (jde-javadoc-tag-order (car l)))
+ (setq ok (semantic-java-doc-keyword-before-p tag (car l))
tag (car l)
l (cdr l)))
(if ok
nil
(concat "Recommended tag order is @"
(mapconcat 'identity
- reference
+ (jde-javadoc-check-suggest-tag-order
+ tag-list reference)
", @")))))
(defun jde-javadoc-check-tag-allowed (doctree allowed)
"Return a message if some tags in DOCTREE are not in ALLOWED.
-Third party tags (not in `jde-javadoc-line-tags') are allways
+Third party tags (not in `semantic-java-doc-line-tags') are allways
allowed."
(let ((invalids
(delq nil
- (mapcar (function
- (lambda (tag)
- (jde-javadoc-dynamic-status)
- (and (member tag jde-javadoc-line-tags)
- (not (member tag allowed))
- tag)))
- (jde-javadoc-doctree-tag-list doctree)))))
+ (mapcar
+ (function
+ (lambda (tag)
+ (jde-javadoc-dynamic-status)
+ (and (member tag semantic-java-doc-line-tags)
+ (not (member tag allowed))
+ tag)))
+ (jde-javadoc-doctree-tag-list doctree)))))
(if (not invalids)
nil
(concat "Invalid tag"
@@ -930,6 +829,7 @@
errors were found."
(let ((name (semantic-token-name token))
(type (semantic-token-type token))
+ (main (jde-javadoc-checker-main-type-p token))
report)
;; Check for missing description
(jde-javadoc-dynamic-status)
@@ -937,17 +837,31 @@
(cons
(jde-javadoc-check-description doctree)
report))
+ ;; Check for missing tags
+ (jde-javadoc-dynamic-status)
+ (setq report
+ (cons
+ (jde-javadoc-check-required-tags
+ doctree semantic-java-doc-type-tags
+ semantic-java-doc-extra-type-tags
+ (if main
+ nil
+ ;; Don't check these tags if internal type.
+ '("author" "version" "since")))
+ report))
;; Check for incorrect tag order
(jde-javadoc-dynamic-status)
(setq report
(cons
- (jde-javadoc-check-tag-ordered doctree jde-javadoc-type-tags)
+ (jde-javadoc-check-tag-ordered
+ doctree semantic-java-doc-type-tags)
report))
;; Check for invalid tags
(jde-javadoc-dynamic-status)
(setq report
(cons
- (jde-javadoc-check-tag-allowed doctree jde-javadoc-type-tags)
+ (jde-javadoc-check-tag-allowed
+ doctree semantic-java-doc-type-tags)
report))
;; Setup the error summary
(jde-javadoc-dynamic-status)
@@ -965,17 +879,27 @@
(cons
(jde-javadoc-check-description doctree)
report))
+ ;; Check for missing tags
+ (jde-javadoc-dynamic-status)
+ (setq report
+ (cons
+ (jde-javadoc-check-required-tags
+ doctree semantic-java-doc-variable-tags
+ semantic-java-doc-extra-variable-tags)
+ report))
;; Check for incorrect tag order
(jde-javadoc-dynamic-status)
(setq report
(cons
- (jde-javadoc-check-tag-ordered doctree jde-javadoc-variable-tags)
+ (jde-javadoc-check-tag-ordered
+ doctree semantic-java-doc-variable-tags)
report))
;; Check for invalid tags
(jde-javadoc-dynamic-status)
(setq report
(cons
- (jde-javadoc-check-tag-allowed doctree jde-javadoc-variable-tags)
+ (jde-javadoc-check-tag-allowed
+ doctree semantic-java-doc-variable-tags)
report))
;; Setup the error summary
(jde-javadoc-dynamic-status)
@@ -996,23 +920,36 @@
(cons
(jde-javadoc-check-description doctree)
report))
+ ;; Check for missing tags
+ (jde-javadoc-dynamic-status)
+ (setq report
+ (cons
+ (jde-javadoc-check-required-tags
+ doctree semantic-java-doc-function-tags
+ semantic-java-doc-extra-function-tags
+ ;; Don't check return, param and exception/throws tags.
+ '("return") semantic-java-doc-with-name-tags)
+ report))
;; Check for missing @param tags
(setq items nil)
(while args
(jde-javadoc-dynamic-status)
(if (semantic-token-p (car args))
(progn
- (setq item (semantic-token-name (car args)))
+ (setq item (jde-javadoc-variable-name
+ (semantic-token-name (car args))))
(setq items (cons item items))
(or (jde-javadoc-doctree-tag doctree "param" item)
- (setq report (cons (format "Missing @param tag for `%s'"
item)
- report)))))
+ (setq report
+ (cons
+ (format "Missing @param tag for `%s'" item)
+ report)))))
(setq args (cdr args)))
;; Check for extra @param tags
(setq args (jde-javadoc-doctree-tag doctree "param"))
(while args
(jde-javadoc-dynamic-status)
- (setq item (cdr (car args)))
+ (setq item (jde-javadoc-variable-name (cdr (car args))))
(or (member item items)
(setq report (cons (format "Invalid @param tag `%s'" item)
report)))
@@ -1025,8 +962,10 @@
(setq items (cons item items))
(setq throws (cdr throws))
(or (jde-javadoc-doctree-tag doctree "exception" item)
- (setq report (cons (format "Missing @exception tag for `%s'"
item)
- report))))
+ (setq report
+ (cons
+ (format "Missing @exception tag for `%s'" item)
+ report))))
;; Check for extra @exception tags
(setq args (jde-javadoc-doctree-tag doctree "exception"))
(while args
@@ -1035,7 +974,9 @@
(or (member item items)
(setq report
(cons
- (format "Extra @exception tag `%s' (maybe not an error)"
item)
+ (format
+ "Extra @exception tag `%s' (maybe not an error)"
+ item)
report)))
(setq args (cdr args)))
;; Check for missing or extra @return tag
@@ -1054,13 +995,15 @@
(jde-javadoc-dynamic-status)
(setq report
(cons
- (jde-javadoc-check-tag-ordered doctree jde-javadoc-function-tags)
+ (jde-javadoc-check-tag-ordered
+ doctree semantic-java-doc-function-tags)
report))
;; Check for invalid tags
(jde-javadoc-dynamic-status)
(setq report
(cons
- (jde-javadoc-check-tag-allowed doctree jde-javadoc-function-tags)
+ (jde-javadoc-check-tag-allowed
+ doctree semantic-java-doc-function-tags)
report))
;; Setup the error summary
(jde-javadoc-dynamic-status)
@@ -1139,13 +1082,13 @@
(semantic-token-type-modifiers token))
((eq categ 'function)
(if (string-equal last-type "interface")
- (list "public") ; interface members are always public
+ (list "public") ;; interface members are always public
(semantic-token-function-modifiers token)))
((eq categ 'variable)
(if (string-equal last-type "interface")
- (list "public") ; interface members are always public
+ (list "public") ;; interface members are always public
(semantic-token-variable-modifiers token)))
- (t ; must never occurs
+ (t ;; must never occurs
(error "Invalid %s token" categ))))
(setq levels
(cons (cond ((member "public" modifiers)
@@ -1172,7 +1115,16 @@
(jde-javadoc-token-access-level token)
level)))))
-(defun jde-javadoc-checker-do-find-previous-token (tokens &optional token prev)
+(defun jde-javadoc-checker-main-type-p (&optional token)
+ "Return non-nil if TOKEN is a main type one.
+That is not an internal class or interface."
+ (setq token (or token (semantic-current-nonterminal)))
+ (and (eq (semantic-token-token token) 'type)
+ (memq token (semantic-find-nonterminal-by-token
+ 'type (current-buffer)))))
+
+(defun jde-javadoc-checker-do-find-previous-token (tokens &optional
+ token prev)
"Visit TOKENS and return the token before TOKEN.
PREV is the last token visited or nil at start. If TOKEN is nil
return the last token found. Return only a 'type 'function or
@@ -1200,7 +1152,8 @@
))
prev))
-(defun jde-javadoc-checker-find-previous-token (tokens &optional token)
+(defun jde-javadoc-checker-find-previous-token (tokens
+ &optional token)
"Visit TOKENS and return the token before TOKEN.
If TOKEN is nil return the last token found. Return only a 'type
'function or 'variable token."
@@ -1222,7 +1175,8 @@
(setq next current)
(if (eq categ 'type)
(setq next (jde-javadoc-checker-find-next-token
- (semantic-token-type-parts current) token)))))
+ (semantic-token-type-parts current)
+ token)))))
(setq tokens (cdr tokens)))
next))
@@ -1231,12 +1185,14 @@
Start checking before TOKEN if non-nil or at the last token found."
(pop-to-buffer buffer)
(let* ((tokens (semantic-bovinate-toplevel))
- (prev (jde-javadoc-checker-find-previous-token tokens token))
+ (prev (jde-javadoc-checker-find-previous-token
+ tokens token))
(report (and prev
(jde-javadoc-checker-at-level-p prev)
(jde-javadoc-checker prev t))))
(while (and prev (not report))
- (setq prev (jde-javadoc-checker-find-previous-token tokens prev))
+ (setq prev (jde-javadoc-checker-find-previous-token
+ tokens prev))
(setq report (and prev
(jde-javadoc-checker-at-level-p prev)
(jde-javadoc-checker prev t))))
@@ -1279,8 +1235,8 @@
"Insert the template *NAME* or *TEXTS* and a newline.
If *NAME* value is nil *TEXTS* are inserted if non-nil. If *NAME* and
*TEXTS* are nil the function does nothing.
-The name of variables local to this function are enclosed with \"*\"
-to avoid conflicts with variables used in templates."
+The name of variables local to this function are enclosed between
+\"*\" to avoid conflicts with variables used in templates."
(cond ((and *name* (symbolp *name*) (symbol-value *name*))
(tempo-insert-template *name* nil)
(newline))
@@ -1292,8 +1248,6 @@
;;
(defun jde-javadoc-insert-start-block ()
"Insert a javadoc comment block start '/**' at point."
-;; (delete-region (point) (progn (skip-chars-backward " \t") (point)))
-;; (jde-javadoc-indent-line)
(jde-javadoc-insert nil "/**"))
(defun jde-javadoc-insert-empty-line ()
@@ -1308,7 +1262,8 @@
(defun jde-javadoc-insert-previous-description (doctree)
"Insert a javadoc description if it already exists in DOCTREE."
- (let ((previous (jde-javadoc-doctree-tag doctree jde-javadoc-desc-tag)))
+ (let ((previous (jde-javadoc-doctree-tag
+ doctree jde-javadoc-desc-tag)))
(if previous
(jde-javadoc-insert
nil
@@ -1348,48 +1303,53 @@
;; (defun jde-javadoc-insert-since-tag (doctree)
;; "Insert a javadoc @since tag.
-;; If tag already exists in DOCTREE keep it, else insert a new default one."
+;; If tag already exists in DOCTREE keep it, else insert a new default
+;; one."
;; (or (jde-javadoc-insert-previous-tag doctree "since")
;; (jde-javadoc-insert 'tempo-template-jde-javadoc-since-tag)))
-;; (defun jde-javadoc-insert-version-tag (doctree)
-;; "Insert a javadoc @version tag.
-;; If tag already exists in DOCTREE keep it, else insert a new default one."
-;; (or (jde-javadoc-insert-previous-tag doctree "version")
-;; (jde-javadoc-insert 'tempo-template-jde-javadoc-version-tag)))
+(defun jde-javadoc-insert-version-tag (doctree)
+ "Insert a javadoc @version tag.
+If tag already exists in DOCTREE keep it, else insert a new default
+one."
+ (or (jde-javadoc-insert-previous-tag doctree "version")
+ (jde-javadoc-insert 'tempo-template-jde-javadoc-version-tag)))
;; (defun jde-javadoc-insert-see-tag (doctree refs)
;; "Insert javadoc @see tags.
-;; If tags already exist in DOCTREE keep them, else insert a new default one
-;; for each item in REFS."
+;; If tags already exist in DOCTREE keep them, else insert a new
+;; default one for each item in REFS."
;; (or (jde-javadoc-insert-previous-tag doctree "see")
;; (jde-javadoc-map
;; (function
;; (lambda (ref)
;; (and ref (not (string= ref ""))
-;; (jde-javadoc-insert 'tempo-template-jde-javadoc-see-tag))))
+;; (jde-javadoc-insert
+;; 'tempo-template-jde-javadoc-see-tag))))
;; refs)))
(defun jde-javadoc-insert-param-tag (doctree type name)
"Insert a javadoc @param tag.
-If tag already exists in DOCTREE keep it, else insert a new default one
-using parameter TYPE and NAME."
+If tag already exists in DOCTREE keep it, else insert a new default
+one using parameter TYPE and NAME."
(or (jde-javadoc-insert-previous-tag doctree "param" name)
(and type (not (string= type ""))
name (not (string= name ""))
- (jde-javadoc-insert 'tempo-template-jde-javadoc-param-tag))))
+ (jde-javadoc-insert
+ 'tempo-template-jde-javadoc-param-tag))))
(defun jde-javadoc-insert-exception-tag (doctree types)
"Insert javadoc @exception tags.
-If tags already exist in DOCTREE keep them, else insert a new default one
-for each exception in TYPES."
+If tags already exist in DOCTREE keep them, else insert a new default
+one for each exception in TYPES."
(jde-javadoc-map
(function
(lambda (type)
(jde-javadoc-dynamic-status)
(or (jde-javadoc-insert-previous-tag doctree "exception" type)
(and type (not (string= type ""))
- (jde-javadoc-insert 'tempo-template-jde-javadoc-exception-tag)))))
+ (jde-javadoc-insert
+ 'tempo-template-jde-javadoc-exception-tag)))))
types)
;; Keep extra exception tags (maybe not invalid tags)
(jde-javadoc-map
@@ -1398,21 +1358,23 @@
(jde-javadoc-dynamic-status)
(setq type (cdr type))
(or (member type types)
- (jde-javadoc-insert-previous-tag doctree "exception" type))))
+ (jde-javadoc-insert-previous-tag
+ doctree "exception" type))))
(jde-javadoc-doctree-tag doctree "exception")))
(defun jde-javadoc-insert-return-tag (doctree type)
"Insert a javadoc @return tag.
-If tag already exists in DOCTREE keep it, else insert a new default one
-using return TYPE."
+If tag already exists in DOCTREE keep it, else insert a new default
+one using return TYPE."
(and type (not (string= type "void"))
(or (jde-javadoc-insert-previous-tag doctree "return")
- (jde-javadoc-insert 'tempo-template-jde-javadoc-return-tag))))
+ (jde-javadoc-insert
+ 'tempo-template-jde-javadoc-return-tag))))
(defun jde-javadoc-insert-field-desc (doctree modifiers type name)
"Insert a field description.
-If a description already exists in DOCTREE keep it, else insert a default
-one using field MODIFIERS TYPE and NAME."
+If a description already exists in DOCTREE keep it, else insert a
+default one using field MODIFIERS TYPE and NAME."
(if (jde-javadoc-insert-previous-description doctree)
nil
(jde-javadoc-insert-start-block)
@@ -1421,9 +1383,9 @@
(defun jde-javadoc-insert-function-desc (doctree type name)
"Insert a method or constructor description.
-If a description already exists in DOCTREE keep it, else insert a default
-one using method TYPE and NAME. If TYPE is nil insert a default
-constructor description."
+If a description already exists in DOCTREE keep it, else insert a
+default one using method TYPE and NAME. If TYPE is nil insert a
+default constructor description."
(if (jde-javadoc-insert-previous-description doctree)
nil
(jde-javadoc-insert-start-block)
@@ -1436,8 +1398,8 @@
(defun jde-javadoc-insert-class-desc (doctree name)
"Insert a class description.
-If a description already exists in DOCTREE keep it, else insert a default
-one using class NAME."
+If a description already exists in DOCTREE keep it, else insert a
+default one using class NAME."
(if (jde-javadoc-insert-previous-description doctree)
nil
(jde-javadoc-insert-start-block)
@@ -1446,40 +1408,48 @@
(defun jde-javadoc-insert-interface-desc (doctree name)
"Insert an interface description.
-If a description already exists in DOCTREE keep it, else insert a default
-one using interface NAME."
+If a description already exists in DOCTREE keep it, else insert a
+default one using interface NAME."
(if (jde-javadoc-insert-previous-description doctree)
nil
(jde-javadoc-insert-start-block)
- (jde-javadoc-insert 'tempo-template-jde-javadoc-describe-interface)
+ (jde-javadoc-insert
+ 'tempo-template-jde-javadoc-describe-interface)
(jde-javadoc-insert-empty-line)))
;; Main generators
;;
-(defun jde-javadoc-type-doc (modifiers type name parents &optional doctree)
+(defun jde-javadoc-type-doc (modifiers type name parents main
+ &optional doctree)
"Document a class or interface using MODIFIERS TYPE NAME PARENTS.
+If MAIN is non-nil this is a main class or interface (not internal).
If description and tags already exist in DOCTREE keep them."
;; description
(jde-javadoc-dynamic-status)
(if (string-equal type "interface")
(jde-javadoc-insert-interface-desc doctree name)
(jde-javadoc-insert-class-desc doctree name))
- ;; author
- (jde-javadoc-dynamic-status)
- (jde-javadoc-insert-author-tag doctree)
+ (when main
+ ;; author
+ (jde-javadoc-dynamic-status)
+ (jde-javadoc-insert-author-tag doctree)
+ ;; version
+ (jde-javadoc-dynamic-status)
+ (jde-javadoc-insert-version-tag doctree))
;; Keep extra optional tags if they already exist
(jde-javadoc-dynamic-status)
(jde-javadoc-map (function
(lambda (tag)
(jde-javadoc-insert-previous-tag doctree tag)))
- jde-javadoc-extra-type-tags)
+ semantic-java-doc-extra-type-tags)
;; Keep unknown (not Sun's) tags
(jde-javadoc-insert-unknown-tags doctree)
;; The end of comment block
(jde-javadoc-dynamic-status)
(jde-javadoc-insert-end-block))
-(defun jde-javadoc-variable-doc (modifiers type name &optional doctree)
+(defun jde-javadoc-variable-doc (modifiers type name
+ &optional doctree)
"Document a field using MODIFIERS TYPE NAME.
If description and tags already exist in DOCTREE keep them."
;; description
@@ -1488,7 +1458,7 @@
(jde-javadoc-map (function
(lambda (tag)
(jde-javadoc-insert-previous-tag doctree tag)))
- jde-javadoc-extra-variable-tags)
+ semantic-java-doc-extra-variable-tags)
;; Keep unknown (not Sun's) tags
(jde-javadoc-insert-unknown-tags doctree)
;; The end of comment block
@@ -1507,7 +1477,8 @@
(jde-javadoc-insert-param-tag doctree type name)))))
tokens))
-(defun jde-javadoc-function-doc (modifiers type name args throws &optional doctree)
+(defun jde-javadoc-function-doc (modifiers type name args throws
+ &optional doctree)
"Document a function using MODIFIERS TYPE NAME ARGS THROWS.
If description and tags already exist in DOCTREE keep them."
;; description
@@ -1522,7 +1493,7 @@
(jde-javadoc-map (function
(lambda (tag)
(jde-javadoc-insert-previous-tag doctree tag)))
- jde-javadoc-extra-function-tags)
+ semantic-java-doc-extra-function-tags)
;; Keep unknown (not Sun's) tags
(jde-javadoc-insert-unknown-tags doctree)
;; The end of comment block
@@ -1536,9 +1507,10 @@
(let ((modifiers (semantic-token-type-modifiers token))
(type (semantic-token-type token))
(name (semantic-token-name token))
- (parents (semantic-token-type-parent token)))
+ (parents (semantic-token-type-parent token))
+ (main (jde-javadoc-checker-main-type-p token)))
(jde-javadoc-dynamic-status)
- (jde-javadoc-type-doc modifiers type name parents doctree)))
+ (jde-javadoc-type-doc modifiers type name parents main doctree)))
(defun jde-javadoc-variable (token doctree)
"Document a 'variable' (field) TOKEN.
@@ -1558,7 +1530,8 @@
(args (semantic-token-function-args token))
(throws (semantic-token-function-throws token)))
(jde-javadoc-dynamic-status)
- (jde-javadoc-function-doc modifiers type name args throws doctree)))
+ (jde-javadoc-function-doc
+ modifiers type name args throws doctree)))
(defun jde-javadoc-generator (token &optional noconfirm)
"Call the javadoc generator associated to TOKEN.
@@ -1577,10 +1550,17 @@
(if (and (fboundp checker)
(not (funcall checker token doctree)))
(setq report nil)
- (when (or (not doctree)
- (jde-javadoc-delete-documentation token noconfirm))
- (funcall generator token doctree)
- (jde-javadoc-indent-documentation token)))
+ (let ((seas semantic-edits-are-safe))
+ (make-local-variable 'semantic-edits-are-safe)
+ (unwind-protect
+ (progn
+ (setq semantic-edits-are-safe t)
+ (when (or (not doctree)
+ (jde-javadoc-delete-documentation
+ token noconfirm))
+ (funcall generator token doctree)
+ (jde-javadoc-indent-documentation token)))
+ (setq semantic-edits-are-safe seas))))
(jde-javadoc-dynamic-status t))
(or report
(message "Documentation is up-to-date")))))
@@ -1601,38 +1581,42 @@
(semantic-current-nonterminal)))
(defvar jde-javadoc-checkdoc-excursion nil
- "Buffer and position before running `jde-javadoc-checkdoc'.")
+ "Window configuration and point before running doc checker.")
+;; Maybe `jde-javadoc-checkdoc-excursion' could be made buffer local?
+;;(make-variable-buffer-local 'jde-javadoc-checkdoc-excursion)
(defun jde-javadoc-checkdoc-clear-excursion ()
- "Clear saved buffer, window start and point.
-See `jde-javadoc-checkdoc-save-excursion'."
+ "Clear saved window configuration and point.
+See also variable `jde-javadoc-checkdoc-excursion'."
(setq jde-javadoc-checkdoc-excursion nil))
(defun jde-javadoc-checkdoc-save-excursion ()
- "Save current buffer, window start and point."
+ "Save window configuration and point.
+See also function `jde-javadoc-checkdoc-restore-excursion'."
(setq jde-javadoc-checkdoc-excursion
- (vector (current-buffer)
- (window-start)
+ (vector (current-window-configuration)
(point))))
(defun jde-javadoc-checkdoc-restore-excursion ()
- "Restore window start and point of the current buffer.
-Does nothing if the current buffer is not the one saved by previous
-`jde-javadoc-checkdoc-save-excursion'."
- (when (and (vectorp jde-javadoc-checkdoc-excursion)
- (= 3 (length jde-javadoc-checkdoc-excursion))
- (eq (current-buffer) (aref jde-javadoc-checkdoc-excursion 0)))
- (set-window-start (selected-window)
- (aref jde-javadoc-checkdoc-excursion 1))
- (goto-char (aref jde-javadoc-checkdoc-excursion 2))
+ "Restore window configuration and point.
+See also function `jde-javadoc-checkdoc-save-excursion'."
+ (let ((ex jde-javadoc-checkdoc-excursion))
+ (and (vectorp ex)
+ (window-configuration-p (aref ex 0))
+ (integer-or-marker-p (aref ex 1))
+ (condition-case nil
+ (progn
+ (set-window-configuration (aref ex 0))
+ (goto-char (aref ex 1)))
+ (error nil)))
(jde-javadoc-checkdoc-clear-excursion)))
-
+
(defun jde-javadoc-checker-previous ()
"Goto the previous token with doc errors."
(interactive)
(and (eq major-mode 'jde-javadoc-checker-report-mode)
- (jde-javadoc-checker-previous-token jde-javadoc-checker-buffer
- jde-javadoc-checker-token)))
+ (jde-javadoc-checker-previous-token
+ jde-javadoc-checker-buffer jde-javadoc-checker-token)))
(defun jde-javadoc-checker-next ()
"Goto the next token with doc errors."
@@ -1661,14 +1645,9 @@
Used in `jde-javadoc-checker-report-mode'."
(interactive)
(let ((buffer (get-buffer jde-javadoc-checker-report-buffer)))
- (if (not buffer)
- (jde-javadoc-checkdoc-restore-excursion)
- (set-buffer buffer)
- (when (bufferp jde-javadoc-checker-buffer)
- (pop-to-buffer jde-javadoc-checker-buffer)
- (jde-javadoc-checkdoc-restore-excursion))
- (delete-windows-on buffer t)
- (kill-buffer buffer))))
+ (if (bufferp buffer)
+ (kill-buffer buffer))
+ (jde-javadoc-checkdoc-restore-excursion)))
;;;; Commands
;;;; --------
@@ -1769,8 +1748,6 @@
- - `jde-javadoc-exception-tag-template'
- - `jde-javadoc-param-tag-template'
- - `jde-javadoc-return-tag-template'
-- - `jde-javadoc-see-tag-template'
-- - `jde-javadoc-since-tag-template'
- - `jde-javadoc-version-tag-template'
For example if you customize `jde-javadoc-describe-class-template'
@@ -1822,8 +1799,11 @@
;;; Compatibility
;;
-(defalias 'jde-javadoc-generate-javadoc-template 'jde-javadoc-autodoc-at-line)
-(require 'jde-javadoc-gen) ; Load the javadoc builder
+(defalias 'jde-javadoc-generate-javadoc-template
+ 'jde-javadoc-autodoc-at-line)
+
+;; Load the javadoc builder
+(require 'jde-javadoc-gen)
(defun jde-javadoc-enable-menu-p ()
"Return non-nil if corresponding doc menu item is enabled.
@@ -1836,10 +1816,11 @@
(memq (semantic-token-token token-at-line)
'(function type variable))
(save-excursion
- (setq start (progn
- (goto-char (semantic-token-start token-at-line))
- (beginning-of-line)
- (point)))
+ (setq start
+ (progn
+ (goto-char (semantic-token-start token-at-line))
+ (beginning-of-line)
+ (point)))
(setq end (or (re-search-forward "[;={]")
(progn
(goto-char p)
@@ -1851,8 +1832,8 @@
;;
;; $Log: jde-javadoc.el,v $
-;; Revision 1.2 2001/02/12 05:38:25 paulk
-;; JDE 2.2.7
+;; Revision 1.18 2001/05/19 02:36:00 paulk
+;; Updated to support semantic 1.4. Thanks to David Ponce.
;;
;; Revision 1.17 2001/01/27 05:42:07 paulk
;; Enhancements from David Ponce:
@@ -1860,25 +1841,26 @@
;; - Improved `jde-javadoc-start-tag-regexp' and
;; `jde-javadoc-end-tag-regexp' regular expressions which fix little
;; problems when parsing javadoc tags. These regexps enforce the
-;; following rule (from JDK 1.3 documentation "javadoc - The Java API
-;; Documentation Generator" - Chapter "DOCUMENTATION COMMENTS" -
+;; following rule (from JDK 1.3 documentation "javadoc - The Java
+;; API Documentation Generator" - Chapter "DOCUMENTATION COMMENTS" -
;; "Standard and in-line tags":
;;
;;
;; "[...] a standard tag must appear at the beginning of a line,
;; ignoring leading asterisks, white space and comment separator
-;; (/**). This means you can use the @ character elsewhere in the text
-;; and it will not be interpreted as the start of a tag. If you want to
-;; start a line with the @ character and not have it be interpreted,
-;; use the HTML entity @. [...]"
+;; (/**). This means you can use the @ character elsewhere in the
+;; text and it will not be interpreted as the start of a tag. If you
+;; want to start a line with the @ character and not have it be
+;; interpreted, use the HTML entity @. [...]"
;;
;;
;; - `jde-javadoc-checker-report-mode' now turns on `font-lock-mode'.
-;; This is useful in XEmacs which don't have a `global-font-lock-mode'.
+;; This is useful in XEmacs which don't have a
+;; `global-font-lock-mode'.
;;
;;
-;; - Filling of messages in `jde-javadoc-checker-show-report' now works
-;; with XEmacs too.
+;; - Filling of messages in `jde-javadoc-checker-show-report' now
+;; works with XEmacs too.
;;
;; Revision 1.16 2000/12/18 05:22:45 paulk
;; *** empty log message ***
@@ -1889,13 +1871,13 @@
;; Revision 1.14 2000/10/25 03:11:57 paulk
;; Enhancements from David Ponce:
;;
-;; * It is now possible to check javadoc comments only for tokens with a
-;; specified access level. The new `jde-javadoc-checker-level' option
-;; defines the accessibility level to check.
+;; * It is now possible to check javadoc comments only for tokens with
+;; a specified access level. The new `jde-javadoc-checker-level'
+;; option defines the accessibility level to check.
;;
;; Only 'type, 'function or 'variable tokens with this level will be
-;; checked. The level is defined to be consistent with the javadoc show
-;; options. That is:
+;; checked. The level is defined to be consistent with the javadoc
+;; show options. That is:
;;
;; - - public - check only public classes and members.
;; - - protected - check only protected and public classes and
@@ -1904,14 +1886,14 @@
;; and members.
;; - - private - check all classes and members.
;;
-;; If a token is included in other ones its access level is the lowest
-;; one found in the hierarchy.
+;; If a token is included in other ones its access level is the
+;; lowest one found in the hierarchy.
;;
-;; Using `jde-javadoc-checkdoc-at-line' it is always possible to check
-;; any token regardless of its access level.
+;; Using `jde-javadoc-checkdoc-at-line' it is always possible to
+;; check any token regardless of its access level.
;;
-;; * Changed '[u]-update' action by more appropriate '[f]-try to fix'
in
-;; the checker report dialog.
+;; * Changed '[u]-update' action by more appropriate '[f]-try to fix'
+;; in the checker report dialog.
;;
;; * Changed message "Invalid tag order, must be ..." by
;; "Recommended tag order is ...".
@@ -1925,8 +1907,10 @@
;; Revision 1.11 2000/10/08 12:55:39 paulk
;; *** empty log message ***
;;
-;; Revision 1.10 2000/09/23 04:26:13 paulk
-;; Adds jde-javadoc-command-path and jde-javadoc-display-doc variables. Thanks to
"Jason Stell" <Jason.Stell(a)globalone.net> for providing the initial
version of these changes.
+;; Revision 1.10 2000/09/23 04:26:13 paulk Adds
+;; jde-javadoc-command-path and jde-javadoc-display-doc
+;; variables. Thanks to "Jason Stell" <Jason.Stell(a)globalone.net> for
+;; providing the initial version of these changes.
;;
;; Revision 1.9 2000/08/19 06:44:02 paulk
;; Don't quote class names in javadoc command.
@@ -1934,11 +1918,11 @@
;; Revision 1.8 2000/08/08 04:49:32 paulk
;; Fixed the doc for jde-javadoc-make.
;;
-;; Revision 1.7 2000/08/07 06:09:57 paulk
-;; jde-javadoc-make now uses jde-db-source-directories as the sourcepath for generating
doc.
+;; Revision 1.7 2000/08/07 06:09:57 paulk jde-javadoc-make now uses
+;; jde-db-source-directories as the sourcepath for generating doc.
;;
-;; Revision 1.6 2000/08/07 05:16:10 paulk
-;; Adds jde-javadoc-make command. Thanks to Sergey A Klibanov
<sakliban(a)cs.wustl.edu>.
+;; Revision 1.6 2000/08/07 05:16:10 paulk Adds jde-javadoc-make
+;; command. Thanks to Sergey A Klibanov <sakliban(a)cs.wustl.edu>.
;;
;; Revision 1.5 2000/07/13 05:22:48 paulk
;; *** empty log message ***
Index: xemacs-packages/jde/lisp/jde-make.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/jde-make.el,v
retrieving revision 1.2
diff -u -r1.2 jde-make.el
--- xemacs-packages/jde/lisp/jde-make.el 2001/02/12 05:38:26 1.2
+++ xemacs-packages/jde/lisp/jde-make.el 2001/08/15 05:28:00
@@ -1,11 +1,11 @@
;;; jde-make.el -- Integrated Development Environment for Java.
-;; $Revision: 1.2 $
+;; $Revision: 1.8 $
;; Author: Paul Kinnucan <paulk(a)mathworks.com>
;; Maintainer: Paul Kinnucan
;; Keywords: java, tools
-;; Copyright (C) 1997, 1998 Paul Kinnucan.
+;; Copyright (C) 1997, 1998, 2001 Paul Kinnucan.
;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
@@ -83,7 +83,7 @@
(default-directory
(if (string= jde-make-working-directory "")
default-directory
- jde-make-working-directory)))
+ (jde-normalize-path 'jde-make-working-directory))))
;; Force save-some-buffers to use the minibuffer
;; to query user about whether to save modified buffers.
@@ -121,8 +121,8 @@
(provide 'jde-make)
;; $Log: jde-make.el,v $
-;; Revision 1.2 2001/02/12 05:38:26 paulk
-;; JDE 2.2.7
+;; Revision 1.8 2001/04/16 05:59:17 paulk
+;; Normalize paths. Thanks to Nick Sieger.
;;
;; Revision 1.7 2000/08/09 03:29:26 paulk
;; Added jde-make-working-directory variable. Thanks to Laurent Latil
<Laurent.Latil(a)france.sun.com>
Index: xemacs-packages/jde/lisp/jde-package.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/jde-package.el,v
retrieving revision 1.1
diff -u -r1.1 jde-package.el
--- xemacs-packages/jde/lisp/jde-package.el 2001/02/25 05:36:05 1.1
+++ xemacs-packages/jde/lisp/jde-package.el 2001/08/15 05:28:01
@@ -1,92 +1,96 @@
-;; @(#) jpack.el -- Java package statement generator
-;; @(#) $Id: jde-package.el,v 1.1 2001/02/25 05:36:05 paulk Exp $
+;; jde-package.el -- Java package statement generator
+;; $Id: jde-package.el,v 1.5 2001/04/09 05:01:03 paulk Exp $
-;; This file is not part of Emacs
-
;; Copyright (C) 1998, 2000, 2001 by David Ponce
+
;; Author: David Ponce <david(a)dponce.com>
;; Maintainer: David Ponce <david(a)dponce.com>
;; Paul Kinnucan <paulk(a)mediaone.net>
;; Created: September 28 1998
-;; COPYRIGHT NOTICE
-;;
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
+;; This file is not part of Emacs
+
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2, or (at
+;; your option) any later version.
+
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with this program; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; along with this program; see the file COPYING. If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
-;;; Description:
+;;; Commentary:
;;
-;; This package automatically generates a Java package statement.
-;; The package name is deducted from the current classpath setting of JDE. When
-;; a directory found in classpath is a root of the current buffer default
-;; directory, the relative path of the default directory from the classpath one
-;; becomes the package name by substituting directory separators by '.'.
+;; This package automatically generates a Java package statement. The
+;; package name is deducted from the current classpath setting of
+;; JDE. When a directory found in classpath is a root of the current
+;; buffer default directory, the relative path of the default
+;; directory from the classpath one becomes the package name by
+;; substituting directory separators by '.'.
;;
-;; For example:
-;; My JDE classpath setting is ("~/java"
"/jdk1.1.6/lib/classes.zip")
-;; I edit the file ~/java/FR/test/MyClass.java
-;; The package name generated will be `FR.test'.
+;; For example:
;;
-;; My JDE classpath setting is ("~/java" "~/java/test"
"/jdk1.1.6/lib/classes.zip")
-;; I edit the file ~/java/test/MyClass.java
-;; "// Default package used." will be generated because the default
package can be used.
+;; The JDE classpath setting is:
;;
-;; My JDE classpath setting is ("~/java"
"/jdk1.1.6/lib/classes.zip")
-;; I edit the file /usr/java/MyClass.java
-;; No package name will be generated because the directory /usr/java is not
-;; accessible from classpath.
-
-;;; Usage:
+;; ("~/java" "/jdk1.1.6/lib/classes.zip")
;;
-;; M-x `jde-package-update' to update the Java package statement or insert a new
-;; at top of buffer.
-;; The function `jde-package-generate-package-statement' could be used in template
to
-;; automatically generate the package statement.
-
-;;; Customization:
+;; For the file "~/java/FR/test/MyClass.java", the package name
+;; generated will be "FR.test".
;;
-;; M-x `jde-package-customize' to customize all the jde-package options.
+;; The JDE classpath setting is:
;;
-;; The following variables could be set:
+;; ("~/java" "~/java/test"
"/jdk1.1.6/lib/classes.zip")
;;
-;; o `jde-package-load-hook'
-;; hook run when package has been loaded.
+;; For the file "~/java/test/MyClass.java",
+;; `jde-package-default-package-comment' will be generated because
+;; the default package can be used.
;;
-;; o `jde-package-package-comment'
-;; Java line comment appended to the generated package statement.
-;; Default to " // Generated package name"
+;; The JDE classpath setting is:
;;
-;; o `jde-package-default-package-comment'
-;; Java line comment generated when the default package is used.
-;; Default to "// Default package used"
+;; ("~/java" "/jdk1.1.6/lib/classes.zip")
;;
-;; o `jde-package-search-classpath-variables'
-;; The list of variables where to search the current classpath list.
-;; Default to '(jde-compile-option-classpath jde-global-classpath)
-
-;;; Support:
+;; For the file "/usr/java/MyClass.java", no package name will be
+;; generated because the directory "/usr/java" is not accessible
+;; from classpath.
;;
-;; Latest version of jde-package can be downloaded from: <
http://www.dponce.com/>
+;; Usage:
;;
-;; Any comments, suggestions, bug reports or upgrade requests are welcome.
-;; Please send them to David Ponce at <david(a)dponce.com>
+;; M-x `jde-package-update' to update the Java package statement or
+;; insert a new one at beginning of current buffer.
;;
-
-;;; Code:
+;; The function `jde-package-generate-package-statement' should be
+;; used in Java template to automatically generate the package
+;; statement.
+;;
+;; Customization:
+;;
+;; The following variables could be set:
+;;
+;; - `jde-package-load-hook' hook run when package has been loaded.
+;;
+;; - `jde-package-package-comment' Java line comment appended to the
+;; generated package statement. Default is " // Generated package
+;; name"
+;;
+;; - `jde-package-default-package-comment' Java line comment generated
+;; when the default package is used. Default is "// Default package
+;; used"
+;;
+;; - `jde-package-search-classpath-variables' list of variables where
+;; to search the current classpath list. Default is
+;; '(`jde-compile-option-classpath' `jde-global-classpath')
+;;; History:
+;;
+;; See at end of this file.
+;;; Code:
(defconst jde-package-unknown-package-name
"*unknown*"
"The string returned when a package name can't be generated.")
@@ -97,138 +101,135 @@
(defgroup jde-package nil
"jde-package package customization"
- :group 'tools
+ :group 'jde
:prefix "jde-package-")
(defcustom jde-package-load-hook nil
"*Hook run when package has been loaded."
:group 'jde-package
- :type 'hook
- )
+ :type 'hook)
-(defcustom jde-package-package-comment " // Generated package name"
+(defcustom jde-package-package-comment
+ " // Generated package name"
"*Java line comment appended to the generated package statement.
An empty string suppress the generation of this comment."
:group 'jde-package
- :type 'string
- )
+ :type 'string)
-(defcustom jde-package-default-package-comment "// Default package used"
+(defcustom jde-package-default-package-comment
+ "// Default package used"
"*Java line comment generated when the default package is used.
An empty string suppress the generation of this comment."
:group 'jde-package
- :type 'string
- )
+ :type 'string)
(defcustom jde-package-search-classpath-variables
'(jde-compile-option-classpath jde-global-classpath)
"*Specify the variables where to search the current classpath list.
The first one which has a non nil value will be used by jde-package."
:group 'jde-package
- :type '(repeat variable)
- )
+ :type '(repeat variable))
-;;;###autoload
-(defun jde-package-customize ()
- "Customization of the group jde-package."
- (interactive)
- (customize-group "jde-package"))
+(defalias 'jde-package-fullpath 'jde-normalize-path)
-
-(defun jde-package-fullpath (path)
- "Returns the full path of the given path.
-~ (HOME) and environment variables references are expanded."
- (expand-file-name (substitute-in-file-name path)))
-
(defun jde-package-get-classpath ()
- "Returns the current classpath list. That is to say the first non-nil value
-found in the variables given by `jde-package-search-classpath-variables'."
+ "Return the current classpath list.
+That is to say the first non-nil value found in the variables given by
+`jde-package-search-classpath-variables'."
(let ((search-in jde-package-search-classpath-variables)
(classpath))
- (catch 'jde-package-classpath
- (while search-in
- (setq classpath (symbol-value (car search-in)))
- (if classpath
- (throw 'jde-package-classpath classpath))
- (setq search-in (cdr search-in))))))
+ (while (and search-in (not classpath))
+ (setq classpath (symbol-value (car search-in))
+ search-in (cdr search-in)))
+ classpath))
(defun jde-package-get-directories-in-classpath ()
- "Returns the list of directories found in classpath."
- (mapcan '(lambda (path)
- (unless (string= path ".") ; "." is ignored in
classpath
- (let ((path (jde-package-fullpath path)))
- (when (file-directory-p path)
- (list (file-name-as-directory path))))))
- (jde-package-get-classpath)))
+ "Return the list of directories found in classpath."
+ (mapcan
+ #'(lambda (path)
+ (if (not (string= path ".")) ; "." is ignored in classpath
+ (let ((path (jde-package-fullpath path)))
+ (if (file-directory-p path)
+ (list (file-name-as-directory path))))))
+ (jde-package-get-classpath)))
(defun jde-package-get-current-directory ()
- "Returns the full path of the current directory."
+ "Return the full path of the current directory."
(jde-package-fullpath default-directory))
(defun jde-package-seach-package-directories ()
- "Returns a list of package directory candidates or nil if none found."
+ "Return a list of package directory candidates or nil if not found."
(let ((dir (jde-package-get-current-directory))
- (case-fold-search (eq system-type 'windows-nt))) ; case-insensitive for
Windows
- (mapcan '(lambda (root)
- (let ((root (regexp-quote root)))
- (message "Seaching %S in %S..." root dir)
- (and (string-match root dir)
- (list (substring dir (match-end 0))))))
- (jde-package-get-directories-in-classpath))))
+ ;; case-insensitive for Windows
+ (case-fold-search (eq system-type 'windows-nt)))
+ (mapcan
+ #'(lambda (root)
+ (let ((root (regexp-quote root)))
+ (message "Seaching %S in %S..." root dir)
+ (and (string-match root dir)
+ (list (substring dir (match-end 0))))))
+ (jde-package-get-directories-in-classpath))))
(defun jde-package-get-package-directory ()
- "Returns the package directory found or `jde-package-unknown-package-name'
-if none found."
- (or (jde-package-best-package-candidate (jde-package-seach-package-directories))
+ "Return the package directory found.
+Or `jde-package-unknown-package-name' if not found."
+ (or (jde-package-best-package-candidate
+ (jde-package-seach-package-directories))
jde-package-unknown-package-name))
(defun jde-package-best-package-candidate (candidates)
- "Returns the best package directory candidate from the given list of
-package directories. The best is the shortest one that could be found."
- (car (sort candidates '(lambda (dir1 dir2) (string-match (regexp-quote dir1)
dir2)))))
+ "Return the best package directory candidate from CANDIDATES.
+The best is the shortest one that could be found."
+ (car (sort candidates
+ #'(lambda (dir1 dir2)
+ (string-match (regexp-quote dir1) dir2)))))
(defun jde-package-convert-directory-to-package (dir)
- "Converts the given directory path to a valid Java package name
-by replacing `directory-sep-char' by '.' and removing extra
+ "Convert directory path DIR to a valid Java package name.
+Replace `directory-sep-char' by '.' and remove extra
`directory-sep-char' at end."
(if (string= dir "")
""
- (subst-char-in-string directory-sep-char ?.
- (substring (file-name-as-directory dir) 0 -1)
- t)))
+ (subst-char-in-string
+ directory-sep-char ?.
+ (substring (file-name-as-directory dir) 0 -1)
+ t)))
;;;###autoload
(defun jde-package-generate-package-statement ()
- "Generates a Java package statement. If the package name cant be generated
-this function returns an empty string."
+ "Generate a Java package statement.
+If the package name cant be generated this function returns an empty
+string."
(let ((package-name (jde-package-get-package-directory)))
- (cond ((string= package-name jde-package-unknown-package-name)
- (message "The current directory is not accessible from
classpath.")
- "")
- ((string= package-name "")
- (message "Default package used.")
- jde-package-default-package-comment)
- (t (message "package %s;%s"
- (jde-package-convert-directory-to-package package-name)
- jde-package-package-comment)))))
+ (cond
+ ((string= package-name jde-package-unknown-package-name)
+ (message
+ "The current directory is not accessible from classpath.")
+ "")
+ ((string= package-name "")
+ (message "Default package used.")
+ jde-package-default-package-comment)
+ (t
+ (message "package %s;%s"
+ (jde-package-convert-directory-to-package package-name)
+ jde-package-package-comment)))))
;;;###autoload
(defun jde-package-update ()
- "Updates or replaces the Java package statement in the current buffer.
+ "Update or replace the Java package statement in the current buffer.
If the package statement does not exist a new one is inserted at the
-top of the buffer. If the package name cant be generated nothing is done.
-The major mode of current buffer must be 'jde-mode'."
+top of the buffer. If the package name cant be generated nothing is
+done. The major mode of current buffer must be `jde-mode'."
(interactive)
- (if (eq major-mode 'jde-mode)
- (let ((package (jde-package-generate-package-statement)))
- (unless (string= package "")
- (goto-char (point-min))
- (if (re-search-forward jde-package-package-regexp nil t)
- (replace-match package)
- (progn
- (insert package)
- (newline)))))
- (message "Invalid major mode found. Must be 'jde-mode'.")))
+ (or (eq major-mode 'jde-mode)
+ (error "Invalid major mode found. Must be `jde-mode'"))
+ (let ((package (jde-package-generate-package-statement)))
+ (unless (string= package "")
+ (goto-char (point-min))
+ (if (re-search-forward jde-package-package-regexp nil t)
+ (replace-match package)
+ (insert package)
+ (newline)))))
(provide 'jde-package)
(run-hooks 'jde-package-load-hook)
@@ -236,9 +237,16 @@
;;; Change History:
;; $Log: jde-package.el,v $
-;; Revision 1.1 2001/02/25 05:36:05 paulk
-;; Initial XEmacs version.
+;; Revision 1.5 2001/04/09 05:01:03 paulk
+;; Fixed bug in jde-package-get-directories-in-classpath that caused it to return t
instead of a list when the classpath contained ".".
+;;
+;; Revision 1.4 2001/03/30 07:10:31 paulk
+;; Minor code improvement and cleanup and many checkdoc related
+;; cosmetic changes contributed by David Ponce.
;;
+;; Revision 1.3 2001/03/13 04:23:58 paulk
+;; Cosmetic changes.
+;;
;; Revision 1.2 2001/02/22 03:36:30 paulk
;; Removed require for jde to fix infinite recursion loading bug.
;;
@@ -248,8 +256,15 @@
;;
;; $Log: jde-package.el,v $
-;; Revision 1.1 2001/02/25 05:36:05 paulk
-;; Initial XEmacs version.
+;; Revision 1.5 2001/04/09 05:01:03 paulk
+;; Fixed bug in jde-package-get-directories-in-classpath that caused it to return t
instead of a list when the classpath contained ".".
+;;
+;; Revision 1.4 2001/03/30 07:10:31 paulk
+;; Minor code improvement and cleanup and many checkdoc related
+;; cosmetic changes contributed by David Ponce.
+;;
+;; Revision 1.3 2001/03/13 04:23:58 paulk
+;; Cosmetic changes.
;;
;; Revision 1.2 2001/02/22 03:36:30 paulk
;; Removed require for jde to fix infinite recursion loading bug.
Index: xemacs-packages/jde/lisp/jde-parse.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/jde-parse.el,v
retrieving revision 1.2
diff -u -r1.2 jde-parse.el
--- xemacs-packages/jde/lisp/jde-parse.el 2001/02/12 05:38:26 1.2
+++ xemacs-packages/jde/lisp/jde-parse.el 2001/08/15 05:28:01
@@ -1,5 +1,5 @@
;;; jde-parse.el
-;; $Revision: 1.2 $
+;; $Revision: 1.30 $
;; Author: Paul Kinnucan <paulk(a)mathworks.com>
;; Maintainer: Paul Kinnucan
@@ -70,6 +70,7 @@
;; in some versions of XEmacs. Hence the following
;; guard.
(when (string= mode-name "JDE")
+ (message "Test parse buffer")
(semantic-clear-toplevel-cache)
(semantic-bovinate-toplevel)))
@@ -143,7 +144,7 @@
(mapcan (lambda (buffer)
(save-excursion
(set-buffer buffer)
- (if (string= mode-name "JDE")
+ (if (equal major-mode 'jde-mode)
(list buffer))))
(buffer-list)))
@@ -160,7 +161,7 @@
(let ((selected-buffer (window-buffer (selected-window))))
(save-excursion
(set-buffer selected-buffer)
- (if (string= mode-name "JDE") selected-buffer))))
+ (if (equal major-mode 'jde-mode) selected-buffer))))
(defun jde-parse-get-package-name ()
"Gets the name of the package in which the Java source file in the
@@ -626,8 +627,8 @@
(provide 'jde-parse)
;; $Log: jde-parse.el,v $
-;; Revision 1.2 2001/02/12 05:38:26 paulk
-;; JDE 2.2.7
+;; Revision 1.30 2001/03/16 04:49:08 paulk
+;; Use major-mode instead of mode-name for testing which mode buffer is in. Thanks to
Kevin Burton burton(a)relativity.yi.org.
;;
;; Revision 1.29 2001/01/05 07:14:35 paulk
;; Removed old version of jde-parse-get-class-at-point.
Index: xemacs-packages/jde/lisp/jde-run.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/jde-run.el,v
retrieving revision 1.3
diff -u -r1.3 jde-run.el
--- xemacs-packages/jde/lisp/jde-run.el 2001/02/12 05:38:26 1.3
+++ xemacs-packages/jde/lisp/jde-run.el 2001/08/15 05:28:02
@@ -1,5 +1,5 @@
;; jde-run.el --- runs the Java app in the current buffer.
-;; $Revision: 1.3 $ $Date: 2001/02/12 05:38:26 $
+;; $Revision: 1.52 $ $Date: 2001/04/28 06:22:19 $
;; Author: Paul Kinnucan <paulk(a)mathworks.com>
;; Maintainer: Paul Kinnucan
@@ -381,15 +381,21 @@
;; Set the classpath option. Use the local
;; classpath, if set; otherwise, the global
;; classpath.
- (setq options
- (nconc
- options
- (list
- "-classpath"
- (jde-build-classpath
- (if jde-run-option-classpath
+ (let ((classpath
+ (if jde-run-option-classpath
jde-run-option-classpath
- jde-global-classpath)))))
+ jde-global-classpath))
+ (symbol
+ (if jde-run-option-classpath
+ 'jde-run-option-classpath
+ 'jde-global-classpath)))
+ (if classpath
+ (setq options
+ (nconc
+ options
+ (list
+ "-classpath"
+ (jde-build-classpath classpath symbol))))))
;; Set the verbose options.
@@ -516,17 +522,28 @@
;;;###autoload
-(defun jde-run ()
+(defun jde-run (main-class)
"Run the Java application specified by `jde-run-executable', if
not the null string. Otherwise run the class specified by
`jde-run-application-class', if non-null; otherwise the class in
-the current buffer. This command also creates a comint buffer to allow
-you to interacti with the program."
- (interactive)
- (if (string= mode-name "JDE")
- (if (string= jde-run-executable "")
- (jde-run-main-class)
- (jde-run-executable))
+the current buffer. Specifying a prefix argument, e.g.,
+C-u C-c C-v C-r, causes this command to prompt you to enter
+the name of the application's main class This command
+creates a comint buffer to allow you to interacti with the program."
+ (interactive "P")
+ (if (equal major-mode 'jde-mode)
+ (cond
+ (main-class
+ (jde-run-internal
+ (read-from-minibuffer
+ "Main class: "
+ (concat (jde-db-get-package)
+ (file-name-sans-extension
+ (file-name-nondirectory (buffer-file-name)))))))
+ ((string= jde-run-executable "")
+ (jde-run-main-class))
+ (t
+ (jde-run-executable)))
(error "The jde-run command works only in a Java source buffer.")))
(defun jde-run-get-main-class ()
@@ -576,7 +593,7 @@
(source-directory default-directory)
(working-directory (if (string= jde-run-working-directory "")
default-directory
- jde-run-working-directory)))
+ (jde-normalize-path 'jde-run-working-directory))))
(if (not (comint-check-proc run-buf-name))
(let* ((run-buffer (get-buffer-create run-buf-name))
(win32-p (eq system-type 'windows-nt))
@@ -633,7 +650,7 @@
(source-directory default-directory)
(working-directory (if (string= jde-run-working-directory "")
default-directory
- jde-run-working-directory)))
+ (jde-normalize-path 'jde-run-working-directory))))
(if (not (comint-check-proc run-buf-name))
(let* ((run-buffer (get-buffer-create run-buf-name))
(prog-args (append
@@ -665,14 +682,19 @@
(pop-to-buffer run-buf-name))))
-;;;###autoload
-(defun jde-run-mode()
+(defun jde-run-mode-internal()
"Mode for running Java programs."
- (interactive)
- (comint-mode)
- (setq major-mode 'jde-run-mode)
- (run-hooks 'jde-run-mode-hook)
-)
+ (define-key (current-local-map) "\C-c\C-v\C-[" 'jde-run-etrace-prev)
+ (define-key (current-local-map) "\C-c\C-v\C-]" 'jde-run-etrace-next)
+ (define-key (current-local-map) [mouse-2] 'jde-run-etrace-show-at-mouse)
+ (font-lock-mode 1)
+ (jde-run-etrace-setup-font-lock))
+
+(define-derived-mode
+ jde-run-mode comint-mode "JDE Run Mode"
+ "Major mode for running Java applications and applets.
+ \\{jde-run-mode-map}"
+ (jde-run-mode-internal))
(defun jde-get-appletviewer-options ()
(let (options)
@@ -838,13 +860,150 @@
(jde-run-applet))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; ;;
+;; Exception Trace Navigation ;;
+;; ;;
+;; Copyright (C) 1999 Phillip Lord <p.lord(a)hgmp.mrc.ac.uk> ;;
+;; Copyright (C) 2001 Sam Steingold <sds(a)gnu.org> ;;
+;; Copyright (C) 2001 Kevin A. Burton <burton(a)apache.org> ;;
+;; ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defvar jde-run-etrace-current-marker (cons (make-marker) (make-marker))
+ "The location of the last stack shown.
+A cons of two markers, location of the error and the location in the code.")
+
+
+(defun jde-run-etrace-current-marker (&optional next)
+ "Update the `cdr' of `jde-run-etrace-current-marker' from its `car'.
+Here goes all the error message parsing."
+ (let ((here (car jde-run-etrace-current-marker))
+ (there (cdr jde-run-etrace-current-marker)))
+ (save-excursion
+ (set-buffer (marker-buffer here))
+ (goto-char here)
+ (forward-line (or next 0))
+ (re-search-forward
+ (eval-when-compile
+ (concat "\\([a-zA-Z0-9_.]+\\.\\)?" ; package
+ "\\([a-zA-Z0-9_]+\\)" ; class
+ "\\.<?[a-zA-Z0-9_]+>?" ; method
+ "(\\([a-zA-Z0-9_]+\\)\\.java:" ; java file = public class
+ "\\([0-9]+\\))"))
+ nil t) ; line number
+ (message "1: [%s]; 2: [%s]; 3: [%s]; 4: [%s]" (match-string 1)
+ (match-string 2) (match-string 3) (match-string 4))
+ (let* ((package (or (match-string 1) ""))
+ (class (match-string 2))
+ (file-name (match-string 3))
+ (line (car (read-from-string (match-string 4))))
+ (file (jde-find-class-source-file (concat package file-name)))
+ (buf (if file (find-file-noselect file)
+ (error "jde-class-source cannot find source for %s%s
(%s)"
+ package class file-name))))
+ (set-buffer buf) (goto-line line)
+ (set-marker there (point) buf)))
+ jde-run-etrace-current-marker))
+
+
+(defun jde-run-etrace-goto (&optional next)
+ "Display the current stack using `compilation-goto-locus'."
+ (compilation-goto-locus (jde-run-etrace-current-marker next)))
+
+
+(defun jde-run-etrace-show-at-mouse (event)
+ "Jump to the stack position at the mouse click.
+Click anywhere on the line with the stack reference."
+ (interactive "e")
+ (set-marker (car jde-run-etrace-current-marker)
+ (posn-point (event-start event))
+ (window-buffer (posn-window (event-start event))))
+ (jde-run-etrace-goto))
+
+
+(defun jde-run-etrace-show-at-point ()
+ "Jump to the stack position on this current line.
+The point should be anywhere on the line with the stack reference."
+ (interactive)
+ (set-marker (car jde-run-etrace-current-marker) (point) (current-buffer))
+ (jde-run-etrace-goto))
+
+
+(defun jde-run-etrace-next ()
+ "Jump to the next stack postion (next line)."
+ (interactive)
+ (jde-run-etrace-goto 1))
+
+
+(defun jde-run-etrace-prev ()
+ "Jump to the previous stack postion (previous line)."
+ (interactive)
+ (jde-run-etrace-goto -1))
+
+(defun jde-run-etrace-setup-font-lock ()
+ ;;setup the correct font-lock stuff
+
+
+ ;;font lock setup notes
+ ;;
+ ;; the actual exception class -> font-lock-keyword-face
+ ;; exception message -> font-lock-string-face
+ ;; stack entry class and method -> font-lock-constant-face
+ ;; stack entry file -> font-lock-variable-name-face
+ ;; stack entry line number -> font-lock-type-face
+
+ (if jde-xemacsp
+ nil
+ (progn
+ (font-lock-add-keywords
+ nil
+ '(("\\(^[a-z.]+[a-zA-Z0-9]+Exception\\)\\(: \\)?\\(.*\\)?"
+ (1 'font-lock-keyword-face append)
+ (3 'font-lock-string-face append))))
+
+ (font-lock-add-keywords
+ nil
+ '(("\\(at
[a-z.]+[a-zA-Z0-9]+\\.[a-zA-Z<>]*\\)(\\([a-zA-Z0-9]+.java\\):\\([0-9]+\\))$"
+ (1 'font-lock-constant-face append)
+ (2 'font-lock-variable-name-face append)
+ (3 'font-lock-type-face append))))
+ (font-lock-fontify-buffer))))
+
+;;(define-key jde-mode-map "\C-c\C-v\C-[" 'jde-run-etrace-prev)
+;;(define-key jde-mode-map "\C-c\C-v\C-]" 'jde-run-etrace-next)
+
+
(provide 'jde-run)
;; Change History
;; $Log: jde-run.el,v $
-;; Revision 1.3 2001/02/12 05:38:26 paulk
-;; JDE 2.2.7
+;; Revision 1.52 2001/04/28 06:22:19 paulk
+;; Makes jde-run-mode a full-fledged major mode derived from comint-mode.
+;;
+;; Revision 1.51 2001/04/16 06:00:50 paulk
+;; Normalize paths. Thanks to Nick Sieger.
+;;
+;; Revision 1.50 2001/04/12 04:37:45 paulk
+;; Normalize jde-run-working-directory.
+;;
+;; Revision 1.49 2001/04/11 03:18:04 paulk
+;; Updated to resolve relative paths relative to the project file that defines them.
Thanks to Nick Seiger.
+;;
+;; Revision 1.48 2001/04/09 05:28:20 paulk
+;;
+;; Revision 1.47 2001/03/16 04:52:46 paulk
+;; Use major-mode instead of mode-name to check the buffer mode. Thanks to Kevin
Burton.
+;;
+;; Revision 1.46 2001/03/02 04:10:37 paulk
+;; Updated jde-run prompt to specify the class in the current buffer as the suggested
response.
+;;
+;; Revision 1.45 2001/03/01 12:50:20 paulk
+;; The jde-run command now prompts you to enter the name of the
+;; application's main class if you type a prefix (C-u) first.
+;;
+;; Revision 1.44 2001/02/26 04:13:11 paulk
+;; jde-run now handles case where jde-global-classpath and jde-run-option-classpath are
nil.
;;
;; Revision 1.43 2001/02/03 08:23:53 paulk
;; Changed declaration of customized variables so you can use completion on path
variables.
Index: xemacs-packages/jde/lisp/jde-stat.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/jde-stat.el,v
retrieving revision 1.1
diff -u -r1.1 jde-stat.el
--- xemacs-packages/jde/lisp/jde-stat.el 2001/02/12 05:54:53 1.1
+++ xemacs-packages/jde/lisp/jde-stat.el 2001/08/15 05:28:02
@@ -1,5 +1,5 @@
;;; jde-stat.el -- Integrated Development Environment for Java.
-;; $Revision: 1.1 $ $Date: 2001/02/12 05:54:53 $
+;; $Revision: 1.1 $ $Date: 2000/07/28 05:59:43 $
;; Author: Stephane Nicolas <s.nicolas(a)videotron.ca>
;; Maintainer: Paul Kinnucan
@@ -163,9 +163,6 @@
;; Change History
;;
;; $Log: jde-stat.el,v $
-;; Revision 1.1 2001/02/12 05:54:53 paulk
-;; Initial XEmacs revision.
-;;
;; Revision 1.1 2000/07/28 05:59:43 paulk
;; Initial revision. Thanks to Stephane Nicolas <s.nicolas(a)videotron.ca>
;; for contributing the initial version of this package.
Index: xemacs-packages/jde/lisp/jde-which-method.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/jde-which-method.el,v
retrieving revision 1.1
diff -u -r1.1 jde-which-method.el
--- xemacs-packages/jde/lisp/jde-which-method.el 2001/02/12 05:57:51 1.1
+++ xemacs-packages/jde/lisp/jde-which-method.el 2001/08/15 05:28:02
@@ -1,6 +1,6 @@
;;; jde-which-method.el --- Print current method in mode line
-;; Copyright (C) 1994, 1997, 1998 Free Software Foundation, Inc.
+;; Copyright (C) 1994, 1997, 1998, 2001 Free Software Foundation, Inc.
;; Author: Paul Kinnucan (paulk(a)mathworks.com)
;; Inspired by Alex Rezinsky's which-func package.
@@ -31,9 +31,12 @@
;;; History:
;; $Log: jde-which-method.el,v $
-;; Revision 1.1 2001/02/12 05:57:51 paulk
-;; Initial XEmacs revision.
+;; Revision 1.10 2001/03/23 09:01:42 paulk
+;; Now update the mode line during idle times instead of after every keystroke. Thanks
to Steven Monnier for suggesting this improvement.
;;
+;; Revision 1.9 2001/02/27 04:58:33 paulk
+;; Disable jde-which-method-mode by default. This mode slows down scrolling, which is
disconcerting to new users.
+;;
;; Revision 1.8 2000/11/27 06:18:41 paulk
;; Miscellaneous bug fixes and minor enhancements.
;;
@@ -133,6 +136,9 @@
;;; -------------------------------------
;;;
+(defvar jde-which-method-idle-timer nil
+ "Timer that updates the mode line.")
+
(defvar jde-which-method-unknown "???"
"String to display in the mode line when the current method is unknown.")
@@ -160,81 +166,85 @@
(defun jde-which-method-update ()
(interactive)
- (condition-case info
- (let ((p (point)))
- (if (or
- (= jde-which-method-current-point-loc p)
- (and
- (>= p (car jde-which-method-current-method-bounds))
- (<= p (cdr jde-which-method-current-method-bounds))))
- (setq jde-which-method-current-point p)
- (let ((name ;; (jde-parse-get-method-at-point)
- (if jde-parse-the-method-map
- (jde-parse-method-map-get-method-at jde-parse-the-method-map))
- ))
- (if name
- (let* ((name-pair (car name))
- (class (car name-pair))
- (method (cdr name-pair))
- (bounds (cdr name))
- (class-length (length class))
- (method-length (length method))
- ;; initialize the truncation with 0!
- (trunc-class 0)
- (trunc-method 0)
- (trunc-complete 0))
- (when jde-which-method-max-length
- ;; compute necessary truncation of method and/or class
- (if jde-parse-buffer-contains-multiple-classes-p
- (when (> (+ class-length method-length 1)
- jde-which-method-max-length)
- (setq trunc-complete (- (+ class-length
- method-length 1)
- jde-which-method-max-length))
- (if (< (- class-length trunc-complete)
- jde-which-method-class-min-length)
- (setq trunc-class
- (- class-length
- jde-which-method-class-min-length)
- trunc-method (- trunc-complete
- trunc-class))
- (setq trunc-method 0
- trunc-class trunc-complete)))
- (when (> method-length jde-which-method-max-length)
- (setq trunc-method (- method-length
- jde-which-method-max-length)))))
- ;; truncate method and class with the computed truncation
- ;; (possible 0, then no truncation is done in fact)
- (setq class (jde-which-method-truncate-end class trunc-class)
- method (jde-which-method-truncate-end method trunc-method))
- ;; set the displayed string from the (possible truncated)
- ;; class and method parts according to
- ;; jde-parse-buffer-contains-multiple-classes-p.
- (setq jde-which-method-current
- (if jde-parse-buffer-contains-multiple-classes-p
- (format "M:%s.%s" class method)
- (format "M:%s" method)))
- (setq jde-which-method-current-point-loc p)
- (setq jde-which-method-current-method-bounds bounds))
- (progn
- (setq name (jde-parse-get-innermost-class-at-point))
- (setq jde-which-method-current-point-loc p)
- (setq jde-which-method-current-method-bounds (cons -1 -1))
- (if name
- (let* ((class (car name))
- (class-length (length class)))
- ;; possible truncate the string to display
- (when (and jde-which-method-max-length
- (> class-length jde-which-method-max-length))
- (setq class (jde-which-method-truncate-begin class
- (- class-length
-
jde-which-method-max-length))))
- (setq jde-which-method-current (format "C:%s" class)))
- (setq jde-which-method-current jde-which-method-unknown)))))))
- (error
- ;; (debug)
- (remove-hook 'post-command-hook 'jde-which-method-update)
- (message "Error in jde-which-method-update: %s" info))))
+ (if (and
+ jde-which-method-mode
+ (eq major-mode 'jde-mode))
+ (condition-case info
+ (let ((p (point)))
+ (if (or
+ (= jde-which-method-current-point-loc p)
+ (and
+ (>= p (car jde-which-method-current-method-bounds))
+ (<= p (cdr jde-which-method-current-method-bounds))))
+ (setq jde-which-method-current-point p)
+ (let ((name;; (jde-parse-get-method-at-point)
+ (if jde-parse-the-method-map
+ (jde-parse-method-map-get-method-at jde-parse-the-method-map))
+ ))
+ (if name
+ (let* ((name-pair (car name))
+ (class (car name-pair))
+ (method (cdr name-pair))
+ (bounds (cdr name))
+ (class-length (length class))
+ (method-length (length method))
+ ;; initialize the truncation with 0!
+ (trunc-class 0)
+ (trunc-method 0)
+ (trunc-complete 0))
+ (when jde-which-method-max-length
+ ;; compute necessary truncation of method and/or class
+ (if jde-parse-buffer-contains-multiple-classes-p
+ (when (> (+ class-length method-length 1)
+ jde-which-method-max-length)
+ (setq trunc-complete (- (+ class-length
+ method-length 1)
+ jde-which-method-max-length))
+ (if (< (- class-length trunc-complete)
+ jde-which-method-class-min-length)
+ (setq trunc-class
+ (- class-length
+ jde-which-method-class-min-length)
+ trunc-method (- trunc-complete
+ trunc-class))
+ (setq trunc-method 0
+ trunc-class trunc-complete)))
+ (when (> method-length jde-which-method-max-length)
+ (setq trunc-method (- method-length
+ jde-which-method-max-length)))))
+ ;; truncate method and class with the computed truncation
+ ;; (possible 0, then no truncation is done in fact)
+ (setq class (jde-which-method-truncate-end class trunc-class)
+ method (jde-which-method-truncate-end method trunc-method))
+ ;; set the displayed string from the (possible truncated)
+ ;; class and method parts according to
+ ;; jde-parse-buffer-contains-multiple-classes-p.
+ (setq jde-which-method-current
+ (if jde-parse-buffer-contains-multiple-classes-p
+ (format "M:%s.%s" class method)
+ (format "M:%s" method)))
+ (setq jde-which-method-current-point-loc p)
+ (setq jde-which-method-current-method-bounds bounds))
+ (progn
+ (setq name (jde-parse-get-innermost-class-at-point))
+ (setq jde-which-method-current-point-loc p)
+ (setq jde-which-method-current-method-bounds (cons -1 -1))
+ (if name
+ (let* ((class (car name))
+ (class-length (length class)))
+ ;; possible truncate the string to display
+ (when (and jde-which-method-max-length
+ (> class-length jde-which-method-max-length))
+ (setq class (jde-which-method-truncate-begin class
+ (- class-length
+ jde-which-method-max-length))))
+ (setq jde-which-method-current (format "C:%s" class)))
+ (setq jde-which-method-current jde-which-method-unknown)))))))
+ (error
+ ;; (debug)
+ (cancel-timer jde-which-method-idle-timer)
+ (setq jde-which-method-idle-timer nil)
+ (message "Error in jde-which-method-update: %s" info)))))
(defun jde-which-method-update-on-entering-buffer ()
(setq jde-which-method-current-point-loc 0)
Index: xemacs-packages/jde/lisp/jde-widgets.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/jde-widgets.el,v
retrieving revision 1.3
diff -u -r1.3 jde-widgets.el
--- xemacs-packages/jde/lisp/jde-widgets.el 2001/02/17 07:38:21 1.3
+++ xemacs-packages/jde/lisp/jde-widgets.el 2001/08/15 05:28:02
@@ -1,5 +1,5 @@
;;; jde-widgets.el -- Custom-style widgets used by the JDE
-;; $Revision: 1.3 $ $Date: 2001/02/17 07:38:21 $
+;; $Revision: 1.12 $ $Date: 2001/05/21 06:44:29 $
;; Author: Paul Kinnucan <paulk(a)mathworks.com>
;; Maintainer: Paul Kinnucan
@@ -40,6 +40,7 @@
(require 'wid-edit)
(require 'eieio)
(require 'cl)
+(require 'tree-widget)
;; ----------------------------------------------------------------------
@@ -245,7 +246,56 @@
(pop-to-buffer (oref this buf)))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; ;;
+;; Option Dialog ;;
+;; ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defclass jde-option-dialog (jde-dialog)
+ ((options :initarg :options
+ :documentation
+ "Options from from which to choose.")
+ (radio-buttons :initarg :interface-buttons
+ :documentation
+ "Buttons for selecting options.")
+ (text :initarg :text
+ :type string
+ :initform "Select option."
+ :documentation
+ "Text to be inserted at top of dialog.")
+ (ok-action :initarg :ok-action
+ :type function
+ :documentation
+ "Function to invoke when the user selects the ok button."))
+ "This dialog allows a user to choose one of a set of OPTIONS by clicking
+a radio button next to the option. The dialog invokes the function OK-ACTION
+when the user selects the OK button on the dialog. OK-ACTION must be a function
+that takes the selected option as its only argument.")
+
+(defmethod initialize-instance ((this jde-option-dialog) &rest fields)
+ "Dialog constructor."
+ (call-next-method))
+
+(defmethod jde-dialog-create ((this jde-option-dialog))
+ (widget-insert (oref this text))
+ (widget-insert "\n\n")
+ (oset this radio-buttons
+ (widget-create
+ (list
+ 'radio-button-choice
+ :value (car (oref this options))
+ :args (mapcar
+ (lambda (x)
+ (list 'item x))
+ (oref this options)))))
+ (widget-insert "\n"))
+
+(defmethod jde-dialog-ok ((this jde-option-dialog))
+ (funcall (oref this ok-action)
+ (widget-value (oref this radio-buttons))))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Dynamic tree widget ;;
@@ -343,45 +393,47 @@
:process process
:object-id (oref var-value id)))
(str-val (jde-dbs-cmd-exec cmd)))
- (list 'jde-widget-tree :tag var-tag :value t
- (list 'jde-widget-tree :tag str-val)))
+ (list 'tree-widget :tag var-tag :value t
+ (list 'tree-widget :tag str-val)))
(list 'jde-widget-java-obj :tag var-tag
:process process :object-id (oref var-value :id))))
((typep var-value 'jde-dbs-java-array)
(list 'jde-widget-java-array :tag var-tag
:process process :object var-value))
((typep var-value 'jde-dbs-java-primitive)
- (list 'jde-widget-tree :tag var-tag :value t
- (list 'jde-widget-tree
+ (list 'tree-widget :tag var-tag :value t
+ (list 'tree-widget
:tag (format "%s" (oref var-value value)))))
((typep var-value 'jde-dbs-java-null)
- (list 'jde-widget-tree :tag var-tag :value t
- (list 'jde-widget-tree :tag "null")))
+ (list 'tree-widget :tag var-tag :value t
+ (list 'tree-widget :tag "null")))
(t
(error "Unidentified type of local variable: %s" var-tag)))))
-(defun jde-widget-java-obj-get-fields (tree-widget)
- (let* ((process (widget-get tree-widget :process))
- (object-id (widget-get tree-widget :object-id))
- (cmd
- (jde-dbs-get-object
- (format "get_object %d" object-id)
- :process process
- :object-id object-id))
- (object
- (jde-dbs-cmd-exec cmd))
- (fields (oref object fields))
- field
- nodes)
- (while fields
- (setq field (car fields) fields (cdr fields))
- (setq field (cdr field))
- (push
- (jde-widget-java-var-to-tree process field)
- nodes))
- nodes))
+(defun jde-widget-java-obj-get-fields (obj-widget)
+ (if (widget-get obj-widget :args)
+ (widget-get obj-widget :args)
+ (let* ((process (widget-get obj-widget :process))
+ (object-id (widget-get obj-widget :object-id))
+ (cmd
+ (jde-dbs-get-object
+ (format "get_object %d" object-id)
+ :process process
+ :object-id object-id))
+ (object
+ (jde-dbs-cmd-exec cmd))
+ (fields (oref object fields))
+ field
+ nodes)
+ (while fields
+ (setq field (car fields) fields (cdr fields))
+ (setq field (cdr field))
+ (push
+ (jde-widget-java-var-to-tree process field)
+ nodes))
+ nodes)))
-(define-widget 'jde-widget-java-obj 'jde-widget-dtree
+(define-widget 'jde-widget-java-obj 'tree-widget
"A widget that represents a Java object.
This widget is essentially a tree node whose entries are the fields
of the corresponding object. The first time the user expands the node,
@@ -392,7 +444,8 @@
:tag NAME :process PROCESS :object-id OBJ-ID) to create the widget where
NAME is the object's name, PROCESS is the process in which
the object exists, and ID is the debugger id for the object."
- :node-fcn 'jde-widget-java-obj-get-fields)
+ :dynargs 'jde-widget-java-obj-get-fields
+ :has-children t)
(defun jde-widget-java-array-element-to-tree (process element index)
@@ -404,7 +457,7 @@
:process process
:object-id (oref element id)))
(str-val (jde-dbs-cmd-exec cmd)))
- (list 'jde-widget-tree :tag (format "[%d] %s" index str-val)))
+ (list 'tree-widget :tag (format "[%d] %s" index str-val)))
(list 'jde-widget-java-obj
:tag (format "[%d] %s" index (oref element jtype))
:process process :object-id (oref element id))))
@@ -413,55 +466,58 @@
:tag (format "[%d] %s" index (oref element jtype))
:process process :object element))
((typep element 'jde-dbs-java-primitive)
- (list 'jde-widget-tree :tag (format "[%d] %s" index (oref element
value))))
+ (list 'tree-widget :tag (format "[%d] %s" index (oref element
value))))
((typep element 'jde-dbs-java-null)
- (list 'jde-widget-tree :tag (format "[%d] null" index)))
+ (list 'tree-widget :tag (format "[%d] null" index)))
(t
(error "Unidentified type of object: <%s|%s>" (oref element jtype)
(oref element id)))))
-(defun jde-widget-java-array-get-elements (tree-widget)
- (let* ((process (widget-get tree-widget :process))
- (array (widget-get tree-widget :object))
- cmd array-length)
-
- (setq cmd
- (jde-dbs-get-array
- (format "get_array_length %d" (oref array id))
- :process process
- :array array))
- (jde-dbs-cmd-exec cmd)
-
- (setq array-length
- (if (slot-boundp array 'length)
- (oref array length)
- 0))
-
- (when (> array-length 0)
+(defun jde-widget-java-array-get-elements (array-widget)
+ (if (widget-get array-widget :args)
+ (widget-get array-widget :args)
+ (let* ((process (widget-get array-widget :process))
+ (array (widget-get array-widget :object))
+ cmd array-length)
+
(setq cmd
- (jde-dbs-get-array
- (format "get_array_elements %d" (oref array id))
- :process process
- :array array
- :index 0
- :length array-length))
- (jde-dbs-cmd-exec cmd)
- (let ((elements (oref array elements))
- element
- nodes
- (index 0))
- (while elements
- (setq element (car elements) elements (cdr elements))
- (setq nodes
- (append nodes
- (list (jde-widget-java-array-element-to-tree process element index))))
- (setq index (1+ index)))
- nodes))))
+ (jde-dbs-get-array
+ (format "get_array_length %d" (oref array id))
+ :process process
+ :array array))
+ (jde-dbs-cmd-exec cmd)
+
+ (setq array-length
+ (if (slot-boundp array 'length)
+ (oref array length)
+ 0))
+
+ (when (> array-length 0)
+ (setq cmd
+ (jde-dbs-get-array
+ (format "get_array_elements %d" (oref array id))
+ :process process
+ :array array
+ :index 0
+ :length array-length))
+ (jde-dbs-cmd-exec cmd)
+ (let ((elements (oref array elements))
+ element
+ nodes
+ (index 0))
+ (while elements
+ (setq element (car elements) elements (cdr elements))
+ (setq nodes
+ (append nodes
+ (list (jde-widget-java-array-element-to-tree process element index))))
+ (setq index (1+ index)))
+ nodes)))))
-(define-widget 'jde-widget-java-array 'jde-widget-dtree
+(define-widget 'jde-widget-java-array 'tree-widget
"A widget that represents a Java array. Clicking on the widget's
expand button causes the widget to display the values of the array."
- :node-fcn 'jde-widget-java-array-get-elements)
+ :dynargs 'jde-widget-java-array-get-elements
+ :has-children t)
(defun test-obj ()
(interactive)
@@ -608,8 +664,11 @@
(provide 'jde-widgets)
;; $Log: jde-widgets.el,v $
-;; Revision 1.3 2001/02/17 07:38:21 paulk
-;; Requires cl to enable batch compile.
+;; Revision 1.12 2001/05/21 06:44:29 paulk
+;; Added jde-option-dialog class.
+;;
+;; Revision 1.11 2001/04/19 04:37:14 paulk
+;; Converted array and object trees to derive from David Ponce's tree widget.
;;
;; Revision 1.10 2001/02/16 04:38:52 paulk
;; Added (require 'cl) to enable batch compile.
Index: xemacs-packages/jde/lisp/jde-wiz.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/jde-wiz.el,v
retrieving revision 1.3
diff -u -r1.3 jde-wiz.el
--- xemacs-packages/jde/lisp/jde-wiz.el 2001/02/12 05:38:26 1.3
+++ xemacs-packages/jde/lisp/jde-wiz.el 2001/08/15 05:28:03
@@ -1,9 +1,10 @@
-;;; jde-wiz.el
;; $Revision: 1.3 $
+;;; jde-wiz.el
+;; $Revision: 1.45 $
;; Author: Paul Kinnucan <paulk(a)mathworks.com>
;; Maintainer: Paul Kinnucan
;; Keywords: java, tools
-;; Copyright (C) 1997, 1998, 2000 Paul Kinnucan.
+;; Copyright (C) 1997, 1998, 2000, 2001 Paul Kinnucan.
;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
@@ -22,12 +23,9 @@
(require 'beanshell)
(require 'jde-complete)
+(require 'jde-widgets)
-
-
-;;
-
-
(defun jde-wiz-escape-backslashes-in-path (path)
+(defun jde-wiz-escape-backslashes-in-path (path)
(mapconcat
(lambda (char)
(if (eq char ?\\) "\\\\" (char-to-string char)))
@@ -42,9 +40,9 @@
(message "Rescanning classes...")
(bsh-eval (concat "jde.util.JdeUtilities.buildClassList("
(jde-wiz-escape-backslashes-in-path
- (jde-build-path-arg nil jde-global-classpath t)
)
+ (jde-build-path-arg nil 'jde-global-classpath t))
");"))
- (message "Rescanning classes...Complete"))
)
+ (message "Rescanning classes...Complete")))
(defun jde-wiz-get-package-name ()
@@ -66,7 +64,6 @@
(string-match "[^.]+$" name)
(substring name (match-beginning 0) (match-end 0)))
-
(defun jde-wiz-update-implements-clause (interface-name)
(interactive
"sEnter interface: ")
@@ -94,12 +91,9 @@
(when class-name-end-pos
(goto-char (- open-brace-pos 1))
(insert (concat " implements " interface " "))))))))
-
-(defun jde-wiz-implement-interface (interface-name)
+(defun jde-wiz-generate-interface (interface-name)
"*Generate a skeleton implementation of a specified interface."
- (interactive
- "sInterface name: ")
(condition-case err
(let* ((nl-brace-p
(find 'before
@@ -121,7 +115,37 @@
(error
(message "%s" (error-message-string err)))))
+(defun jde-wiz-implement-interface-internal (interface-name)
+ "*Generate a skeleton implementation of a specified interface."
+ (interactive
+ "sInterface name: ")
+ (condition-case err
+ (let ((names
+ (bsh-eval-r
+ (format "jde.util.JdeUtilities.getQualifiedName(\"%s\");"
interface-name ))))
+ (if names
+ (if (> (length names) 1)
+ (let ((dialog
+ (jde-option-dialog
+ "class name dialog"
+ :options names
+ :text "Select interface to implement."
+ :ok-action 'jde-wiz-generate-interface)))
+ (jde-dialog-show dialog))
+ (jde-wiz-generate-interface (car names)))
+ (error "Cannot find interface %s on jde-global-classpath."
interface-name)))
+ (error
+ (message "%s" (error-message-string err)))))
+
+(defun jde-wiz-implement-interface (interface-name)
+ "*Generate a skeleton implementation of a specified interface."
+ (interactive
+ "sInterface name: ")
+ (jde-wiz-implement-interface-internal interface-name)
+ (goto-char (scan-lists (point) -1 1))
+ (c-indent-exp))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Method override wizard ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -139,10 +163,9 @@
(buffer-substring-no-properties
(match-beginning 1)
(match-end 1))))))))
-
-(defun jde-wiz-override-method (method-name)
- "Overrides a method whose name you specify.
+(defun jde-wiz-override-method (method-name)
+ "Overrides a method whose name you specify.
This command creates a skeleton implementation of the
overridden method at point. This command infers the
qualified name of the class of the overriden method by
@@ -163,14 +186,12 @@
NOTE: this command works only if the overriding class
has been previously compiled."
(interactive
- "sMethod name: ")
+ "sMethod name: " )
(condition-case err
- (let* ((package-name (jde-wiz-get-package-name))
- (class-name (jde-wiz-get-method-class))
- (qualified-class-name
- (if (and package-name class-name)
- (concat package-name "." class-name)
- class-name)))
+ (let* ((class-name
+ (jde-parse-get-super-class-at-point))
+ (qualified-class-name
+ (jde-complete-get-qualified-name class-name)))
(if qualified-class-name
(let ((signatures
(bsh-eval
@@ -180,10 +201,12 @@
(if signatures
(if (> (length signatures) 1)
(jde-wiz-override-variant-method signatures)
- (jde-wiz-override-method-internal (car signatures) signatures))))))
+ (jde-wiz-override-method-internal (car signatures) signatures))))
+ (error "Cannot find parent class %s" class-name)))
(error
(message "%s" (error-message-string err)))))
+
(defun jde-wiz-override-method-internal (selected-method methods)
(let* ((variant
(position selected-method methods :test 'string=))
@@ -203,6 +226,8 @@
(bsh-eval-r
"jde.wizards.MethodOverrideFactory.getImportedClasses();")))
(insert skeleton)
+ (goto-char (scan-lists (point) -1 1))
+ (c-indent-exp)
(if required-imports
(jde-import-insert-imports required-imports))))
@@ -324,12 +349,34 @@
(error
(message "%s" (error-message-string err)))))
+
+
(provide 'jde-wiz)
+;;; Change History:
+
;; $Log: jde-wiz.el,v $
-;; Revision 1.3 2001/02/12 05:38:26 paulk
-;; JDE 2.2.7
+;; Revision 1.45 2001/05/23 05:14:00 paulk
+;; Updated jde-wiz-override-method-internal to intent the inserted code.
+;;
+;; Revision 1.44 2001/05/23 05:03:32 paulk
+;; Updated jde-wiz-implement-interface to indent the inserted code.
+;;
+;; Revision 1.43 2001/05/21 06:45:39 paulk
+;; Implement interface command now accepts unqualified interface names.
+;;
+;; Revision 1.42 2001/04/27 03:58:13 paulk
+;; Fixes Override Method Wizard so that it does not require a compiled version of the
base class.
+;;
+;; Revision 1.41 2001/04/16 06:02:27 paulk
+;; Normalize paths. Thanks to Nick Sieger.
+;;
+;; Revision 1.40 2001/04/11 03:16:36 paulk
+;; Updated to resolve relative paths relative to the project file that defines them.
Thanks to Nick Seiger.
+;;
+;; Revision 1.39 2001/03/13 03:45:06 paulk
+;; Cosmetic changes.
;;
;; Revision 1.38 2000/12/21 13:24:12 paulk
;; Changed jde-wiz-insert-imports to jde-import-insert-imports to reflect recent
repackaging scheme.
Index: xemacs-packages/jde/lisp/jde.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/jde.el,v
retrieving revision 1.5
diff -u -r1.5 jde.el
--- xemacs-packages/jde/lisp/jde.el 2001/02/25 05:10:13 1.5
+++ xemacs-packages/jde/lisp/jde.el 2001/08/15 05:28:04
@@ -1,5 +1,5 @@
;;; jde.el -- Integrated Development Environment for Java.
-;; $Revision: 1.5 $ $Date: 2001/02/25 05:10:13 $
+;; $Revision: 1.170 $ $Date: 2001/05/23 03:33:56 $
;; Author: Paul Kinnucan <paulk(a)mathworks.com>
;; Maintainer: Paul Kinnucan
@@ -29,7 +29,7 @@
;; JDE User's Guide for more information.
;; The latest version of the JDE is available at
-;; <URL:http://sunsite.auc.dk/jde/>.
+;; <URL:http://jde.sunsite.dk>.
;; <
URL:http://www.geocities.com/SiliconValley/Lakes/1506/>
;; Please send any comments, bugs, or upgrade requests to
@@ -39,7 +39,7 @@
;;;###autoload
-(defconst jde-version "2.2.7beta3"
+(defconst jde-version "2.2.7.1"
"JDE version number.")
(defconst jde-xemacsp (string-match "XEmacs" (emacs-version))
@@ -55,6 +55,7 @@
(defconst jde-xemacs20p (and jde-xemacsp (>= emacs-major-version 20))))
+(require 'semantic-load)
(require 'easymenu)
(require 'cl)
(require 'font-lock)
@@ -83,6 +84,7 @@
(require 'jde-import)
(require 'senator)
(require 'jde-package)
+(require 'executable) ;; in XEmacs' sh-script package
;; (require 'jde-project)
;; From custom web page for compatibility between versions of custom:
@@ -126,7 +128,8 @@
(cons "[?\C-c ?\C-v ?\C-b]" 'jde-build)
(cons "[?\C-c ?\C-v ?\C-c]" 'jde-compile)
(cons "[?\C-c ?\C-v ?\C-d]" 'jde-debug)
- (cons "[?\C-c ?\C-v ?\C-f]" 'jde-wiz-implement-interface)
+ (cons "[?\C-c ?\C-v ?\C-f]" 'jde-find)
+ (cons "[?\C-c ?\C-v ?i]" 'jde-wiz-implement-interface)
(cons "[?\C-c ?\C-v ?j]" 'jde-javadoc-generate-javadoc-template)
(cons "[?\C-c ?\C-v ?\C-k]" 'bsh)
(cons "[?\C-c ?\C-v ?\C-l]" 'jde-gen-println)
@@ -139,6 +142,8 @@
(cons "[?\C-c ?\C-v ?\C-w]" 'jde-help-symbol)
(cons "[?\C-c ?\C-v ?\C-y]" 'jde-show-class-source)
(cons "[?\C-c ?\C-v ?\C-z]" 'jde-import-find-and-import)
+ (cons "[?\C-c ?\C-v ?\C-[]" 'jde-run-etrace-prev)
+ (cons "[?\C-c ?\C-v ?\C-]]" 'jde-run-etrace-next)
(cons "[(control c) (control v) (control ?.)]"
'jde-complete-at-point-menu)
(cons "[(control c) (control v) ?.]" 'jde-complete-at-point)
)
@@ -193,9 +198,11 @@
:type 'boolean
)
-;; Used by debugger to disable context-switching temporarily while
-;; stepping through code.
-(setq jde-project-cs-enabled-p t)
+(defun jde-toggle-project-switching ()
+ "Toggles project switching on or off."
+ (interactive)
+ (setq jde-project-context-switching-enabled-p
+ (not jde-project-context-switching-enabled-p)))
;;(makunbound 'jde-jdk-doc-url)
(defcustom jde-jdk-doc-url "http://www.javasoft.com/j2se/1.3/docs/index.html"
@@ -219,7 +226,7 @@
of an environment variable with its value before inserting it into
a command line.
-You cans specify different classpaths for compiling, running and
+You can specify different classpaths for compiling, running and
debugging applicaitons. Use `jde-compile-option-classpath' to specify
the compilation classpath, `jde-run-option-classpath' to specify the
run classpath, and/or `jde-db-option-classpath' to specify the debug
@@ -235,7 +242,9 @@
If you do not set `jde-global-classpath', the JDE uses the operation-specific
classpath if it is set. If neither the global nor the
operation-specific classpath is set, the JDE does not generate a
--classpath argument for the operation.
+-classpath argument for the operation, e.g., compile or run a Java
+class. In this case, the operation uses the value of the CLASSPATH variable
+if specified.
Note: do not use environment variables in the paths that you set via
jde-global-classpath."
@@ -249,9 +258,23 @@
:group 'jde-project
:type 'boolean)
-(defvar jde-project-name "default"
-"Specifies name of project to which the current buffer belongs.")
+(defcustom jde-expand-classpath-p t
+ "Replace each occurence of a directory named `jde-lib-directory-name'
+ in the classpath with paths to the jar and zip files in that directory."
+ :group 'jde-project
+ :type 'boolean)
+
+(defcustom jde-lib-directory-name "lib"
+ "Regular expression that matches name of lib directories for
+the current project. See `jde-expand-classpath-p' and
+`jde-expand-classpath' for more information"
+ :group 'jde-project
+ :type 'string)
+(defcustom jde-project-name "default"
+"Specifies name of project to which the current buffer belongs."
+ :group 'jde-project
+ :type 'string)
(defcustom jde-project-file-name "prj.el"
"*Specify name of JDE project file.
@@ -385,7 +408,7 @@
(string :tag "Abbreviation")
(string :tag "Expansion"))))
-(defvar jde-mode-abbrev-table nil
+(defvar jde-mode-abbrev-table (make-abbrev-table)
"Abbrev table for use in JDE-mode buffers.")
@@ -398,7 +421,7 @@
;; around, since the anonymous function needs the closure provided by
;; lexical-let.
(interactive)
- (setq local-abbrev-table (make-abbrev-table))
+ ;; (setq local-abbrev-table (make-abbrev-table))
(mapc
(lambda (x)
(lexical-let
@@ -476,12 +499,13 @@
"Displays the JDK doc in a web browser. This function uses the URL
stored in the variable jde-jdk-doc-url to locate the JDK documentation."
(interactive)
- (if (or
- (string-match "http:" jde-jdk-doc-url)
- (string-match "file:" jde-jdk-doc-url)
- (file-exists-p jde-jdk-doc-url))
- (browse-url jde-jdk-doc-url browse-url-new-window-p)
- (error "The JDK documentation file, %s, does not exist."
jde-jdk-doc-url)))
+ (let ((expanded-url (jde-normalize-path 'jde-jdk-doc-url)))
+ (if (or (string-match "http:" jde-jdk-doc-url)
+ (string-match "file:" jde-jdk-doc-url))
+ (browse-url jde-jdk-doc-url browse-url-new-window-p)
+ (if (file-exists-p expanded-url)
+ (browse-url expanded-url browse-url-new-window-p)
+ (error "The JDK documentation file, %s, does not exist."
jde-jdk-doc-url)))))
(defun jde-make-compile-command (more-args)
"Constructs the java compile command as: jde-compiler + options + buffer file
name."
@@ -588,14 +612,19 @@
;; This feature loads the appropriate project settings whenever
;; a user switches from a Java buffer belonging to one project
;; to a buffer belonging to another.
- (make-local-hook 'post-command-hook)
- (unless (find 'jde-detect-java-buffer-activation post-command-hook)
- (add-hook 'post-command-hook 'jde-detect-java-buffer-activation nil t))
-
- (make-local-hook 'after-change-functions)
- (setq after-change-functions (default-value 'after-change-functions))
- (add-hook 'after-change-functions 'jde-parse-buffer-changed-hook nil t)
+ (let ((pch post-command-hook))
+ (make-local-hook 'post-command-hook)
+ (setq post-command-hook pch)
+ (unless (find 'jde-detect-java-buffer-activation post-command-hook)
+ (add-hook 'post-command-hook 'jde-detect-java-buffer-activation nil t)))
+
+ (let ((acf after-change-functions))
+ (make-local-hook 'after-change-functions)
+ (setq after-change-functions acf)
+ (add-hook 'after-change-functions
+ 'jde-parse-buffer-changed-hook nil t))
+
(if jde-xemacsp
(jde-insert-menu-in-XEmacs-menubar))
@@ -638,8 +667,11 @@
(make-local-variable 'mode-line-format)
(setq mode-line-format jde-mode-line-format)
- (when jde-which-method-mode
- (add-hook 'post-command-hook 'jde-which-method-update nil t))
+ (if (and
+ jde-which-method-mode
+ (not jde-which-method-idle-timer))
+ (setq jde-which-method-idle-timer
+ (run-with-idle-timer .25 t 'jde-which-method-update)))
(make-local-hook 'semantic-after-toplevel-bovinate-hook)
(add-hook 'semantic-after-toplevel-bovinate-hook
@@ -672,6 +704,43 @@
(jde-mode-internal)
)
+(defcustom jde-log-max 500
+ "*Maximum number of lines to keep in the JDE log buffer. If nil,
+disable logging. If t, don't truncate the buffer."
+ :group 'jde-project
+ :type '(choice (integer :tag "Number of lines to keep")
+ (boolean :tag "Disable/Unlimited")))
+
+(defun jde-log-msg (msg &rest args)
+ "Log a message to the *jde-log* buffer. Does nothing if
+`jde-log-max' is nil."
+ (if jde-log-max
+ (save-match-data
+ (save-excursion
+ (set-buffer (get-buffer-create "*jde-log*"))
+ (goto-char (point-max))
+ (insert (apply 'format msg args))
+ (insert "\n")
+ (if (integerp jde-log-max)
+ (let ((line-cnt 0))
+ (while (search-backward "\n" nil t)
+ (setq line-cnt (1+ line-cnt)))
+ (goto-char (point-min))
+ (while (> line-cnt jde-log-max)
+ (delete-region (point) (search-forward "\n" nil t))
+ (setq line-cnt (1- line-cnt)))))))))
+
+(defun jde-log-msg-t (msg &rest args)
+ "Log a message to the *jde-log* buffer, and return t. Does nothing
+but return t if `jde-log-max' is nil."
+ (jde-log-msg msg args)
+ t)
+
+(defun jde-log-msg-nil (msg &rest args)
+ "Log a message to the *jde-log* buffer, and return nil. Does nothing
+but return nil if `jde-log-max' is nil."
+ (jde-log-msg msg args)
+ nil)
;; Make jde-mode the default mode for Java source code buffers.
;; Prepend the jde-mode entry so that it shadows the java-mode
@@ -694,6 +763,9 @@
["Debug Applet" jde-db-menu-debug-applet t]
"-"
["Build" jde-build t]
+ ["Find" jde-find (and
+ (executable-find "find")
+ (executable-find "grep"))]
["Interpret" bsh t]
(list "Documentation"
["Add" jde-javadoc-autodoc-at-line
(jde-javadoc-enable-menu-p)]
@@ -722,6 +794,11 @@
)
["Speedbar" speedbar-frame-mode t]
(list "Project"
+ (vector "Auto Switch"
+ 'jde-toggle-project-switching
+ (if jde-xemacsp :active :enable) t
+ :style 'radio
+ :selected 'jde-project-context-switching-enabled-p)
(list "Options"
["General" jde-show-project-options t]
["Compile" jde-show-compile-options t]
@@ -731,6 +808,7 @@
["Javadoc" jde-javadoc-customize t]
)
(list "Project File"
+ ["Create New" jde-create-new-project t]
["Save" jde-save-project t]
["Load" jde-load-project-file t]
["Load All" jde-load-all-project-files t]
@@ -794,14 +872,16 @@
-;; Project File Functions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Path Conversion Functions ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun jde-cygpath (path &optional direction)
"Converts a path from cygwin to DOS form if DIRECTION is nil.
Otherwise, it converts the path to cygwin form. Requires that cygpath
be in your path."
(interactive "sPath: ")
- (if (which "cygpath")
+ (if (executable-find "cygpath")
(save-excursion
(let ((buf-name "*cygwin-output*")
(output-type (if direction "-u" "-w")))
@@ -878,54 +958,154 @@
(funcall (car jde-cygwin-path-converter)
(if separator (substitute ?\: (string-to-char separator) path) path)))
-(defun jde-normalize-path (path)
- "This function performs
- the following transformation on PATH:
-
- * Replaces environment variables of the form
- $VAR or ${VAR} with their values. Note
- that you must use the Unix notation for
- environment variables on the native Windows
- versions of Emacs and XEmacs.
-
- * Replaces the tilde character with the
- value of the home directory, typically
- specified by the HOME environment variable.
-
- * Converts Cygwin style paths to DOS notation
- on Windows.
-
-This function does not expand relative paths."
- (let ((p (substitute-in-file-name path)))
- (if (not (eq (aref p 0) ?.))
- (setq p (expand-file-name p)))
- (jde-convert-cygwin-path
- p)))
-
-(defun jde-build-classpath (paths)
- "Builds a classpath from PATHS.
-PATHS is a list of paths. "
+(defcustom jde-resolve-relative-paths-p t
+ "If this variable is non-nil, the JDE converts relative paths to
+absolute paths. The JDE does this by appending the relative path to the path
+of the project file for the current source buffer, if such
+a file exists. Otherwise, the JDE appends the relative path to the path
+of the current directory."
+ :group 'jde-project
+ :type 'boolean)
+
+(defun jde-normalize-path (path &optional symbol)
+ "This function performs the following transformation on PATH:
+
+ * Replaces environment variables of the form $VAR or ${VAR} with
+ their values. Note that you must use the Unix notation for
+ environment variables on the native Windows versions of Emacs and
+ XEmacs.
+
+ * Replaces the tilde character with the value of the home directory,
+ typically specified by the HOME environment variable.
+
+ * Converts Cygwin style paths to DOS notation on Windows.
+
+ * Converts relative paths to absolute paths if
+ `jde-resolve-relative-paths-p' is non-nil. Paths are resolved
+ according to the location deepest project file found, or if
+ optional SYMBOL is non-nil, paths are resolved to the location of
+ the deepest project file found that defines SYMBOL.
+
+Note: PATH can either be a path string or a symbol corresponding to a
+variable that holds a path string, in which case the optional arg
+SYMBOL is unnecessary."
+ (if (symbolp path)
+ (setq symbol path
+ path (symbol-value symbol)))
+ (let* ((directory-sep-char ?/)
+ (p (substitute-in-file-name path))
+ (len (length p)))
+ (if (and
+ jde-resolve-relative-paths-p
+ (> len 0)
+ (eq (aref p 0) ?.))
+ (let* (prj-file-path
+ (dir (file-name-directory (or (buffer-file-name)
+ default-directory))))
+ ;; find the deepest originating project for the symbol
+ ;; based on the current directory, and resolve to that
+ ;; project's directory
+ (if symbol
+ (let ((prjs (get symbol 'jde-project))
+ (sort-fn
+ (lambda (x1 x2)
+ (let* ((dir1 (file-name-directory (car x1)))
+ (dir2 (file-name-directory (car x2)))
+ match1 match2)
+ (if (null dir1)
+ (null dir2)
+ (if (null dir2)
+ t
+ (setq match1 (compare-strings
+ dir1 0 (length dir1)
+ dir 0 (length dir1)))
+ (setq match2 (compare-strings
+ dir2 0 (length dir2)
+ dir 0 (length dir2))))
+ (cond
+ ((not (eq match1 t))
+ (if (eq match2 t)
+ nil
+ (> (length dir1) (length dir2))))
+ ((not (eq match2 t))
+ t)
+ ((> (length dir1) (length dir2)))))))))
+ (setq prjs (sort prjs sort-fn))
+ (setq prj-file-path (caar prjs)))
+ (setq prj-file-path
+ (jde-find-project-file dir)))
+ (if prj-file-path
+ (setq dir (file-name-directory prj-file-path))
+ (setq dir default-directory))
+ (if (and (> len 1)
+ (eq (aref p 1) ?.))
+ ;; path actually begins with `..', so normalize to one
+ ;; directory up
+ (save-match-data
+ (string-match "\\.+/?" p)
+ (setq p (expand-file-name (substring p (match-end 0))
+ (expand-file-name (concat dir "../")))))
+ (setq p (expand-file-name p dir))))
+ (setq p (expand-file-name p)))
+ (jde-convert-cygwin-path p)))
+
+(defun jde-expand-classpath (classpath)
+ "Replaces paths to directories named lib with paths
+to jar or zip files in those directories."
+ (if jde-expand-classpath-p
+ (let (paths)
+ (loop for path in classpath do
+ (if (and
+ (file-exists-p path)
+ (file-directory-p path)
+ (string-match jde-lib-directory-name
+ (file-name-nondirectory path)))
+ (progn
+ (setq paths
+ (append paths
+ (directory-files path t "\\.jar$")))
+ (setq paths
+ (append paths
+ (directory-files path t "\\.zip$"))))
+ (setq paths (append paths (list path)))))
+ paths)
+ classpath))
+
+
+(defun jde-build-classpath (paths &optional symbol)
+ "Builds a classpath from PATHS. PATHS is a either list of paths or
+a symbol whose value is a list of paths, in which case the optional
+arg SYMBOL is unnecessary."
+ (if (symbolp paths)
+ (setq symbol paths
+ paths (symbol-value symbol)))
(mapconcat
(lambda (path)
- (jde-normalize-path path))
- paths
+ (jde-normalize-path path symbol))
+ (jde-expand-classpath
+ (mapcar
+ (lambda (path)
+ (jde-normalize-path path symbol))
+ paths))
jde-classpath-separator))
(defun jde-global-classpath ()
- (jde-build-classpath jde-global-classpath))
+ "Builds a classpath string from the path entries in
+`jde-global-classpath'."
+ (jde-build-classpath 'jde-global-classpath))
-(defun jde-build-path-arg (arg path-list &optional quote)
+(defun jde-build-path-arg (arg path-list &optional quote symbol)
"Build a command-line path argument from a list of paths."
- (let ((path (jde-build-classpath path-list)))
+ (let ((path (jde-build-classpath path-list symbol)))
(if quote
(setq path (concat "\"" path "\"")))
(setq path (concat arg " " path))))
-(defun jde-build-classpath-arg (path-list &optional quote)
+(defun jde-build-classpath-arg (path-list &optional quote symbol)
"Build a classpath from a list of paths."
- (jde-build-path-arg "-classpath" path-list quote))
+ (jde-build-path-arg "-classpath" path-list quote symbol))
(defun jde-root-dir-p (dir)
(let ((parent (concat dir "../")))
@@ -946,10 +1126,20 @@
(string= (file-truename dir) "/")
(string= (file-truename parent) "/")))))))
+(defconst jde-project-file-version "1.0"
+ "*The current JDE project file version number.")
+
+(defvar jde-loaded-project-file-version nil
+ "*Temporary var that holds the project file version of the project
+being loaded.")
+
+(defun jde-project-file-version (ver)
+ (setq jde-loaded-project-file-version ver))
+
(defun jde-find-project-file (dir)
- "Finds the project file for the Java source file in the current
-buffer. Returns nil if it cannot find a project file in the
-source file directory or an ascendant directory."
+ "Finds the next project file upwards in the directory tree
+from DIR. Returns nil if it cannot find a project file in DIR
+or an ascendant directory."
(let ((file (find jde-project-file-name
(directory-files dir) :test 'string=)))
(if file
@@ -957,18 +1147,42 @@
(if (not (jde-root-dir-p dir))
(jde-find-project-file (concat dir "../"))))))
+(defun jde-find-project-files (dir)
+ "Return all the project files in the current directory tree,
+starting with the topmost."
+ (let ((file (jde-find-project-file dir))
+ current-dir files)
+ (while file
+ (setq files (append (list file) files))
+ (setq current-dir (file-name-directory file))
+ (setq
+ file
+ (if (not (jde-root-dir-p current-dir))
+ (jde-find-project-file
+ (concat current-dir "../")))))
+ files))
+
+
(defun jde-load-project-file ()
- "Loads the project file for the Java source file in the current
-buffer. Searches for the project file first in the buffer directory,
-then in ascendant directories. Uses the first file that it encounters.
-If no project file is found, set each JDE variable to the value defined
-in your .emacs file or, if your .emacs file does not define a value, to
-the value defined by the JDE."
+ "Load the project file(s) for the Java source file in the current
+buffer. Search for all the project file first in the directory
+tree containing the current source buffer. If any files are found,
+first reset all variables to their startup values. Then load
+the project files starting with the topmost in the tree.
+If no project files are found, set the JDE variables to their
+Emacs startup values."
(interactive)
- (let ((prj-file (jde-find-project-file default-directory)))
- (if prj-file
- (load-file prj-file)
- (jde-set-variables-init-value))))
+ (let ((prj-files (jde-find-project-files default-directory)))
+ (if prj-files
+ (progn
+ (jde-set-variables-init-value)
+ (loop for file in prj-files do
+ (let ((jde-loading-project file))
+ (jde-log-msg "jde-load-project-file: Loading %s" file)
+ ;; reset project file version
+ (setq jde-loaded-project-file-version nil)
+ (load-file file))))
+ (jde-set-variables-init-value t))))
(defun jde-load-all-project-files ()
@@ -994,15 +1208,11 @@
(message "%s" "Project file not found."))))
-(defun jde-save-delete (symbol)
- "Delete the call to SYMBOL from project file.
+(defun jde-save-delete (symbol buffer)
+ "Delete the call to SYMBOL from project file in BUFFER.
Leave point at the location of the call, or after the last expression."
(save-excursion
- (let ((project-file (or
- (jde-find-project-file default-directory)
- (concat "./" jde-project-file-name))))
- (set-buffer (find-file-noselect project-file)))
-
+ (set-buffer buffer)
(goto-char (point-min))
(catch 'found
(while t
@@ -1019,63 +1229,219 @@
(unless (bolp)
(princ "\n"))))
+(defun jde-symbol-p (symbol)
+ "Returns non-nil if SYMBOL is a JDE variable."
+ (and (get symbol 'custom-type)
+ (or (string-match "^bsh-" (symbol-name symbol))
+ (string-match "^jde-" (symbol-name symbol)))))
+
(defvar jde-symbol-list nil
- "A list of jde variables which are processed by jde-save-variables")
+ "*A list of jde variables which are processed by `jde-save-project'.")
(defun jde-symbol-list ()
- "Return a list of variables processed by jde-save-variables.
-The first time this is called, the list is saved in jde-symbol-list"
+ "Return a list of variables processed by `jde-save-project'.
+The first time this is called, the list is saved in jde-symbol-list."
(or jde-symbol-list
(mapatoms
(lambda (symbol)
- (if (and (string-match "jde-" (symbol-name symbol))
- (get symbol 'custom-type))
+ (if (jde-symbol-p symbol)
(setq jde-symbol-list (cons symbol jde-symbol-list))))))
jde-symbol-list)
-
-(defun jde-save-variables ()
- "Save all JDE variables in project file."
- (jde-save-delete 'jde-set-project-name)
- (jde-save-delete 'jde-set-variables)
- (let ((standard-output (get-buffer jde-project-file-name)))
- (unless (bolp)
- (princ "\n"))
+(defun jde-set-project-name (name)
+ (put 'jde-project-name 'customized-value (list name))
+ (setq jde-project-name name))
- (princ "(jde-set-project-name ")
- (prin1 jde-project-name)
+(defun jde-put-project (symbol project value)
+ "Stores a new value for SYMBOL in PROJECT, or overwrites any
+existing value."
+ (let ((proj-alist (get symbol 'jde-project)))
+ (if (null proj-alist)
+ (put symbol 'jde-project (list (cons project (list value))))
+ (if (assoc project proj-alist)
+ (setcdr (assoc project proj-alist) (list value))
+ (put symbol 'jde-project (pushnew (cons project (list value)) proj-alist))))))
+
+(defun jde-get-project (symbol project)
+ "Gets the value for SYMBOL that is associated with PROJECT, or nil
+if none. To test if SYMBOL has any value for PROJECT, use
+`jde-project-present-p'."
+ (car-safe (cdr-safe (assoc project (get symbol 'jde-project)))))
+
+(defun jde-project-present-p (symbol project)
+ "Returns non-nil if SYMBOL has a value for PROJECT."
+ (assoc project (get symbol 'jde-project)))
+
+(defun jde-save-open-buffer (project)
+ "Creates a new buffer or opens an existing buffer for PROJECT."
+ (let ((auto-insert nil) ; turn off auto-insert when
+ buffer standard-output) ; creating a new file
+ (setq buffer (find-file-noselect project))
+ (setq standard-output buffer)
+ (save-excursion
+ (set-buffer buffer)
+ (goto-char (point-min))
+ (jde-save-delete 'jde-project-file-version buffer)
+ (delete-blank-lines)
+ (jde-save-delete 'jde-set-variables buffer)
+ (delete-blank-lines)
+ (jde-save-delete 'jde-set-project-name buffer)
+ (delete-blank-lines))
+ (princ "(jde-project-file-version ")
+ (prin1 jde-project-file-version)
(princ ")\n")
+ (princ "(jde-set-variables")
+ (jde-log-msg "jde-save-open-buffer: Opening buffer for %s" project)
+ buffer))
+
+(defun jde-save-close-buffer (project)
+ "Saves and closes the buffer associated with PROJECT."
+ (let* ((buffer (find-if (lambda (buf)
+ (string= project (buffer-file-name buf)))
+ (buffer-list)))
+ (standard-output buffer))
+ (if buffer
+ (progn
+ (princ ")\n")
+ (save-excursion
+ (set-buffer buffer)
+ (save-buffer))
+ (jde-log-msg "jde-save-close-buffer: Closing buffer for %s" project)
+ (kill-buffer buffer))
+ (jde-log-msg "jde-save-close-buffer: Unable to find buffer for %s"
project))))
+
+(defun jde-save-variable (symbol projects)
+ "Saves all of the values of SYMBOL for each project file mentioned
+in PROJECTS."
+ (mapc
+ (lambda (project)
+ (if (and (not (string= (car project) "default"))
+ (member (car project) projects))
+ (let ((buffer (find-if (lambda (buf)
+ (string= (car project) (buffer-file-name buf)))
+ (buffer-list)))
+ standard-output)
+ (if (null buffer)
+ (setq standard-output (setq buffer (jde-save-open-buffer (car project))))
+ (setq standard-output buffer))
+ (jde-log-msg "jde-save-variable: Saving %S in %s" symbol (car project))
+ (princ "\n '(")
+ (princ symbol)
+ (princ " ")
+ (prin1 (custom-quote (car (cdr project))))
+ (princ ")"))))
+ (get symbol 'jde-project)))
+
+(defun jde-save-needs-saving-p (symbol projects)
+ "Function used internally by the project saving mechanism to
+determine whether or not to save a symbol in a project file. If there
+are settings to be saved, this function also resolves which project
+should receive the customized values."
+ (unless (= (length projects) 0)
+ (let ((value (symbol-value symbol))
+ val-to-save
+ current-proj proj-iter)
+ (setq current-proj (car projects))
+ (cond
+ ;; CASE: current value changed from saved value in current
+ ;; project
+ ((and (jde-project-present-p symbol current-proj)
+ (not (equal value (jde-get-project symbol current-proj))))
+ (jde-log-msg "jde-save-needs-saving-p: changed value for %S in project
`%s'"
+ symbol current-proj)
+ (jde-put-project symbol current-proj value)
+ t)
+ ;; CASE: no value for symbol in current project - check all
+ ;; parent projects (plus default) to see if value has changed
+ ((and (not (jde-project-present-p symbol current-proj))
+ (progn
+ (setq val-to-save value)
+ (setq proj-iter (cdr projects))
+ (while (and proj-iter
+ (not (jde-project-present-p symbol (car proj-iter))))
+ (setq proj-iter (cdr proj-iter)))
+ (if proj-iter
+ (not (equal value
+ (jde-get-project symbol (car proj-iter))))
+ (setq proj-iter (list "default"))
+ (setq val-to-save (eval (car (get symbol 'customized-value))))
+ (and val-to-save
+ (not (equal val-to-save
+ (and (jde-project-present-p symbol (car proj-iter))
+ (jde-get-project symbol (car proj-iter)))))))))
+ (jde-log-msg "jde-save-needs-saving-p: override value %S from parent `%s' in
project `%s'"
+ symbol (car proj-iter) current-proj)
+ (jde-put-project symbol current-proj val-to-save)
+ t)
+ ;; CASE: current value same as value in the deepest project that
+ ;; holds that value - re-save it
+ ((progn
+ (setq proj-iter projects)
+ (while (and proj-iter
+ (not (jde-project-present-p symbol (car proj-iter))))
+ (setq proj-iter (cdr proj-iter)))
+ (if proj-iter
+ (equal value (jde-get-project symbol (car proj-iter)))))
+ (jde-log-msg "jde-save-needs-saving-p: original value for %S in project
`%s'"
+ symbol (car proj-iter))
+ t)))))
+
+(defun jde-save-project-internal (projects)
+ (let ((projects-reversed (nreverse projects)))
+ (jde-log-msg "jde-save-project-internal: projects: %S" projects-reversed)
+ (mapc 'jde-save-open-buffer projects-reversed)
+ (mapc (lambda (symbol)
+ (if (jde-save-needs-saving-p symbol projects-reversed)
+ (jde-save-variable symbol projects-reversed)))
+ (jde-symbol-list))
+ (mapc 'jde-save-close-buffer projects-reversed)))
- (princ "(jde-set-variables ")
- (mapcar
- (lambda (symbol)
- (when
- (and (string-match "jde-" (symbol-name symbol))
- (get symbol 'custom-type))
- (let ((value (symbol-value symbol)))
- (princ "\n '(")
- (princ symbol)
- (princ " ")
- (prin1 (custom-quote value))
- ;; Check whether the user has changed the value of this
- ;; variable in a customization buffer. If so, save flag
- ;; so that custom knows that this value differs from
- ;; standard value.
- (if (get symbol 'customized-value)
- (princ " t)")
- (princ ")"))
- )))
- (jde-symbol-list))
- (princ ")")
- (save-excursion
- (set-buffer (get-buffer jde-project-file-name))
- (unless (looking-at "\n")
- (princ "\n"))
- (save-buffer))
- (kill-buffer (get-buffer jde-project-file-name))))
+;;;###autoload
+(defun jde-save-project ()
+ "Saves source file buffer options in one or more project files.
+This command provides an easy way to create and update a project file
+for a Java project. Simply open a source file, set the desired
+options, using the JDE Options menu, then save the settings in the
+project file, using this command. Now, whenever you open a source
+file from the same directory tree, the saved settings will be restored
+for that file."
+ (interactive)
+ (let ((project-file-paths (jde-find-project-files default-directory)))
+ (if (not project-file-paths)
+ (setq project-file-paths
+ (list (expand-file-name jde-project-file-name
+ (read-file-name "Save in directory: "
+ default-directory
+ default-directory)))))
+ (jde-save-project-internal project-file-paths)))
-(defun jde-set-project-name (name)
- (setq jde-project-name name))
+;;;###autoload
+(defun jde-create-new-project (new-dir)
+ "Creates a new JDE project file in directory NEW-DIR, saving any
+current customized variables. If a project file already exists in the
+given directory, the project is simply re-saved. This functions the
+same as `jde-save-project' when no project files can be found for the
+current source file. But, if there already exist projects somewhere
+along the path, this command unconditionally creates a project file in
+the directory specified, thus allowing the user to create and maintain
+hierarchical projects."
+ (interactive "DCreate new project in directory: ")
+ (let ((prj-file (expand-file-name jde-project-file-name new-dir))
+ (projects (jde-find-project-files new-dir)))
+ (if (not (member prj-file projects))
+ ;; create empty project file if none found
+ (let* ((auto-insert nil) ; disable auto-insert
+ (standard-output (find-file-noselect prj-file))
+ (message-log-max nil)) ; disable message log
+ (princ "(jde-project-file-version ")
+ (prin1 jde-project-file-version)
+ (princ ")\n(jde-set-variables)\n")
+ (save-excursion
+ (set-buffer standard-output)
+ (save-buffer))
+ (kill-buffer standard-output)
+ (setq projects (nconc projects (list prj-file)))))
+ (jde-save-project-internal projects)))
(defun jde-set-variables (&rest args)
"Initialize JDE customization variables.
@@ -1093,85 +1459,42 @@
(let* ((symbol (nth 0 entry))
(value (nth 1 entry))
(customized (nth 2 entry))
- (set (or (get symbol 'custom-set) 'set-default)))
- (if customized
+ (set (or (and (local-variable-if-set-p symbol nil) 'set)
+ (get symbol 'custom-set)
+ 'set-default)))
+ (if (or customized
+ jde-loaded-project-file-version)
(put symbol 'customized-value (list value)))
+ (if (boundp 'jde-loading-project)
+ (progn
+ (jde-log-msg "jde-set-variables: Loading %S from project %s" symbol
+ (symbol-value 'jde-loading-project))
+ (jde-put-project symbol
+ (symbol-value 'jde-loading-project)
+ (eval value)))
+ (jde-log-msg "jde-set-variables: Loading %S from unknown project"
symbol))
(when (default-boundp symbol)
- ;; Something already set this, overwrite it
- (funcall set symbol (eval value)))
+ ;; Something already set this, overwrite it
+ (funcall set symbol (eval value)))
(setq args (cdr args)))))))
-(defun jde-set-variables-init-value ()
+(defun jde-set-variables-init-value (&optional msg)
"Set each JDE variable to the value it has at Emacs startup."
(interactive)
- (message "Setting JDE variables to startup values...")
+ (if (or (interactive-p) msg)
+ (message "Setting JDE variables to startup values..."))
(mapcar
(lambda (symbol)
- (when
- (and (string-match "jde-" (symbol-name symbol))
- (get symbol 'custom-type))
- (let ((saved-val (get symbol 'saved-value))
- (std-val (get symbol 'standard-value))
- (set (or (get symbol 'custom-set) 'set-default)))
- (if saved-val
- (funcall set symbol (eval (car saved-val)))
- (funcall set symbol (eval (car std-val)))))))
- (jde-symbol-list)))
-
-;;;###autoload
-(defun jde-save-project (proj-name)
- "Saves local source file buffer options in project file.
-This command provides an easy way to create and update a
-project file for a Java project. Simply open a source file,
-set the desired options, using the JDE Options menu, then
-save the settings in the project file, using this command.
-Now, whenever you open a source file from the same directory
-tree, the saved settings will be restored for that file."
- (interactive
- (list
- (let (prompt)
- (if (string= jde-project-name "")
- (setq prompt "Enter project name: ")
- (setq prompt
- (format "Enter project name (%s): "
- jde-project-name)))
- (read-string prompt))))
- (unless (string= proj-name "")
- (setq jde-project-name proj-name))
- (jde-save-variables))
-
-(defun jde-convert-prj-file (file)
-"Converts a pre-JDE-2.0.7 project file to JDE-2.0.7 format.
-Note: old project files did not preserve information about
-whether a saved value differed from the standard (JDE-defined)
-value of a variable. Thus, all values are saved in the
-converted file as though they were standard values. This means
-that when JDE reloads the file, a custom buffer will customized
-values as though they were standard. If you want to restore
-a customized value to a standard value, simply make some
-innocuous edit to the customized value and choose
-'Set for current session' from the customization buffer's
-Set menu. Custom will then enable the Set menu option that
-allows you to restore the value to its default value."
- (interactive "F")
- (let ((olddef (symbol-function 'jde-set-variables))
- (newdef
- (lambda (&rest args)
- (while args
- (let ((entry (car args)))
- (if (listp entry)
- (let* ((symbol (nth 0 entry))
- (value (nth 1 entry))
- (set (or (get symbol 'custom-set) 'set-default)))
- (when (default-boundp symbol)
- ;; Something already set this, overwrite it
- (funcall set symbol value))
- (setq args (cdr args)))))))))
- (defalias 'jde-set-variables newdef)
- (require 'cus-edit)
- (load-file file)
- (jde-save-project jde-project-name)
- (defalias 'jde-set-variables olddef)))
+ (let ((val-to-set (eval (car (or (get symbol 'saved-value)
+ (get symbol 'standard-value)))))
+ (set (or (get symbol 'custom-set) 'set-default)))
+ (if (or (get symbol 'customized-value)
+ (get symbol 'jde-project))
+ (funcall set symbol val-to-set))
+ (put symbol 'customized-value nil)
+ (put symbol 'jde-project nil)
+ (jde-put-project symbol "default" val-to-set)))
+ (jde-symbol-list)))
;; Code to update JDE customization variables when a user switches
;; from a Java source buffer belonging to one project to a buffer
@@ -1204,25 +1527,23 @@
(defcustom jde-entering-java-buffer-hook
'(jde-reload-project-file
jde-which-method-update-on-entering-buffer)
-"*Lists functions to run when entering a Java source buffer."
+ "*Lists functions to run when entering a Java source buffer."
:group 'jde-project
:type 'hook)
-
-(setq jde-current-buffer (current-buffer))
+(defvar jde-current-buffer (current-buffer)
+ "*Internal JDE variable that holds the current active buffer.")
(defun jde-detect-java-buffer-activation ()
-"Detects when a user activates a buffer.
+ "Detects when a user activates a buffer.
If the activated buffer is a Java buffer, runs the
`jde-entering-java-buffer-hook' hooks."
(let ((curr-buff (current-buffer)))
- (if (not
- (equal curr-buff jde-current-buffer))
+ (if (not (equal curr-buff jde-current-buffer))
(progn
(setq jde-current-buffer curr-buff)
(if (eq major-mode 'jde-mode)
- (run-hooks 'jde-entering-java-buffer-hook))))))
-
+ (run-hooks 'jde-entering-java-buffer-hook))))))
(defun jde-count-open-java-buffers ()
"Returns non-nil if any java buffers are open."
@@ -1287,10 +1608,11 @@
(let* ((jde-dir (jde-find-jde-doc-directory))
(jde-help
(if jde-dir
- (if (and jde-xemacsp
- (locate-data-directory "jde"))
- (expand-file-name "jde-ug.html" jde-dir)
- (expand-file-name "doc/html/jde-ug/jde-ug.html" jde-dir)))))
+; XEmacs change - this no longer appears to be necessary
+; (if (and jde-xemacsp
+; (locate-data-directory "jde"))
+; (expand-file-name "jde-ug.html" jde-dir)
+ (expand-file-name "doc/html/jde-ug/jde-ug.html" jde-dir))))
(if (and
jde-help
(file-exists-p jde-help))
@@ -1336,23 +1658,24 @@
(save-excursion
(goto-char (point-max))
(let* ((debug-buffer (get-buffer "*JDEbug*"))
- (messages-buffer
- (get-buffer
- (if jde-xemacsp " *Message-Log*" "*Messages*")))
- (backtrace-buffer (get-buffer "*Backtrace*"))
- (process
- (let ((proc (jde-dbs-get-target-process)))
- (if (not proc)
- (let ((dead-proc-alist
- (oref jde-dbs-the-process-morgue proc-alist)))
- (if dead-proc-alist
- (setq proc (cdr (car dead-proc-alist))))))
- proc))
- (cli-buffer (if (and process (slot-boundp process 'cli-buf))
- (oref process cli-buf)))
- (locals-buffer (if (and process (slot-boundp process 'locals-buf))
- (oref process locals-buf)))
- )
+ (messages-buffer
+ (get-buffer
+ (if jde-xemacsp " *Message-Log*" "*Messages*")))
+ (backtrace-buffer (get-buffer "*Backtrace*"))
+ (jde-log-buffer (get-buffer "*jde-log*"))
+ (process
+ (let ((proc (jde-dbs-get-target-process)))
+ (if (not proc)
+ (let ((dead-proc-alist
+ (oref jde-dbs-the-process-morgue proc-alist)))
+ (if dead-proc-alist
+ (setq proc (cdr (car dead-proc-alist))))))
+ proc))
+ (cli-buffer (if (and process (slot-boundp process 'cli-buf))
+ (oref process cli-buf)))
+ (locals-buffer (if (and process (slot-boundp process 'locals-buf))
+ (oref process locals-buf)))
+ )
;;insert the contents of the debug buffer if it is there.
(if debug-buffer
@@ -1399,8 +1722,17 @@
(insert-buffer messages-buffer)
(goto-char (point-max))
(insert-string "\n\n\nEnd Insert *Messages* buffer" ))
- (insert-string "\n\n\nThere was no *Messages* buffer" )))
+ (insert-string "\n\n\nThere was no *Messages* buffer" ))
+ ;;insert the contents of the jde-log buffer if it is there.
+ (if jde-log-buffer
+ (progn
+ (insert-string "\n\n\nThe contents of the *jde-log* buffer were\n\n")
+ (insert-buffer jde-log-buffer)
+ (goto-char (point-max))
+ (insert-string "\n\n\nEnd Insert *jde-log* buffer" ))
+ (insert-string "\n\n\nThere was no *jde-log* buffer" )))
+
(when process-environment
(insert-string "\n\n\nProcess environment: \n\n")
(insert-string (mapconcat (lambda (var) var) process-environment
"\n")))
@@ -1566,16 +1898,11 @@
(interactive)
(let ((load-path (append '(".") load-path))
- (buffer-directory (file-name-directory (buffer-file-name)))
(jde-lisp-directory (expand-file-name "lisp"
(jde-find-jde-data-directory))))
(save-excursion
- (dired jde-lisp-directory)
(mapcar
(function jde-compile-file-if-necessary)
- (mapcar
- (lambda (file)
- (expand-file-name file jde-lisp-directory))
- (directory-files jde-lisp-directory))))))
+ (directory-files jde-lisp-directory t)))))
;; Provided for XEmacs compatibility.
(if (not (fboundp 'subst-char-in-string))
@@ -1590,19 +1917,200 @@
(aset newstr i tochar)))
newstr)))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; ;;
+;; Find command ;;
+;; ;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defcustom jde-find-case-sensitive nil
+ "*Specifies whether recursive file search are case-sensitive.
+If non-nil, the search made with 'jde-grep' would be case-sensitive, otherwise
+case difference would be ignored."
+ :group 'jde-project
+ :type 'boolean
+)
+(defcustom jde-find-file-regexp '("*.java")
+ "*Specifies the file pattern to select files to be searched.
+This regular expression will be applied to the find command used to select the
+files on which the grep will be applied. By default it selects all java files,
+but one could modify it to also search other files such as jsp files. The
+syntaxt should follow the one supported by GNU find in its -name option."
+ :group 'jde-project
+ :type '(repeat (string :tag "Find regexg"))
+)
+
+(defun jde-find (&optional regexp)
+ "Find a regular expression REGEXP in all of the current JDE project files.
+It suggests the path to use to search file. By default this is the first defined
+value of `jde-db-source-directories', `jde-compile-option-sourcepath',
+`jde-compile-option-classpath', or `jde-global-classpath'
+This command can be customized using the `jde-find-case-sensitive' variable to
+control case sensitivity and `jde-find-file-regexp' to choose the type of files
+to be searched. This command requires that the Unix grep and find utilities be
+installed on your system in the Emacs command path. The Cygwin package contains
+Windows versions of both utilities."
+ (interactive)
+ (if (not (executable-find
+ ;; Hack required by faulty XEmacs implementation of executable-find.
+ (if (eq system-type 'windows-nt) "grep.exe" "grep")))
+ (error "This command requires the Unix grep utility."))
+ (if (not (executable-find
+ (if (eq system-type 'windows-nt) "find.exe" "find")))
+ (error (list "This command requires the Unix find utility.")))
+ (let* ((grep-roots
+ (read-from-minibuffer
+ "Recursive grep from directories: "
+ (cons
+ (mapconcat
+ 'jde-normalize-path
+ (or
+ jde-db-source-directories
+ jde-compile-option-sourcepath
+ jde-compile-option-classpath
+ jde-global-classpath)
+ " ")
+ 0)
+ nil nil 'jde-grep-root-history))
+ (case-sensitive-option
+ (if jde-find-case-sensitive
+ ""
+ "-i"))
+ (regexp
+ (if (and (boundp 'regexp) regexp)
+ regexp
+ (read-from-minibuffer
+ "Search for regexp: "
+ (if (boundp 'jde-grep-regexp-history)
+ (car jde-grep-regexp-history)
+ nil)
+ nil nil 'jde-grep-regexp-history)))
+ ;;file option would be like -name "regexp1" -or -name "regexp2"
...
+ (file-regexp
+ (mapconcat
+ (lambda (x)
+ (format "-name \"%s\"" x))
+ jde-find-file-regexp
+ " -or "))
+ (whole-cmd
+ (format "find %s %s -type f | xargs grep %s -n \"%s\" /dev/null"
+ grep-roots
+ file-regexp
+ case-sensitive-option
+ regexp)))
+ (grep whole-cmd)))
+
+
+
(provide 'jde)
;; Change History
;;
;; $Log: jde.el,v $
-;; Revision 1.5 2001/02/25 05:10:13 paulk
-;; Update for JDE 2.2.7beta3
+;; Revision 1.170 2001/05/23 03:33:56 paulk
+;; Added require for semantic-load. Thanks to David Ponce.
+;;
+;; Revision 1.169 2001/05/22 02:54:14 paulk
+;; Adds jde-find command. Thanks to "Guillaume Berche"
<guillaume.berche(a)eloquant.com>.
+;;
+;; Revision 1.168 2001/05/19 02:36:01 paulk
+;; Updated to support semantic 1.4. Thanks to David Ponce.
+;;
+;; Revision 1.167 2001/04/27 04:52:10 paulk
+;; Fixes bug in jde-normalize-path's handling of paths that begin with ../. Thanks to
"Nick Sieger" <nsieger(a)bitstream.net> for this fix.
+;;
+;; Revision 1.166 2001/04/26 08:46:27 paulk
+;; jde-lib-directory-name can now be a regular expression that matches the name of
directories that contain zip or jar files.
+;;
+;; Revision 1.165 2001/04/25 03:23:26 paulk
+;; Fix Project->Auto Switch menu to work on XEmacs.
+;;
+;; Revision 1.164 2001/04/24 08:13:48 paulk
+;; Adds a new menu item, JDE->Project->Auto Switch, that toggles project context
switching on or off.
+;;
+;; Revision 1.163 2001/04/24 08:01:21 paulk
+;; Define new function jde-toggle-project-switching.
+;;
+;; Revision 1.162 2001/04/20 20:52:13 paulk
+;; Bug fix: JDE no longer overwrites local version of after-change-functions. Thanks to
David Ponce.
+;;
+;; Revision 1.161 2001/04/19 04:40:57 paulk
+;; Updated version number.
+;;
+;; Revision 1.160 2001/04/17 04:18:03 paulk
+;; XEmacs compatibility fix: pass nil third argument to local-variable-if-set-p. Thanks
to Nick Sieger.
;;
-;; Revision 1.4 2001/02/20 05:29:19 paulk
-;; JDE 2.27 updates
+;; Revision 1.159 2001/04/16 05:41:27 paulk
+;; - jde-build-classpath now optionally takes a symbol representing a string of paths.
+;; - Normalized JDK doc path.
+;; Thanks to Nick Sieger for both enhancements.
;;
+;; Revision 1.158 2001/04/11 03:13:55 paulk
+;; This is a major update to the JDE project file system to support hierarchical
+;; project files. The enhanced code remembers which project files set
+;; options and will save them back to the appropriate project
+;; file when the project is saved.
+;;
+;; When the values of variables are newly customized, the new value is saved in
+;; the deepest project file found relative to the buffer where
+;; `jde-save-project' is invoked. Thus, the buffer where you save the project
+;; controls in whic project file newly customized values are saved.
+;;
+;; The implementation boils down to associating a new property `jde-project'
+;; with each symbol that has been saved to a project file. The property's
+;; content is an alist of cons cells that look like ("<project file
path>"
+;; <saved value>).
+;;
+;; A side-effect of the changes is where do relative paths resolve to now
+;; that path-related options can be set by multiple project files? The project
+;; system solves that problem by resolving relative paths relative to the project
+;; file that defines the option.
+;;
+;; Thanks to "Nick Sieger" <nsieger(a)bitstream.net> for contributing
this
+;; enhancement.
+;;
+;; Revision 1.157 2001/04/11 02:33:42 paulk
+;; The JDE now replaces occurrences of lib directories in classpaths
+;; with the jar and zip files that those directories
+;; contain. This means that you no longer have to include
+;; jar and zip files explicitly in classpaths. See
+;; jde-expand-classpath-p and jde-lib-directory-name for details.
+;;
+;; Revision 1.156 2001/03/30 18:04:28 paulk
+;; Fix jde-save-variables to save overrides of variables customized in the user's
.emacs file. Thanks to Nick Sieger <nsieger(a)bitstream.net> for providing this fix.
+;;
+;; Revision 1.155 2001/03/30 08:46:29 paulk
+;; Implements hierarchical project files. The JDE saves only variables that have been
customized for the current session in project files. The JDE now loads project files in
the following manner. It first sets all the JDE variables to their Emacs startup values
(i.e., the default value or the value saved in your .emacs file). It then loads all the
project files in the directory tree containing the current source buffer, starting with
the topmost file. Thanks to Nick Sieger for contributing to this enhancement.
+;;
+;; Revision 1.154 2001/03/29 06:19:15 paulk
+;; - jde-save-project now prompts you to enter the directory in which to save a new
project file.
+;;
+;; - jde-save-project-in prompts you to enter the directory in which to save a new or
existing project file.
+;;
+;; Revision 1.153 2001/03/29 04:16:16 paulk
+;; Adds support for relative paths. The JDE now converts relative paths to absolute paths
by appending the relative path to the path of the project file for the current source
buffer.
+;;
+;; Revision 1.152 2001/03/29 02:44:32 paulk
+;; Replaced jde-find-exec with executable-find, which is defined by executable.el
available with both the Emacs and XEmacs distributions.
+;;
+;; Revision 1.151 2001/03/27 17:47:45 paulk
+;; Eliminate dependency on which package by including the function jde-find-exec and
replacing references to the which command with jde-find-exec. Thanks to
klaus.berndl(a)sdm.de for suggesting this change and providing the implementation of
jde-find-exec.
+;;
+;; Revision 1.150 2001/03/23 09:04:06 paulk
+;; Now update the method in the mode line during idle times instead of after every
keystroke. Thanks to Steven Monnier for suggesting this enhancement.
+;;
+;; Revision 1.149 2001/02/27 12:53:09 paulk
+;; Now initializes jde-mode-abbrev-table to ensure compatability with cc-mode 5.28.
Thanks to David Ponce for this fix.
+;;
+;; Revision 1.148 2001/02/25 04:14:55 paulk
+;; - Update docstring for jde-global-classpath.
+;; - Removed jde-path-to-string function because split-string does the same job.
+;;
+;; Revision 1.147 2001/02/21 05:53:13 paulk
+;; Added require for new jde-package package.
+;;
;; Revision 1.146 2001/02/20 05:09:04 paulk
;; The JDE now expands paths that begin with a tilde but not a period (.).
;;
@@ -1712,207 +2220,6 @@
;; Revision 1.114 2000/01/02 08:07:55 paulk
;; Added attach process commands.
;;
-;; Revision 1.113 1999/12/23 04:04:02 paulk
-;; * jde-mode now defines underscore as a word constituent to allow
-;; variable names to start with underscores.
-;; * Added Project menu
-;; * Added Project Files->Load and Load All commands
-;; * Added jde-project-context-switching-enabled-p variable.
-;; * Context-switching now suspended when JDEbug is running a debuggee process.
-;;
-;; Revision 1.112 1999/12/19 06:57:43 paulk
-;; Made buffer activation hook truly buffer local. Thanks to "Phillip
-;; Lord" <plord(a)hgmp.mrc.ac.uk> for this fix.
-;;
-;; Revision 1.111 1999/12/14 05:16:13 paulk
-;; Changed key binding for jde-help-class from C-c C-v C-h to C-c C-v C-w
-;; because C-h is a reserve binding. Thanks to Richard Y. Kim <ryk(a)coho.net> for
suggesing this change.
-;;
-;; Revision 1.110 1999/12/13 05:54:09 paulk
-;; Added jde-bug-vm-executable and jde-bug-jre-home variables.
-;; Fixed jde-dbs-launch-process command so that it fails gracefully.
-;;
-;; Revision 1.109 1999/11/28 07:01:23 paulk
-;; Changed key binding for jde-complete-at-point to C-c C-v C-.
-;;
-;; Revision 1.108 1999/11/27 05:13:50 paulk
-;; Added commands for tracing classes.
-;;
-;; Revision 1.107 1999/11/01 03:08:05 paulk
-;; Added jde-submit-bug-report contributed by Phillip Lord.
-;;
-;; Revision 1.106 1999/10/01 05:59:25 paulk
-;; Added jde-wiz-update-class-list function to the Wizards menu.
-;; Added jde-help-class to the Help menu.
-;;
-;; Revision 1.105 1999/09/30 04:48:53 paulk
-;; Cache jde variables to speed switching between projects. Enhancement
-;; provide by David Biesack.
-;;
-;; Revision 1.104 1999/09/17 06:51:07 paulk
-;; Fixed Wizards->Import Class menu item to invoke
-;; jde-wiz-find-and-import instead of jde-wiz-import.
-;;
-;; Revision 1.103 1999/09/08 05:40:47 paulk
-;; Updated debugger code to take advantage of new unbound slot capability
-;; of eieio.
-;;
-;; Revision 1.102 1999/09/05 04:37:24 paulk
-;; Fixed bug in jde-show-help function that prevented it from working
-;; with Internet Explorer on Windows/NT.
-;;
-;; Revision 1.101 1999/08/27 05:27:53 paulk
-;; Provided initial support for multiple processes.
-;; Fixed jde-find-data-directory to work on XEmacs with a standard
-;; JDE distribution.
-;; Ported breakpoint highlighting code to XEmacs. Still has bugs though.
-;; Now includes jde-db-option options on vm command-line for process.
-;;
-;; Revision 1.100 1999/08/24 06:29:43 paulk
-;; Reimplemented the constructor for jde-dbs-proc the right way. Renamed
-;; jde-bug-counter to jde-bug-breakpoint-counter.
-;;
-;; Revision 1.99 1999/08/23 03:52:01 paulk
-;; Updated jde-show-help function to reflect new location of user's guide
-;; in the JDE help hierarchy.
-;;
-;; Revision 1.98 1999/08/23 01:44:25 paulk
-;; Updated to use Eric Ludlam's eieio object system.
-;;
-;; Revision 1.97 1999/08/15 23:48:32 paulk
-;; Provided support for initial implementation of JDEbug.
-;;
-;; Revision 1.96 1999/06/27 01:04:14 paulk
-;; Changed release number to 2.1.6beta4.
-;;
-;; Revision 1.95 1999/06/26 00:15:09 paulk
-;; Kill project file buffer after saving to prevent cross-contamination of simultaneously
open project files.
-;;
-;; Revision 1.94 1999/06/22 21:16:24 paulk
-;; Added key binding for `jde-help-class'.
-;; Updated revision to 2.1.6beta3.
-;;
-;; Revision 1.93 1999/05/10 13:23:07 paulk
-;; Added require statement for jde-parse.
-;;
-;; Revision 1.92 1999/05/07 23:25:13 paulk
-;; Changed version number to 2.1.6beta1.
-;;
-;; Revision 1.91 1999/05/07 21:13:45 paulk
-;; Changed key binding C-c C-v C-z to invoke
-;; jde-wiz-find-and-import instead of jde-wiz-import.
-;;
-;; Changed jde-build to support interactive entry of make arguments.
-;;
-;; Revision 1.90 1999/03/10 18:56:43 paulk
-;; Fixed in bug in jde-find-jde-data-directory
-;;
-;; Revision 1.89 1999/03/10 17:00:09 paulk
-;; Changed version to 2.1.5.
-;;
-;; Revision 1.88 1999/02/26 15:56:38 paulk
-;; Version 2.1.5b4
-;;
-;; Revision 1.87 1999/02/17 19:17:11 paulk
-;; 2.1.5b3 version number.
-;;
-;; Revision 1.86 1999/02/15 01:15:09 paulk
-;; Updated version number.
-;;
-;; Revision 1.85 1999/02/12 15:26:09 paulk
-;; Added menu item (Wizards->Import Class) for generating import statements.
-;;
-;; Revision 1.84 1999/02/08 18:02:57 paulk
-;; *** empty log message ***
-;;
-;; Revision 1.83 1999/02/04 01:38:37 paulk
-;; Provided a fix for ensuring that key bindings are always set. The fix is
-;; to do a custom-initialize-reset on the jde-key-bindings variable in the jde-mode
-;; function. The jde-mode-map is updated with the key bindings as a side effect of
-;; resetting the variable.
-;;
-;; Revision 1.82 1999/02/04 01:22:23 paulk
-;; Fixed some keybindings. Also backed out Matthew Moore's fix for ensuring
-;; that jde-mode-keymap gets set at startup since it seems to break
-;; java-mode. I'll try to come up with another fix later.
-;;
-;; Revision 1.81 1999/02/03 22:57:31 paulk
-;; *** empty log message ***
-;;
-;; Revision 1.80 1999/02/03 01:54:46 paulk
-;; Minor fix to debug applet item.
-;;
-;; Revision 1.79 1999/02/03 01:12:11 paulk
-;; Fixed a bug in the initialization code for jde-key-bindings.
-;; Thanks to Matthew Moore <matthew.moore(a)Schwab.COM> for this fix.
-;;
-;; Added a menu item for debugging applets.
-;;
-;; Revision 1.78 1999/01/15 22:11:04 paulk
-;; Some XEmacs patches that I missed.
-;;
-;; Revision 1.77 1999/01/15 21:57:48 paulk
-;; Added XEmacs compatibility changes from Andy Piper.
-;;
-;; Revision 1.76 1998/12/09 00:56:31 paulk
-;; Put jde-compile variables in a new file jde-compile.el.
-;;
-;; Revision 1.75 1998/11/27 10:10:03 paulk
-;; Updated JDE version number to 2.1.3.
-;;
-;; Revision 1.74 1998/11/22 18:13:57 paulk
-;; Added menu items for the BeanShell and method override and interface wizards.
-;;
-;; Revision 1.73 1998/09/13 02:01:53 paulk
-;; Fixed a small bug in key binding code.
-;;
-;; Revision 1.72 1998/09/13 01:49:35 paulk
-;; Added support for customization of JDE key bindings via the
-;; variable jde-key-bindings.
-;;
-;; Revision 1.71 1998/09/13 00:32:48 paulk
-;; Added System.out.println template to the Generate menu.
-;;
-;; Revision 1.70 1998/09/07 02:50:31 paulk
-;; This version includes the latest version of jde-gen.el, which was inadvertently
-;; replaced by an older version in the last release. This version also includes
-;; a newer version of speedbar.el that seems to work better with NT/Emacs 20.3.1
-;; than the one that comes with the 20.3.1 distribution.
-;;
-;; Revision 1.69 1998/08/28 12:56:06 paulk
-;; *** empty log message ***
-;;
-;; Revision 1.68 1998/08/28 12:52:52 paulk
-;; Updated version number.
-;;
-;; Revision 1.67 1998/07/28 03:15:33 paulk
-;; Removed a diagnostic message.
-;;
-;; Revision 1.66 1998/07/28 03:12:40 paulk
-;; Updated version number to 2.0.9.
-;;
-;; Revision 1.65 1998/07/28 03:12:05 paulk
-;; Fixed the following project file bugs:
-;;
-;; * JDE does not store the project name in the project file.
-;; * JDE does not save variables whose value is nil.
-;; * JDE does not reset variables to initial values when
-;; switching to a buffer that is not part of a project.
-;;
-;; Revision 1.64 1998/07/22 00:10:07 paulk
-;; Now requires cus-edit. This fixes custom-quote is void bug.
-;;
-;; Fixed bug in jde-set-variables that prevented loading of
-;; project files in the new format.
-;;
-;; Revision 1.63 1998/07/10 00:49:24 paulk
-;; Changed jde-save-variables to mark variables that have been customized\n in the
current session. Changed jde-set-variables to store the value\n of a customized variable
in the customized-value property of the\n variable. This enables Custom to recognize the
variable as customized.\n\n Added jde-convert-prj-file, a function that converts old
project files to \n \
-;; JDE-2.0.7 format.\n\n Fixed a bug in the function that finds the JDE documentation.
-;;
-;; Revision 1.62 1998/07/09 04:33:57 paulk
-;; Change the way that the JDE saves and restores project-specific values of
-;; customization variables to be compatible with custom. This fixes the bug
-;; that caused errors when loading customized JDE variables from a .emacs file.
;; .
;; .
;; .
@@ -1920,4 +2227,6 @@
;;
;; Revision 1.8 1997/06/18 17:20:00 paulk
;; Initial checkin.
-;;
\ No newline at end of file
+;;
+
+;; End of jde.el
Index: xemacs-packages/jde/lisp/jtags
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/jtags,v
retrieving revision 1.2
diff -u -r1.2 jtags
--- xemacs-packages/jde/lisp/jtags 2001/02/12 05:38:27 1.2
+++ xemacs-packages/jde/lisp/jtags 2001/08/15 05:28:04
@@ -1,6 +1,6 @@
#! /bin/sh
#
-# $Id: jtags,v 1.2 2001/02/12 05:38:27 paulk Exp $
+# $Id: jtags,v 1.11 2001/01/06 05:29:58 paulk Exp $
#
# Usage: jtags [-h | srcdir]
#
@@ -147,9 +147,6 @@
# History:
#
# $Log: jtags,v $
-# Revision 1.2 2001/02/12 05:38:27 paulk
-# JDE 2.2.7
-#
# Revision 1.11 2001/01/06 05:29:58 paulk
# Add "\." below to the definition of class_type so
# that methods whose return type included a period (e.g, Foo.Bar)
Index: xemacs-packages/jde/lisp/jtags.csh
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/jde/lisp/jtags.csh,v
retrieving revision 1.2
diff -u -r1.2 jtags.csh
--- xemacs-packages/jde/lisp/jtags.csh 2001/02/12 05:38:27 1.2
+++ xemacs-packages/jde/lisp/jtags.csh 2001/08/15 05:28:04
@@ -1,6 +1,6 @@
#! /bin/csh
#
-# $Id: jtags.csh,v 1.2 2001/02/12 05:38:27 paulk Exp $
+# $Id: jtags.csh,v 1.6 2001/01/06 05:27:49 paulk Exp $
#
# Usage: jtags [-h | srcdir]
#
@@ -177,9 +177,6 @@
# History:
#
# $Log: jtags.csh,v $
-# Revision 1.2 2001/02/12 05:38:27 paulk
-# JDE 2.2.7
-#
# Revision 1.6 2001/01/06 05:27:49 paulk
# Add "\." below to the definition of class_type so
# that methods whose return type included a period (e.g, Foo.Bar)
Index: xemacs-packages/jde/lisp/senator-isearch.el
===================================================================
RCS file: senator-isearch.el
diff -N senator-isearch.el
--- /dev/null Tue Aug 14 14:29:33 2001
+++ senator-isearch.el Tue Aug 14 22:28:05 2001
@@ -0,0 +1,316 @@
+;;; senator-isearch.el --- SEmantic NAvigaTOR isearch support
+
+;; Copyright (C) 2000 by David Ponce
+
+;; Author: David Ponce <david(a)dponce.com>
+;; Maintainer: David Ponce <david(a)dponce.com>
+;; Created: 04 Dec 2000
+;; Version: 1.0
+;; Keywords: tools, syntax
+;; VC: $Id: senator-isearch.el,v 1.3 2001/01/03 15:41:11 david_ponce Exp $
+
+;; This file is not part of Emacs
+
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2, or (at
+;; your option) any later version.
+
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING. If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+;;
+;; This library improves isearch (and ishl) to allow overriding of the
+;; basic search functions used by `isearch-search' and
+;; `isearch-lazy-highlight-search' (or `ishl-search').
+;;
+;; This feature is needed by the SEmantic NAvigaTOR library to extend
+;; isearch with an incremental semantic search mode. When isearch is
+;; switched to this mode it searches only in language tokens in the
+;; current buffer.
+
+;; THIS CODE HAS ONLY BEEN TESTED WITH GNU EMACS 20.7, 21.0 AND XEMACS
+;; 21.1. GNU EMACS 20.7 REQUIRES ISHL 1.5 TO ENABLE ISEARCH LAZY
+;; HIGHLIGHTING.
+
+;;; Change Log:
+
+;; $Log: senator-isearch.el,v $
+;; Revision 1.3 2001/01/03 15:41:11 david_ponce
+;; Improved isearch lazy highlighting support.
+;;
+;; Revision 1.2 2000/12/08 16:18:32 david_ponce
+;; A bunch of XEmacs compatibility code!
+;;
+;; Revision 1.1 2000/12/05 11:15:14 david_ponce
+;; Initial revision needed by senator.el 1.7 (version 2.0) and above.
+;;
+
+;;; Code:
+
+;;;;
+;;;; Improvement of `isearch-search' to use a customizable core search
+;;;; function provider. This feature will probably be included in
+;;;; isearch starting with GNU Emacs 21.2.
+;;;;
+
+(defcustom isearch-search-handler-provider 'isearch-default-search-handler
+ "Function providing the basic search handlers.
+The default function `isearch-default-search-handler' provides one the
+built-ins `search-forward', `search-backward', `word-search-forward',
+`word-search-backward', `re-search-forward' or `re-search-backward'
+depending on current values of variables `isearch-forward',
+`isearch-regexp' and `isearch-word'. Any other user's defined basic
+search handler that `isearch-search-handler-provider' returns must
+accept the same arguments and have the same behaviour as the above
+built-in ones."
+ :group 'isearch
+ :type 'function)
+
+(defun isearch-default-search-handler ()
+ "Return the actual search function used by `isearch-search'.
+That is one of the built-in functions `search-forward',
+`search-backward', `word-search-forward', `word-search-backward',
+`re-search-forward' or `re-search-backward' depending on current
+values of variables `isearch-forward', `isearch-regexp' and
+`isearch-word'."
+ (cond (isearch-word
+ (if isearch-forward
+ 'word-search-forward
+ 'word-search-backward))
+ (isearch-regexp
+ (if isearch-forward
+ 're-search-forward
+ 're-search-backward))
+ (t
+ (if isearch-forward
+ 'search-forward
+ 'search-backward))))
+
+(cond ;; Compatibility between GNU Emacs and XEmacs
+
+ ((featurep 'xemacs) ;; XEmacs stuff
+
+ ;; Provide `isearch-update-ring' function (from 21.1.9 isearch-mode.el)
+ (defun isearch-update-ring (string &optional regexp)
+ "Add STRING to the beginning of the search ring.
+REGEXP says which ring to use."
+ (if (> (length string) 0)
+ ;; Update the ring data.
+ (if regexp
+ (if (not (setq regexp-search-ring-yank-pointer
+ (member string regexp-search-ring)))
+ (progn
+ (setq regexp-search-ring
+ (cons string regexp-search-ring)
+ regexp-search-ring-yank-pointer regexp-search-ring)
+ (if (> (length regexp-search-ring) regexp-search-ring-max)
+ (setcdr (nthcdr (1- regexp-search-ring-max) regexp-search-ring)
+ nil))))
+ (if (not (setq search-ring-yank-pointer
+ ;; really need equal test instead of eq.
+ (member string search-ring)))
+ (progn
+ (setq search-ring (cons string search-ring)
+ search-ring-yank-pointer search-ring)
+ (if (> (length search-ring) search-ring-max)
+ (setcdr (nthcdr (1- search-ring-max) search-ring) nil)))))))
+
+ ;; `isearch-search' from 21.1.9 isearch-mode.el
+ (defadvice isearch-search (around senator activate)
+ ;; Do the search with the current search string.
+ (isearch-message nil t)
+ (isearch-fix-case)
+ (condition-case lossage
+ (let ((inhibit-quit nil)
+ (case-fold-search isearch-case-fold-search))
+ (if isearch-regexp (setq isearch-invalid-regexp nil))
+ (setq isearch-success
+ (funcall
+ (if isearch-search-handler-provider
+ (funcall isearch-search-handler-provider)
+ (isearch-default-search-handler))
+ isearch-string nil t))
+ (setq isearch-just-started nil)
+ (if isearch-success
+ (setq isearch-other-end
+ (if isearch-forward (match-beginning 0) (match-end 0)))))
+
+ (quit (setq unread-command-event (character-to-event (quit-char)))
+ (setq isearch-success nil))
+
+ (invalid-regexp
+ (setq isearch-invalid-regexp (car (cdr lossage)))
+ (if (string-match
+ "\\`Premature \\|\\`Unmatched \\|\\`Invalid "
+ isearch-invalid-regexp)
+ (setq isearch-invalid-regexp (gettext "incomplete input")))))
+
+ (if isearch-success
+ nil
+
+ ;; If we're being run inside a keyboard macro, then the call to
+ ;; ding will signal an error (to terminate the macro). We must
+ ;; turn off isearch-mode first, so that we aren't still in isearch
+ ;; mode after the macro exits. Note that isearch-recursive-edit
+ ;; must not be true if a keyboard macro is executing.
+ (if (and executing-kbd-macro (not defining-kbd-macro))
+ (progn
+ (isearch-done)
+ (ding nil 'isearch-failed)))
+
+ ;; Ding if failed this time after succeeding last time.
+ (and (nth 3 (car isearch-cmds))
+ (ding nil 'isearch-failed))
+ (goto-char (nth 2 (car isearch-cmds)))))
+
+ ) ;; End of XEmacs stuff
+
+ (t ;; GNU Emacs stuff
+
+ ;; `isearch-search' from 20.7 (not changed in 21.0) isearch.el
+ (defadvice isearch-search (around senator activate)
+ ;; Do the search with the current search string.
+ (isearch-message nil t)
+ (if (and (eq isearch-case-fold-search t) search-upper-case)
+ (setq isearch-case-fold-search
+ (isearch-no-upper-case-p isearch-string isearch-regexp)))
+ (condition-case lossage
+ (let ((inhibit-point-motion-hooks search-invisible)
+ (inhibit-quit nil)
+ (case-fold-search isearch-case-fold-search)
+ (retry t))
+ (if isearch-regexp (setq isearch-invalid-regexp nil))
+ (setq isearch-within-brackets nil)
+ (while retry
+ (setq isearch-success
+ (funcall
+ (if isearch-search-handler-provider
+ (funcall isearch-search-handler-provider)
+ (isearch-default-search-handler))
+ isearch-string nil t))
+ ;; Clear RETRY unless we matched some invisible text
+ ;; and we aren't supposed to do that.
+ (if (or (eq search-invisible t)
+ (not isearch-success)
+ (bobp) (eobp)
+ (= (match-beginning 0) (match-end 0))
+ (not (isearch-range-invisible
+ (match-beginning 0) (match-end 0))))
+ (setq retry nil)))
+ (setq isearch-just-started nil)
+ (if isearch-success
+ (setq isearch-other-end
+ (if isearch-forward (match-beginning 0) (match-end 0)))))
+
+ (quit (isearch-unread ?\C-g)
+ (setq isearch-success nil))
+
+ (invalid-regexp
+ (setq isearch-invalid-regexp (car (cdr lossage)))
+ (setq isearch-within-brackets (string-match "\\`Unmatched \\["
+ isearch-invalid-regexp))
+ (if (string-match
+ "\\`Premature \\|\\`Unmatched \\|\\`Invalid "
+ isearch-invalid-regexp)
+ (setq isearch-invalid-regexp "incomplete input")))
+ (error
+ ;; stack overflow in regexp search.
+ (setq isearch-invalid-regexp (car (cdr lossage)))))
+
+ (setq ad-return-value
+ (if isearch-success
+ nil
+ ;; Ding if failed this time after succeeding last time.
+ (and (nth 3 (car isearch-cmds))
+ (ding))
+ (goto-char (nth 2 (car isearch-cmds))))))
+
+ ) ;; End of GNU Emacs stuff
+
+ ) ;; End of compatibility stuff
+
+;; Improvement of the isearch lazy highlighting feature to use the
+;; core search function provider. Lazy highlighting is part of isearch
+;; for GNU Emacs 21 or provided by the optional ishl.el library for
+;; Emacs 20. Not currently implemented for XEmacs (it seems that ishl
+;; does not work).
+(cond
+ (;; GNU Emacs 21 lazy highlighting
+ (fboundp 'isearch-lazy-highlight-search)
+
+ (defadvice isearch-lazy-highlight-search (around senator activate)
+ "Search ahead for the next or previous match, for lazy highlighting.
+Attempt to do the search exactly the way the pending isearch would."
+ (let ((case-fold-search isearch-case-fold-search))
+ (setq ad-return-value
+ (funcall (if isearch-search-handler-provider
+ (funcall isearch-search-handler-provider)
+ (isearch-default-search-handler))
+ isearch-string
+ (if isearch-forward
+ (if isearch-lazy-highlight-wrapped
+ isearch-lazy-highlight-start
+ nil)
+ (if isearch-lazy-highlight-wrapped
+ isearch-lazy-highlight-end
+ nil))
+ t))))
+
+ ;; Provide this function used by senator
+ (defun senator-lazy-highlight-update ()
+ "Force lazy highlight update."
+ (isearch-lazy-highlight-cleanup t)
+ (setq isearch-lazy-highlight-last-string nil)
+ (setq isearch-adjusted t)
+ (isearch-update))
+
+ ) ;; End of GNU Emacs 21 lazy highlighting
+
+ (;; GNU Emacs 20 lazy highlighting (from ishl.el 1.5)
+ (condition-case nil
+ (require 'ishl)
+ (error nil))
+
+ (defadvice ishl-search (around senator activate)
+ (let ((case-fold-search isearch-case-fold-search))
+ (setq ad-return-value
+ (funcall (if isearch-search-handler-provider
+ (funcall isearch-search-handler-provider)
+ (isearch-default-search-handler))
+ isearch-string
+ (if isearch-forward
+ (if ishl-wrapped ishl-start nil)
+ (if ishl-wrapped ishl-end nil))
+ t))))
+
+ ;; Provide this function used by senator
+ (defun senator-lazy-highlight-update ()
+ "Force lazy highlight update."
+ (ishl-cleanup t)
+ (setq ishl-last-string nil)
+ (setq isearch-adjusted t)
+ (isearch-update))
+
+ ) ;; End of GNU Emacs 20 lazy highlighting
+
+ (t ;; No lazy highlighting
+
+ ;; Ignore this function used by senator
+ (defalias 'senator-lazy-highlight-update 'ignore)
+
+ )
+
+ ) ;; End of isearch lazy highlight stuff
+
+(provide 'senator-isearch)
+
+;;; senator-isearch.el ends here
Index: xemacs-packages/jde/lisp/senator.el
===================================================================
RCS file: senator.el
diff -N senator.el
--- /dev/null Tue Aug 14 14:29:33 2001
+++ senator.el Tue Aug 14 22:28:05 2001
@@ -0,0 +1,1138 @@
+;;; senator.el --- SEmantic NAvigaTOR
+
+;; Copyright (C) 2000 by David Ponce
+
+;; Author: David Ponce <david(a)dponce.com>
+;; Maintainer: David Ponce <david(a)dponce.com>
+;; Created: 10 Nov 2000
+;; Version: 2.1
+;; Keywords: tools, syntax
+;; VC: $Id: senator.el,v 1.15 2001/01/03 16:09:28 david_ponce Exp $
+
+;; This file is not part of Emacs
+
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2, or (at
+;; your option) any later version.
+
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING. If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+;;
+;; This library defines commands and a minor mode to navigate between
+;; semantic language tokens in the current buffer. It uses Eric Ludlam's
+;; Semantic Bovinator tool to parse the buffer and find the language
+;; tokens.
+
+;; The commands `senator-next-token' and `senator-previous-token'
+;; navigate respectively to the token after or before the point. The
+;; command `senator-jump' directly jumps to a particular semantic
+;; symbol.
+
+;; Also, for each built-in search command `search-forward',
+;; `search-backward', `re-search-forward', `re-search-backward',
+;; `word-search-forward' and `word-search-backward', there is an
+;; equivalent `senator-<search-command>' defined which searches only
+;; in semantic token names.
+
+;; The command `senator-isearch-toggle-semantic-mode' toggles semantic
+;; search in isearch mode. When semantic search is enabled, isearch
+;; is restricted to token names.
+
+;; Finally, the library provides a `senator-minor-mode' to easily
+;; enable or disable the SEmantic NAvigaTOR stuff for the current
+;; buffer.
+
+;; The best way to use navigation commands is to bind them to keyboard
+;; shortcuts. Senator minor mode uses the common prefix key "C-c ,".
+;; The following default key bindings are provided when semantic minor
+;; mode is enabled:
+;;
+;; key binding
+;; --- -------
+;; C-c , n `senator-next-token'
+;; C-c , p `senator-previous-token'
+;; C-c , j `senator-jump'
+;; C-c , i `senator-isearch-toggle-semantic-mode'
+;;
+;; To install, put this file on your Emacs-Lisp load path and add
+;; (require 'senator)
+;; into your ~/.emacs startup file. To enable senator stuff in the
+;; current buffer use
+;; (senator-minor-mode 1).
+
+;; You can customize the `senator-step-at-token-ids' to navigate (and
+;; search) only between tokens of a particular type. (Such as
+;; functions and variables.)
+
+;; Customize `senator-step-at-start-end-token-ids' to stop at the
+;; start and end of the specified token types.
+
+;; To have a mode specific customization, do something like this in a hook:
+;;
+;; (add-hook 'mode-hook
+;; (lambda ()
+;; (setq senator-step-at-token-ids '(function variable))
+;; (setq senator-step-at-start-end-token-ids '(function))
+;; ))
+;;
+;; The above example specifies to navigate (and search) only between
+;; functions and variables, and to step at start and end of functions
+;; only.
+;;
+;; Any comments, suggestions, bug reports or upgrade requests are
+;; welcome. Please send them to David Ponce at <david(a)dponce.com>
+
+;;; History:
+
+;; $Log: senator.el,v $
+;; Revision 1.15 2001/01/03 16:09:28 david_ponce
+;; New version 2.1.
+;;
+;; Fixed a nasty typo in `senator-minor-mode'. `run-hooks' were missing
+;; a quotation before their arguments. Thanks to "Charles Rich"
+;; <rich(a)merl.com> who has reported this bug.
+;;
+;; Added new `senator-jump' command. Thanks to "Eric M. Ludlam"
+;; <zappo(a)ultranet.com> and "T. V. Raman" <tvraman(a)almaden.ibm.com>
for
+;; their help.
+;;
+;; Added new `senator-minor-mode-name' option to customize the name
+;; displayed in the modeline when senator minor mode is on.
+;;
+;; When semantic isearch mode is on it now appends "/si" to the senator
+;; minor mode name displayed in the modeline.
+;;
+;; Added new keyboard shortcut "\C-," to toggle semantic search in
+;; isearch mode.
+;;
+;; Some code improvements.
+;;
+;; Revision 1.14 2000/12/12 11:02:16 david_ponce
+;; `senator-mark-defun' now work on XEmacs too.
+;;
+;; Revision 1.13 2000/12/12 09:21:43 david_ponce
+;; Fixed a "side effect" bug with latest `beginning-of-defun' and
+;; `end-of-defun' advices. They caused font-lock, which uses
+;; beginning/end of defun to force a reparse. Thanks to "Eric M. Ludlam"
+;; <zappo(a)ultranet.com> for pointing this.
+;;
+;; Improved consistency with standard behaviour of `beginning-of-defun'
+;; (go to the beginning of the line where the defun starts) and
+;; `end-of-defun' (go to the beginning of the line following the end of
+;; the defun).
+;;
+;; Added useful advices for `narrow-to-defun', `mark-defun' and
+;; `c-mark-function'.
+;;
+;; Advices are enabled when the functions are called interactively and
+;; `senator-minor-mode' is enabled.
+;;
+;; Revision 1.12 2000/12/11 14:05:06 david_ponce
+;; Code cleanup and optimization.
+;; `senator-next-token' and `senator-previous-token' now correctly work
+;; when not binded to keyboard shortcuts.
+;; `beginning-of-defun' and `end-of-defun' advices no more need to be
+;; called interactively. So `narrow-to-defun' can use these advices when
+;; `senator-minor-mode' is enabled.
+;;
+;; Revision 1.11 2000/12/11 07:07:09 david_ponce
+;; Applied Eric Ludlam's patch. It adds a special face for senator to
+;; use for momentary highlight (requires latest semantic-util.el). If
+;; the user cancels the parse (C-g) when `senator-minor-mode'
+;; initializes, it doesn't kill the rest of the configuration. (Useful
+;; on a slow machine.)
+;;
+;; Revision 1.10 2000/12/08 16:18:32 david_ponce
+;; A bunch of XEmacs compatibility code!
+;;
+;; Revision 1.9 2000/12/07 09:20:21 david_ponce
+;; Applied Eric Ludlam's doc fix patch.
+;;
+;; Revision 1.8 2000/12/05 15:59:07 david_ponce
+;; Improved consistency with built-in search commands.
+;; New search commands like the ones in the Emacs Search menu.
+;; Added a menu to senator minor mode.
+;; The common prefix key in senator minor mode is now "C-c ,".
+;; Updated header comments.
+;; Some code cleanup.
+;;
+;; Revision 1.7 2000/12/05 11:13:19 david_ponce
+;; New major version 2.0 with [i]search feature and a senator minor mode.
+;; Added compatibility code between GNU Emacs 20.7 and 21.
+;;
+;; Revision 1.6 2000/11/28 12:44:47 david_ponce
+;; More performance improvements.
+;; New option `senator-highlight-found' to customize token highlighting.
+;;
+;; Revision 1.5 2000/11/27 13:24:17 david_ponce
+;; Fixed a serious performance problem in `senator-next-token' and
+;; `senator-previous-token'.
+;;
+;; Before searching for a next or previous token the point was just moved
+;; to respectively the next or previous character. Thus, during
+;; navigation, the buffer was explored character by character :-(. Now
+;; `senator-next-token' and `senator-previous-token' skip whole tokens
+;; (unless they are 'type tokens which may include sub tokens).
+;;
+;; Revision 1.4 2000/11/14 17:23:21 david_ponce
+;; Minor change to `senator-next-token' and `senator-previous-token' to
+;; return the token at point. Useful when calling these commands
+;; non-interactively.
+;;
+;; Revision 1.3 2000/11/14 13:04:26 david_ponce
+;; Improved navigation in semantic token where to step at start and end.
+;;
+;; - `senator-next-token' move the point to the end of token if it was at
+;; beginning or in the middle of the token.
+;;
+;; - `senator-previous-token' move the point to the beginning of token if
+;; it was at end or in the middle of the token.
+;;
+;; Revision 1.2 2000/11/10 17:11:15 david_ponce
+;; Fixed a little bug in `senator-previous-token' navigation.
+;;
+;; Revision 1.1 2000/11/10 16:04:20 david_ponce
+;; Initial revision.
+;;
+
+;;; Code:
+(require 'semantic)
+(require 'senator-isearch) ; Needed isearch advices
+
+(defgroup senator nil
+ "SEmantic NAvigaTOR."
+ :group 'semantic)
+
+(defcustom senator-minor-mode-name "Senator"
+ "*Name displayed in the modeline when senator minor mode is on."
+ :group 'senator
+ :type 'string)
+
+(defface senator-momentary-highlight-face '((((class color) (background dark))
+ (:background "gray30"))
+ (((class color) (background light))
+ (:background "gray70")))
+ "Face used to momentarilly highlight tokens."
+ :group 'senator)
+
+(defcustom senator-step-at-token-ids nil
+ "*List of token identifiers where to step.
+Token identifier is symbol 'variable, 'function, 'type, or other. If
+nil navigation steps at any token found. This is a buffer local
+variable. It can be set in a mode hook to get a specific langage
+navigation."
+ :group 'senator
+ :type '(repeat (symbol)))
+(make-variable-buffer-local 'senator-step-at-token-ids)
+
+(defcustom senator-step-at-start-end-token-ids '(function)
+ "*List of token identifiers where to step at start and end.
+Token identifier is symbol 'variable, 'function, 'type, or other. If
+nil navigation only step at beginning of tokens. This is a buffer
+local variable. It can be set in a mode hook to get a specific
+langage navigation."
+ :group 'senator
+ :type '(repeat (symbol)))
+(make-variable-buffer-local 'senator-step-at-start-end-token-ids)
+
+(defcustom senator-highlight-found t
+ "*If non-nil highlight tokens found.
+This option requires semantic 1.3 and above. This is a buffer
+local variable. It can be set in a mode hook to get a specific
+langage behaviour."
+ :group 'senator
+ :type 'boolean)
+(make-variable-buffer-local 'senator-highlight-found)
+
+(defcustom senator-separator-char ?#
+ "*Character separator used to compose token full name."
+ :group 'senator
+ :type 'character)
+(make-variable-buffer-local 'senator-separator-char)
+
+;;; Compatibility
+(cond ((fboundp 'semantic-momentary-highlight-token)
+ ;; semantic 1.3
+ (defun senator-parse ()
+ "Parse the current buffer and return the tokens where to navigate."
+ (semantic-bovinate-toplevel t))
+ )
+ (t
+ ;; semantic before 1.3
+ (defun semantic-momentary-highlight-token (&rest ignore)
+ "Highlight a token, removing highlighting when the user hits a key.
+Not implemented in this version of the Semantic Bovinator. IGNORE
+arguments and always return nil."
+ nil)
+ (defun semantic-find-nonterminal-by-overlay (&rest ignore)
+ "Find all nonterminals covering a position by using overlays.
+Not implemented in this version of the Semantic Bovinator. IGNORE
+arguments and always return nil."
+ nil)
+ (defun senator-parse ()
+ "Parse the current buffer and return the tokens where to navigate."
+ (semantic-bovinate-toplevel nil nil t))
+ ))
+
+;;;;
+;;;; Common functions
+;;;;
+
+(defun senator-momentary-highlight-token (token)
+ "Momentary highlight TOKEN.
+Does nothing if `senator-highlight-found' is nil or semantic version
+is bellow 1.3."
+ (and senator-highlight-found
+ (condition-case nil
+ (semantic-momentary-highlight-token
+ token 'senator-momentary-highlight-face)
+ (error (semantic-momentary-highlight-token token)))))
+
+(defun senator-message (&rest args)
+ "Call function `message' with ARGS without logging."
+ (let (message-log-max)
+ (apply 'message args)))
+
+(defun senator-step-at-start-end-p (token)
+ "Return non-nil if must step at start and end of TOKEN."
+ (if token
+ (let ((categ (semantic-token-token token)))
+ (and (not (eq categ 'type))
+ (memq categ senator-step-at-start-end-token-ids)))))
+
+(defun senator-skip-p (token)
+ "Return non-nil if must skip TOKEN."
+ (and token
+ senator-step-at-token-ids
+ (not (memq (semantic-token-token token)
+ senator-step-at-token-ids))))
+
+(defun senator-find-token-before (tokens pos comp &optional prev)
+ "Visit TOKENS and return the last one found at or before POS.
+COMP is the function used to compare a current visited token start
+position to POS. That is `>=' to return the token before POS or `>'
+to return the token at or before POS. PREV is the last token found or
+nil."
+ (let (token)
+ (while tokens
+ (setq token (car tokens))
+ (if (funcall comp (semantic-token-start token) pos)
+ (throw 'found prev))
+ (or (senator-skip-p token)
+ (setq prev token))
+ (if (eq (semantic-token-token token) 'type)
+ (setq prev (senator-find-token-before
+ (semantic-token-type-parts token) pos comp prev)))
+ (setq tokens (cdr tokens)))
+ prev))
+
+(defun senator-find-previous-token (tokens pos)
+ "Visit TOKENS and return the token before POS."
+ (catch 'found (senator-find-token-before tokens pos #'>=)))
+
+(defun senator-find-last-token (tokens pos)
+ "Visit TOKENS and return the token at or before POS."
+ (catch 'found (senator-find-token-before tokens pos #'>)))
+
+(defun senator-find-next-token (tokens pos)
+ "Visit TOKENS and return the token after POS."
+ (let (token found)
+ (while (and tokens (not found))
+ (setq token (car tokens))
+ (if (and (not (senator-skip-p token))
+ (or (and (senator-step-at-start-end-p token)
+ (> (semantic-token-end token) pos))
+ (> (semantic-token-start token) pos)))
+ (setq found token)
+ (if (eq (semantic-token-token token) 'type)
+ (setq found (senator-find-next-token
+ (semantic-token-type-parts token) pos))))
+ (setq tokens (cdr tokens)))
+ found))
+
+(defun senator-middle-of-token-p (pos token)
+ "Return non-nil if POS is between start and end of TOKEN."
+ (and (> pos (semantic-token-start token))
+ (< pos (semantic-token-end token))))
+
+(defun senator-full-token-name (token parent)
+ "Compose a full name from TOKEN name and names in its PARENT list.
+A `senator-separator-char' separates each token name. The parent list
+is in reverse order."
+ (let ((sep (char-to-string senator-separator-char))
+ (name ""))
+ (while parent
+ (setq name (concat (semantic-token-name (car parent))
+ sep
+ name)
+ parent (cdr parent)))
+ (concat name (semantic-token-name token))))
+
+(defun senator-last-name (full-name)
+ "Return the last name from FULL-NAME.
+That is the name after the last `senator-separator-char' or FULL-NAME
+itself if it does not contain any separator character."
+ (and (string-match (format "[%c]?\\([^%c]+\\)\\'"
+ senator-separator-char
+ senator-separator-char)
+ full-name)
+ (match-string 1 full-name)))
+
+(defun senator-completion-stream (stream parent full-name-p &optional top-level)
+ "Return a useful completion list from STREAM.
+That is a flat list of all tokens available. Prepend to each token
+name the name of tokens in its PARENT list if FULL-NAME-P is non-nil.
+This helps to distinguish between tokens in multiple top level type
+declarations or in sub type declarations. If TOP-LEVEL is non-nil the
+completion list will contain only tokens at top level. Otherwise all
+sub type tokens are included too."
+ (let (cs token)
+ (while stream
+ (setq token (car stream))
+ (setq stream (cdr stream))
+ (setq cs (cons (cons (senator-full-token-name token parent)
+ (cdr token))
+ cs))
+ (and (not top-level)
+ (eq (semantic-token-token token) 'type)
+ (setq cs (append cs (senator-completion-stream
+ (semantic-token-type-parts token)
+ (and full-name-p (cons token parent))
+ t)))))
+ cs))
+
+(defun senator-current-type-context ()
+ "Return tokens in the type context at point or nil if not found."
+ (let ((context (semantic-find-nonterminal-by-token
+ 'type (semantic-find-nonterminal-by-overlay))))
+ (if context
+ (semantic-token-type-parts
+ (nth (1- (length context)) context)))))
+
+(defun senator-completion-list (&optional in-context)
+ "Return a useful completion list from tokens in current buffer.
+That is a flat list of all tokens available. If IN-CONTEXT is not nil
+return only the top level tokens in the type context at point or the
+top level tokens in the current buffer if no type context exists at
+point."
+ (let (stream full-name-p)
+ (if in-context
+ (setq stream (senator-current-type-context)))
+ (or stream (setq stream (senator-parse)))
+ (setq full-name-p (and (not in-context)
+ (cdr (semantic-find-nonterminal-by-token
+ 'type stream))))
+ (senator-completion-stream stream nil full-name-p in-context)))
+
+;;;;
+;;;; Search functions
+;;;;
+
+(defun senator-search-token-name (token)
+ "Search the TOKEN name in TOKEN bounds.
+Set point to the end of the name, and return point. To get the
+beginning of the name use (match-beginning 0)."
+ (let ((name (semantic-token-name token)))
+ (goto-char (semantic-token-start token))
+ (re-search-forward (concat
+ "\\b"
+ (regexp-quote
+ (if (string-match "\\`\\([^[]+\\)[[]" name)
+ (match-string 1 name)
+ name)))
+ (semantic-token-end token))))
+
+(defun senator-search-forward-raw (searcher what &optional bound noerror count)
+ "Use SEARCHER to search WHAT in semantic tokens after point.
+See `search-forward' for the meaning of BOUND NOERROR and COUNT.
+BOUND and COUNT are just ignored in the current implementation."
+ (let ((origin (point))
+ (tokens (senator-parse))
+ (senator-step-at-start-end-token-ids nil)
+ token pos start limit)
+ (save-excursion
+ (setq token (or (senator-find-last-token tokens origin)
+ (senator-find-next-token tokens origin)))
+ (while (and token (not pos))
+ (setq limit (senator-search-token-name token))
+ (setq start (match-beginning 0))
+ (if (and (> origin start) (< origin limit))
+ (setq start origin))
+ (goto-char start)
+ (setq pos (funcall searcher what limit t))
+ (if (and pos (>= (match-beginning 0) origin))
+ nil
+ (setq pos nil)
+ (setq token (senator-find-next-token tokens (point))))))
+ (if pos
+ (goto-char start)
+ (setq limit (point)))
+ (funcall searcher what limit noerror)))
+
+(defun senator-search-backward-raw (searcher what &optional bound noerror count)
+ "Use SEARCHER to search WHAT in semantic tokens before point.
+See `search-backward' for the meaning of BOUND NOERROR and
+COUNT. BOUND and COUNT are just ignored in the current
+implementation."
+ (let ((origin (point))
+ (tokens (senator-parse))
+ (senator-step-at-start-end-token-ids nil)
+ token pos start limit)
+ (save-excursion
+ (setq token (senator-find-previous-token tokens origin))
+ (while (and token (not pos))
+ (setq start (senator-search-token-name token))
+ (setq limit (match-beginning 0))
+ (if (and (< origin start) (> origin limit))
+ (setq start origin))
+ (goto-char start)
+ (setq pos (funcall searcher what limit t))
+ (if (and pos (<= (match-end 0) origin))
+ nil
+ (setq pos nil)
+ (goto-char (semantic-token-start token))
+ (setq token (senator-find-previous-token tokens (point))))))
+ (if pos
+ (goto-char start)
+ (setq limit (point)))
+ (funcall searcher what limit noerror)))
+
+;;;;
+;;;; Navigation commands
+;;;;
+
+;;;###autoload
+(defun senator-next-token ()
+ "Navigate to the next semantic token.
+Return the semantic token or nil if at end of buffer."
+ (interactive)
+ (let ((pos (point))
+ (tokens (senator-parse))
+ found where)
+ (setq found (senator-find-next-token tokens (point)))
+ (if (not found)
+ (progn
+ (goto-char (point-max))
+ (senator-message "End of buffer"))
+ (cond ((and (senator-step-at-start-end-p found)
+ (or (= pos (semantic-token-start found))
+ (senator-middle-of-token-p pos found)))
+ (setq where "end")
+ (goto-char (semantic-token-end found)))
+ (t
+ (setq where "start")
+ (goto-char (semantic-token-start found))))
+ (senator-momentary-highlight-token found)
+ (senator-message "%S: %s (%s)"
+ (semantic-token-token found)
+ (semantic-token-name found)
+ where))
+ found))
+
+;;;###autoload
+(defun senator-previous-token ()
+ "Navigate to the previous semantic token.
+Return the semantic token or nil if at beginning of buffer."
+ (interactive)
+ (let ((pos (point))
+ (tokens (senator-parse))
+ found where)
+ (setq found (senator-find-previous-token tokens (point)))
+ (if (not found)
+ (progn
+ (goto-char (point-min))
+ (senator-message "Beginning of buffer"))
+ (cond ((or (not (senator-step-at-start-end-p found))
+ (= pos (semantic-token-end found))
+ (senator-middle-of-token-p pos found))
+ (setq where "start")
+ (goto-char (semantic-token-start found)))
+ (t
+ (setq where "end")
+ (goto-char (semantic-token-end found))))
+ (senator-momentary-highlight-token found)
+ (senator-message "%S: %s (%s)"
+ (semantic-token-token found)
+ (semantic-token-name found)
+ where))
+ found))
+
+;;;###autoload
+(defun senator-jump (sym)
+ "Jump to the semantic symbol SYM.
+If called interactively and a prefix argument is supplied jump in the
+local type's context (see function `senator-current-type-context')."
+ (interactive
+ (list
+ (completing-read "Jump to: "
+ (senator-completion-list current-prefix-arg)
+ nil
+ t
+ ""
+ 'semantic-read-symbol-history)))
+ (when sym
+ (let ((token
+ (semantic-find-nonterminal-by-name (senator-last-name sym)
+ (current-buffer))))
+ (goto-char (semantic-token-start token))
+ (senator-momentary-highlight-token token)
+ (senator-message "%S: %s "
+ (semantic-token-token token)
+ (semantic-token-name token)))))
+
+;;;;
+;;;; Search commands
+;;;;
+
+;;;###autoload
+(defun senator-search-forward (what &optional bound noerror count)
+ "Search semantic tokens forward from point for string WHAT.
+Set point to the end of the occurrence found, and return point. See
+`search-forward' for details and the meaning of BOUND NOERROR and
+COUNT. BOUND and COUNT are just ignored in the current
+implementation."
+ (interactive "sSemantic search: ")
+ (senator-search-forward-raw #'search-forward what bound noerror count))
+
+;;;###autoload
+(defun senator-re-search-forward (what &optional bound noerror count)
+ "Search semantic tokens forward from point for regexp WHAT.
+Set point to the end of the occurrence found, and return point. See
+`re-search-forward' for details and the meaning of BOUND NOERROR and
+COUNT. BOUND and COUNT are just ignored in the current
+implementation."
+ (interactive "sSemantic regexp search: ")
+ (senator-search-forward-raw #'re-search-forward what bound noerror count))
+
+;;;###autoload
+(defun senator-word-search-forward (what &optional bound noerror count)
+ "Search semantic tokens forward from point for word WHAT.
+Set point to the end of the occurrence found, and return point. See
+`word-search-forward' for details and the meaning of BOUND NOERROR and
+COUNT. BOUND and COUNT are just ignored in the current
+implementation."
+ (interactive "sSemantic word search: ")
+ (senator-search-forward-raw #'word-search-forward what bound noerror count))
+
+;;;###autoload
+(defun senator-search-backward (what &optional bound noerror count)
+ "Search semantic tokens backward from point for string WHAT.
+Set point to the beginning of the occurrence found, and return point.
+See `search-backward' for details and the meaning of BOUND NOERROR and
+COUNT. BOUND and COUNT are just ignored in the current
+implementation."
+ (interactive "sSemantic backward search: ")
+ (senator-search-backward-raw #'search-backward what bound noerror count))
+
+;;;###autoload
+(defun senator-re-search-backward (what &optional bound noerror count)
+ "Search semantic tokens backward from point for regexp WHAT.
+Set point to the beginning of the occurrence found, and return point.
+See `re-search-backward' for details and the meaning of BOUND NOERROR
+and COUNT. BOUND and COUNT are just ignored in the current
+implementation."
+ (interactive "sSemantic backward regexp search: ")
+ (senator-search-backward-raw #'re-search-backward what bound noerror count))
+
+;;;###autoload
+(defun senator-word-search-backward (what &optional bound noerror count)
+ "Search semantic tokens backward from point for word WHAT.
+Set point to the beginning of the occurrence found, and return point.
+See `word-search-backward' for details and the meaning of BOUND
+NOERROR and COUNT. BOUND and COUNT are just ignored in the current
+implementation."
+ (interactive "sSemantic backward word search: ")
+ (senator-search-backward-raw #'word-search-backward what bound noerror count))
+
+;;;;
+;;;; Others useful search commands (minor mode menu)
+;;;;
+
+(defun senator-nonincremental-search-forward (string)
+ "Search for STRING nonincrementally."
+ (interactive "sSemantic search for string: ")
+ (if (equal string "")
+ (senator-search-forward (car search-ring))
+ (isearch-update-ring string nil)
+ (senator-search-forward string)))
+
+(defun senator-nonincremental-search-backward (string)
+ "Search backward for STRING nonincrementally."
+ (interactive "sSemantic search for string: ")
+ (if (equal string "")
+ (senator-search-backward (car search-ring))
+ (isearch-update-ring string nil)
+ (senator-search-backward string)))
+
+(defun senator-nonincremental-re-search-forward (string)
+ "Search for the regular expression STRING nonincrementally."
+ (interactive "sSemantic search for regexp: ")
+ (if (equal string "")
+ (senator-re-search-forward (car regexp-search-ring))
+ (isearch-update-ring string t)
+ (senator-re-search-forward string)))
+
+(defun senator-nonincremental-re-search-backward (string)
+ "Search backward for the regular expression STRING nonincrementally."
+ (interactive "sSemantic search for regexp: ")
+ (if (equal string "")
+ (senator-re-search-backward (car regexp-search-ring))
+ (isearch-update-ring string t)
+ (senator-re-search-backward string)))
+
+(defun senator-nonincremental-repeat-search-forward ()
+ "Search forward for the previous search string."
+ (interactive)
+ (if (null search-ring)
+ (error "No previous search"))
+ (senator-search-forward (car search-ring)))
+
+(defun senator-nonincremental-repeat-search-backward ()
+ "Search backward for the previous search string."
+ (interactive)
+ (if (null search-ring)
+ (error "No previous search"))
+ (senator-search-backward (car search-ring)))
+
+(defun senator-nonincremental-repeat-re-search-forward ()
+ "Search forward for the previous regular expression."
+ (interactive)
+ (if (null regexp-search-ring)
+ (error "No previous search"))
+ (senator-re-search-forward (car regexp-search-ring)))
+
+(defun senator-nonincremental-repeat-re-search-backward ()
+ "Search backward for the previous regular expression."
+ (interactive)
+ (if (null regexp-search-ring)
+ (error "No previous search"))
+ (senator-re-search-backward (car regexp-search-ring)))
+
+;;;;
+;;;; Senator minor mode
+;;;;
+(defvar senator-mode nil
+ "Name of the minor mode, if non-nil.")
+(make-variable-buffer-local 'senator-mode)
+
+(defvar senator-isearch-semantic-mode nil
+ "Non-nil if isearch does semantic search.
+This is a buffer local variable.")
+(make-variable-buffer-local 'senator-isearch-semantic-mode)
+
+(defvar senator-prefix-key [(control ?c) ?,]
+ "The common prefix key in senator minor mode.")
+
+(defvar senator-prefix-map
+ (let ((km (make-sparse-keymap)))
+ (define-key km "i" 'senator-isearch-toggle-semantic-mode)
+ (define-key km "j" 'senator-jump)
+ (define-key km "p" 'senator-previous-token)
+ (define-key km "n" 'senator-next-token)
+ km)
+ "Default key bindings in senator minor mode.")
+
+(defun senator-menu-item (item)
+ "Build an XEmacs compatible menu item from vector ITEM.
+That is remove the unsupported :help stuff."
+ (if (featurep 'xemacs)
+ (let ((n (length item))
+ (i 0)
+ l)
+ (while (< i n)
+ (setq slot (aref item i))
+ (if (and (keywordp slot)
+ (eq slot :help))
+ (setq i (1+ i))
+ (setq l (cons slot l)))
+ (setq i (1+ i)))
+ (apply #'vector (nreverse l)))
+ item))
+
+(defvar senator-menu-bar
+ (list
+ "Senator"
+ (list
+ "Navigate"
+ (senator-menu-item
+ ["Next"
+ senator-next-token
+ :active t
+ :help "Go to the next token found"
+ ])
+ (senator-menu-item
+ ["Previous"
+ senator-previous-token
+ :active t
+ :help "Go to the previous token found"
+ ])
+ (senator-menu-item
+ ["Jump..."
+ senator-jump
+ :active t
+ :help "Jump to a semantic symbol"
+ ])
+ )
+ (list
+ "Search"
+ (senator-menu-item
+ ["Search..."
+ senator-nonincremental-search-forward
+ :active t
+ :help "Search forward for a string"
+ ])
+ (senator-menu-item
+ ["Search Backwards..."
+ senator-nonincremental-search-backward
+ :active t
+ :help "Search backwards for a string"
+ ])
+ (senator-menu-item
+ ["Repeat Search"
+ senator-nonincremental-repeat-search-forward
+ :active search-ring
+ :help "Repeat last search forward"
+ ])
+ (senator-menu-item
+ ["Repeat Backwards"
+ senator-nonincremental-repeat-search-backward
+ :active search-ring
+ :help "Repeat last search backwards"
+ ])
+ (senator-menu-item
+ ["Search Regexp..."
+ senator-nonincremental-re-search-forward
+ :active t
+ :help "Search forward for a regular expression"
+ ])
+ (senator-menu-item
+ ["Search Regexp Backwards..."
+ senator-nonincremental-re-search-backward
+ :active t
+ :help "Search backwards for a regular expression"
+ ])
+ (senator-menu-item
+ ["Repeat Regexp"
+ senator-nonincremental-repeat-re-search-forward
+ :active regexp-search-ring
+ :help "Repeat last regular expression search forward"
+ ])
+ (senator-menu-item
+ ["Repeat Regexp Backwards"
+ senator-nonincremental-repeat-re-search-backward
+ :active regexp-search-ring
+ :help "Repeat last regular expression search backwards"
+ ])
+ "-"
+ (senator-menu-item
+ ["Semantic isearch mode"
+ senator-isearch-toggle-semantic-mode
+ :active t
+ :style toggle :selected senator-isearch-semantic-mode
+ :help "Toggle semantic search in isearch mode"
+ ])
+ )
+ "-"
+ (senator-menu-item
+ ["Options..."
+ (customize-group "senator")
+ :active t
+ :help "Customize SEmantic NAvigaTOR options"
+ ])
+ )
+ "Menu for senator minor mode.")
+
+(defvar senator-mode-map
+ (let ((km (make-sparse-keymap)))
+ (define-key km senator-prefix-key senator-prefix-map)
+ (easy-menu-define senator-minor-menu km "Senator Minor Mode Menu"
+ senator-menu-bar)
+ km)
+ "Keymap for senator minor mode.")
+
+(defun senator-show-status ()
+ "Update the modeline to show the senator minor mode state.
+If `senator-isearch-semantic-mode' is non-nil append \"/si\" to
+the value of the variable `senator-minor-mode-name'."
+ (setq senator-mode (format (if senator-isearch-semantic-mode
+ " %s/si"
+ " %s")
+ senator-minor-mode-name))
+ (force-mode-line-update))
+
+(defun senator-minor-mode-setup ()
+ "Actually setup the senator minor mode.
+Turn off the minor mode if semantic feature is not available or
+`semantic-toplevel-bovine-table' not provided for the current buffer.
+If minor mode is enabled parse the current buffer if needed. Return
+non-nil if the minor mode is enabled."
+ (if senator-minor-mode
+ (if (not (and (featurep 'semantic) semantic-toplevel-bovine-table))
+ ;; Disable minor mode if semantic stuff not available
+ (senator-minor-mode nil)
+ ;; XEmacs needs this
+ (if (featurep 'xemacs)
+ (easy-menu-add senator-minor-menu senator-mode-map))
+ ;; Parse the current buffer if needed
+ (condition-case nil
+ (senator-parse)
+ (quit (message "senator-minor-mode: parsing of buffer canceled.")))
+ (senator-show-status)
+ )
+ ;; XEmacs needs this
+ (if (featurep 'xemacs)
+ (easy-menu-remove senator-minor-menu))
+ ;; Disable semantic isearch
+ (setq senator-isearch-semantic-mode nil))
+ senator-minor-mode)
+
+(if (fboundp 'define-minor-mode)
+
+;;; Note that `define-minor-mode' actually calls the mode-function if
+;;; the associated variable is non-nil, which requires that all needed
+;;; functions be already defined. [This is arguably a bug in d-m-m]
+;;;###autoload
+ (define-minor-mode senator-minor-mode
+ "Toggle senator minor mode.
+With prefix argument ARG, turn on if positive, otherwise off. The
+minor mode is turned on only if semantic feature is available and a
+`semantic-toplevel-bovine-table' is provided for the current buffer.
+Return non-nil if the minor mode is enabled.
+
+\\{senator-mode-map}"
+ nil senator-mode senator-mode-map
+ :global nil
+ :group 'senator
+ (senator-minor-mode-setup))
+
+;;; `define-minor-mode' is not defined
+
+ (defvar senator-minor-mode nil
+ "Non-nil if senator minor mode is on.")
+ (make-variable-buffer-local 'senator-minor-mode)
+
+ (defvar senator-minor-mode-hook nil
+ "Hook called when senator minor mode is toggled")
+
+ (defvar senator-minor-mode-on-hook nil
+ "Hook called when senator minor mode is turned on")
+
+ (defvar senator-minor-mode-off-hook nil
+ "Hook called when senator minor mode is turned off")
+
+;;;###autoload
+ (defun senator-minor-mode (&optional arg)
+ "Toggle senator minor mode.
+With prefix argument ARG, turn on if positive, otherwise off. The
+minor mode is turned on only if semantic feature is available and a
+`semantic-toplevel-bovine-table' is provided for the current buffer.
+Return non-nil if the minor mode is enabled.
+
+\\{senator-mode-map}"
+ (interactive "P")
+ (let ((old-mode senator-minor-mode))
+ (setq senator-minor-mode
+ (if arg
+ (or (listp arg) ;; C-u alone
+ (> (prefix-numeric-value arg) 0))
+ (not senator-minor-mode)))
+ (and senator-minor-mode-hook
+ (not (equal old-mode senator-minor-mode))
+ (run-hooks 'senator-minor-mode-hook))
+ (and senator-minor-mode-on-hook
+ senator-minor-mode
+ (run-hooks 'senator-minor-mode-on-hook))
+ (and senator-minor-mode-off-hook
+ (not senator-minor-mode)
+ (run-hooks 'senator-minor-mode-off-hook)))
+ (senator-minor-mode-setup)
+ (senator-message "Senator minor mode %s"
+ (if senator-minor-mode
+ "enabled"
+ "disabled"))
+ senator-minor-mode)
+
+ (if (fboundp 'add-minor-mode)
+
+ ;; XEmacs
+ (add-minor-mode 'senator-minor-mode 'senator-mode senator-mode-map)
+
+ ;; Emacs 20
+ (or (assq 'senator-minor-mode minor-mode-alist)
+ (setq minor-mode-alist
+ (cons (list 'senator-minor-mode 'senator-mode)
minor-mode-alist)))
+
+ (or (assq 'senator-minor-mode minor-mode-map-alist)
+ (setq minor-mode-map-alist
+ (cons (cons 'senator-minor-mode senator-mode-map)
+ minor-mode-map-alist)))
+
+ ))
+
+;;;;
+;;;; Useful advices
+;;;;
+
+(defun senator-beginning-of-defun ()
+ "Move backward to the beginning of a defun.
+Use semantic tokens to navigate."
+ (let ((senator-highlight-found nil)
+ (senator-step-at-start-end-token-ids nil)
+ (senator-step-at-token-ids '(function)))
+ (if (senator-previous-token)
+ (beginning-of-line))
+ (senator-message nil)))
+
+(defun senator-end-of-defun ()
+ "Move forward to next end of defun.
+Use semantic tokens to navigate."
+ (let* ((senator-highlight-found nil)
+ (senator-step-at-start-end-token-ids '(function))
+ (senator-step-at-token-ids '(function))
+ (token (senator-next-token)))
+ (when token
+ (if (= (point) (semantic-token-start token))
+ (goto-char (semantic-token-end token)))
+ (skip-chars-forward " \t")
+ (if (looking-at "\\s<\\|\n")
+ (forward-line 1)))
+ (senator-message nil)))
+
+(defun senator-narrow-to-defun ()
+ "Make text outside current defun invisible.
+The defun visible is the one that contains point or follows point.
+Use semantic tokens to navigate."
+ (interactive)
+ (save-excursion
+ (widen)
+ (senator-end-of-defun)
+ (let ((end (point)))
+ (senator-beginning-of-defun)
+ (narrow-to-region (point) end))))
+
+(defun senator-mark-defun ()
+ "Put mark at end of this defun, point at beginning.
+The defun marked is the one that contains point or follows point.
+Use semantic tokens to navigate."
+ (interactive)
+ (let ((origin (point))
+ (end (progn (senator-end-of-defun) (point)))
+ (start (progn (senator-beginning-of-defun) (point))))
+ (goto-char origin)
+ (push-mark (point))
+ (goto-char end) ;; end-of-defun
+ (push-mark (point) nil t)
+ (goto-char start) ;; beginning-of-defun
+ (re-search-backward "^\n" (- (point) 1) t)))
+
+(defadvice beginning-of-defun (around senator activate)
+ "Move backward to the beginning of a defun.
+If semantic tokens are available, use them to navigate."
+ (if (and senator-minor-mode (interactive-p))
+ (senator-beginning-of-defun)
+ ad-do-it))
+
+(defadvice end-of-defun (around senator activate)
+ "Move forward to next end of defun.
+If semantic tokens are available, use them to navigate."
+ (if (and senator-minor-mode (interactive-p))
+ (senator-end-of-defun)
+ ad-do-it))
+
+(defadvice narrow-to-defun (around senator activate)
+ "Make text outside current defun invisible.
+The defun visible is the one that contains point or follows point.
+If semantic tokens are available, use them to navigate."
+ (if (and senator-minor-mode (interactive-p))
+ (senator-narrow-to-defun)
+ ad-do-it))
+
+(defadvice mark-defun (around senator activate)
+ "Put mark at end of this defun, point at beginning.
+The defun marked is the one that contains point or follows point.
+If semantic tokens are available, use them to navigate."
+ (if (and senator-minor-mode (interactive-p))
+ (senator-mark-defun)
+ ad-do-it))
+
+(defadvice c-mark-function (around senator activate)
+ "Put mark at end of this defun, point at beginning.
+The defun marked is the one that contains point or follows point.
+If semantic tokens are available, use them to navigate."
+ (if (and senator-minor-mode (interactive-p))
+ (senator-mark-defun)
+ ad-do-it))
+
+;;;;
+;;;; Using semantic search in isearch mode
+;;;;
+
+(defun senator-isearch-search-handler ()
+ "Return the actual search function used by `isearch-search'.
+If `senator-isearch-semantic-mode' is nil it delegates to the
+function `isearch-default-search-handler'. Otherwise it returns one
+of the functions `senator-search-forward', `senator-search-backward',
+`senator-word-search-forward', `senator-word-search-backward',
+`senator-re-search-forward' or `senator-re-search-backward' depending
+on current values of the variables `isearch-forward', `isearch-regexp'
+and `isearch-word'."
+ (if senator-isearch-semantic-mode
+ (cond (isearch-word
+ (if isearch-forward
+ 'senator-word-search-forward
+ 'senator-word-search-backward))
+ (isearch-regexp
+ (if isearch-forward
+ 'senator-re-search-forward
+ 'senator-re-search-backward))
+ (t
+ (if isearch-forward
+ 'senator-search-forward
+ 'senator-search-backward)))
+ (isearch-default-search-handler)))
+
+(defun senator-isearch-toggle-semantic-mode ()
+ "Toggle semantic searching on or off in isearch mode.
+\\[senator-isearch-toggle-semantic-mode] toggle semantic searching."
+ (interactive)
+ (when senator-minor-mode
+ (setq senator-isearch-semantic-mode
+ (not senator-isearch-semantic-mode))
+ (senator-show-status)
+ (if isearch-mode
+ ;; force lazy highlight update
+ (senator-lazy-highlight-update)
+ (senator-message "Isearch semantic mode %s"
+ (if senator-isearch-semantic-mode
+ "enabled"
+ "disabled")))))
+
+;; Needed by XEmacs isearch to not terminate isearch mode when
+;; toggling semantic search.
+(put 'senator-isearch-toggle-semantic-mode 'isearch-command t)
+
+;; Keyboard shortcut to toggle semantic search in isearch mode.
+(define-key isearch-mode-map [(control ?,)] 'senator-isearch-toggle-semantic-mode)
+
+(defun senator-isearch-mode-hook ()
+ "Isearch mode hook to setup semantic searching."
+ (setq isearch-search-handler-provider #'senator-isearch-search-handler)
+ (or senator-minor-mode
+ (setq senator-isearch-semantic-mode nil))
+ (senator-show-status))
+
+(add-hook 'isearch-mode-hook 'senator-isearch-mode-hook)
+
+(provide 'senator)
+
+;;; senator.el ends here
Index: xemacs-packages/jde/lisp/tree-widget.el
===================================================================
RCS file: tree-widget.el
diff -N tree-widget.el
--- /dev/null Tue Aug 14 14:29:33 2001
+++ tree-widget.el Tue Aug 14 22:28:05 2001
@@ -0,0 +1,559 @@
+;;; tree-widget.el --- Tree widget
+
+;; Copyright (C) 2001 by David Ponce
+
+;; Author: David Ponce <david(a)dponce.com>
+;; Maintainer: David Ponce <david(a)dponce.com>
+;; Created: 16 Feb 2001
+;; Version: 1.0.5
+;; Keywords: extensions
+;; VC: $Id: tree-widget.el,v 1.5 2001/05/11 23:11:18 ponce Exp $
+
+;; This file is not part of Emacs
+
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2, or (at
+;; your option) any later version.
+
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program; see the file COPYING. If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+;;
+;; This library provide a `tree-widget' useful to display data
+;; structures organized in hierarchical order.
+;;
+;; The following `tree-widget' extra properties are recognized:
+;;
+;; :open
+;; Set to non-nil to unfold the tree. By default the tree is
+;; folded.
+;;
+;; :node
+;; The widget used for the tree node. By default this is an
+;; `item' widget which displays the tree :tag property value if
+;; defined or a string representation of the tree value using the
+;; function `widget-princ-to-string'.
+;;
+;; :keep
+;; Specify a list of extra properties to keep when the tree is
+;; folded so they can be recovered when the tree is unfolded.
+;; This property is also honoured in `tree-widget' children.
+;;
+;; :dynargs
+;; Specify a function to be called when the tree is unfolded.
+;; This function will receives the tree widget as its argument
+;; and must return a list of children widget definitions. Thus
+;; dynamlically providing the tree children in response to an
+;; unfold request. The list of children definitions is kept in
+;; the tree :args property and the :dynargs function can just
+;; return its value when unfolding the tree again. To force a
+;; new evaluation of the tree content just set its :args property
+;; to nil and redraw the node.
+;;
+;; :has-children
+;; Specify if this tree has children. This property has meaning
+;; only when used with the above :dynargs one. It indicates that
+;; children widget exist but will be provided when unfolding the
+;; node.
+;;
+;; :no-leaf-handle (default "*---- ")
+;; :close-handle (default "-- ")
+;; :no-guide (default " ")
+;; :open-handle (default "-, ")
+;; :guide (default " | ")
+;; :leaf-handle (default " |--- ")
+;; :last-leaf-handle (default " `--- ")
+;; These properties define the strings used to draw the tree
+;; like the following:
+;;
+;; *---- N0 :no-leaf-handle + node
+;;
+;; [-]-, N0 node-handle + :open-handle + node
+;; |--- N1 :no-guide + :leaf-handle + node
+;; [-]-, N2 :no-guide + node-handle + :open-handle + node
+;; | |--- N21 :no-guide + :guide + :leaf-handle + node
+;; | `--- N22 :no-guide + :guide + :last-leaf-handle + node
+;; [+]-- N3 :no-guide + node-handle + :close-handle + node
+;;
+;; About leaf node format
+;; To correctly draw the tree, that is insert the current leaf node
+;; prefix, leaf node widgets should prepend the "%p" escape to the
+;; value of the :format property. And set the :format-handler
+;; property to `tree-widget-format-handler'. Something like this:
+;;
+;; (define-widget 'leaf-node 'item
+;; :format "%p%t\n"
+;; :format-handler #'tree-widget-format-handler)
+;;
+;; Basic examples of `tree-widget' usage are provided in this file
+;; (see commands `tree-widget-example-1' and `tree-widget-example-2').
+;; A more sophisticated example is provided in the dir-tree.el
+;; source.
+;;
+;; Installation
+
+;; Put this file on your Emacs-Lisp load path and add following into
+;; your ~/.emacs startup file
+;;
+;; (require 'tree-widget)
+
+;; Support
+;;
+;; This program is available at <
http://www.dponce.com/>. Any
+;; comments, suggestions, bug reports or upgrade requests are welcome.
+;; Please send them to David Ponce <david(a)dponce.com>.
+
+;;; History:
+;;
+;; $Log: tree-widget.el,v $
+;; Revision 1.5 2001/05/11 23:11:18 ponce
+;; Updated version to 1.0.5.
+;;
+;; Revision 1.4 2001/05/11 23:02:14 ponce
+;; (tree-widget-value-create): Fixed a bug when the dynamic tree :dynargs
+;; function returns nil (no children).
+;;
+;; Revision 1.3 2001/03/16 14:23:15 ponce
+;; (tree-widget-example-1): removed unused free variable
+;; `tree-widget-sample'.
+;;
+;; Revision 1.2 2001/03/16 14:15:09 ponce
+;; (tree-widget-children-value-save): use `tree-widget-node' to get the
+;; :node value of widgets. Check node and node-child values before
+;; saving properties.
+;;
+;; (tree-widget-button-keymap): new variable. Keymap used inside node
+;; handle buttons.
+;;
+;; (tree-widget-node-handle): use `tree-widget-button-keymap'.
+;;
+;; (tree-widget-map): new utility function.
+;;
+;; Revision 1.1 2001/02/19 22:51:23 ponce
+;; Initial revision.
+;;
+
+;;; Code:
+
+(require 'wid-edit)
+
+;;; Customization.
+
+(defgroup tree-widget nil
+ "Customization support for the Tree Widget Library."
+ :group 'widgets)
+
+(defcustom tree-widget-node-handle-widget 'tree-widget-node-handle
+ "Widget type used for tree node handle."
+ :type 'symbol
+ :group 'tree-widget)
+
+(defun tree-widget-get-super (widget property)
+ "Return WIDGET super class PROPERTY value."
+ (widget-get
+ (get (widget-type
+ (get (widget-type widget) 'widget-type))
+ 'widget-type)
+ property))
+
+(defun tree-widget-p (widget)
+ "Return non-nil if WIDGET inherits from a 'tree-widget' widget."
+ (let ((type (widget-type widget)))
+ (while (and type (not (eq type 'tree-widget)))
+ (setq type (widget-type (get type 'widget-type))))
+ (eq type 'tree-widget)))
+
+(defun tree-widget-keep (arg widget)
+ "Save in ARG the WIDGET properties specified by :keep."
+ (let ((plist (widget-get widget :keep))
+ prop)
+ (while plist
+ (setq prop (car plist)
+ plist (cdr plist))
+ (widget-put arg prop (widget-get widget prop)))))
+
+(defun tree-widget-node (widget)
+ "Return the tree WIDGET :node value.
+If not found setup a default 'item' widget."
+ (or (widget-get widget :node)
+ ;; Take care of actually return the :node property value.
+ ;; Because FSF Emacs `widget-put' returns the property value and
+ ;; XEmacs one returns the widget value!!! So don't use thing
+ ;; like this ;-)
+ ;; (or (widget-get widget :node)
+ ;; (widget-put widget :node node))
+ (let ((node `(item :tag ,(or (widget-get widget :tag)
+ (widget-princ-to-string
+ (widget-value widget))))))
+ (widget-put widget :node node)
+ node)))
+
+(defun tree-widget-children-value-save (widget &optional args node)
+ "Save WIDGET children values.
+Children properties and values are saved in ARGS if non-nil else in
+WIDGET :args property value. Data node properties and value are saved
+in NODE if non-nil else in WIDGET :node property value."
+ (let ((args (or args (widget-get widget :args)))
+ (node (or node (tree-widget-node widget)))
+ (children (widget-get widget :children))
+ (node-child (widget-get widget :tree-widget-node))
+ arg child)
+ (while (and args children)
+ (setq arg (car args)
+ args (cdr args)
+ child (car children)
+ children (cdr children))
+ (cond
+
+ ;; The child is a tree node.
+ ((tree-widget-p child)
+
+ ;; Backtrack :args and :node properties.
+ (widget-put arg :args (widget-get child :args))
+ (widget-put arg :node (tree-widget-node child))
+
+ ;; Save :open property.
+ (widget-put arg :open (widget-get child :open))
+
+ ;; The node is open.
+ (if (widget-get child :open)
+ (progn
+ ;; Save the widget value.
+ (widget-put arg :value (widget-value child))
+ ;; Save properties specified in :keep.
+ (tree-widget-keep arg child)
+ ;; Save children.
+ (tree-widget-children-value-save
+ child
+ (widget-get arg :args)
+ (widget-get arg :node)))))
+
+ ;; Another non tree node.
+ (t
+ ;; Save the widget value
+ (widget-put arg :value (widget-value child))
+ ;; Save properties specified in :keep.
+ (tree-widget-keep arg child))))
+
+ (cond ((and node node-child)
+ ;; Assume that the node child widget is not a tree!
+ ;; Save the node child widget value.
+ (widget-put node :value (widget-value node-child))
+ ;; Save the node child properties specified in :keep.
+ (tree-widget-keep node node-child)))))
+
+(defun tree-widget-toggle-folding (widget &rest ignore)
+ "Toggle tree WIDGET folding.
+IGNORE other arguments."
+ (let ((parent (widget-get widget :parent))
+ (open (widget-value widget)))
+ (if open
+ ;; Before folding the node up, save children values so next
+ ;; open can recover them.
+ (tree-widget-children-value-save parent))
+ (widget-put parent :open (not open))
+ (widget-value-set parent (not open))))
+
+(defvar tree-widget-button-keymap
+ (let (parent-keymap mouse-button1 keymap)
+ (if (featurep 'xemacs)
+ (setq parent-keymap widget-button-keymap
+ mouse-button1 [button1])
+ (setq parent-keymap widget-keymap
+ mouse-button1 [down-mouse-1]))
+ (setq keymap (copy-keymap parent-keymap))
+ (define-key keymap mouse-button1 #'widget-button-click)
+ keymap)
+ "Keymap used inside node handle buttons.")
+
+
+(define-widget 'tree-widget-node-handle 'toggle
+ "Tree node handle widget."
+ :button-keymap tree-widget-button-keymap ; XEmacs
+ :keymap tree-widget-button-keymap ; Emacs
+ :format "%[%v%]"
+ :on "[+]"
+ :off "[-]"
+ :notify #'tree-widget-toggle-folding)
+
+(define-widget 'tree-widget 'default
+ "Tree node widget."
+ :format "%v"
+ :convert-widget #'widget-types-convert-widget
+ :value-get #'widget-value-value-get
+ :value-create #'tree-widget-value-create
+ :value-delete #'tree-widget-value-delete
+
+ ;; *---- N :no-leaf-handle + node
+
+ ;; [-]-, N node-handle + :open-handle + node
+ ;; |--- N1 :no-guide + :leaf-handle + node
+ ;; [-]-, N2 :no-guide + node-handle + :open-handle + node
+ ;; | |--- N21 :no-guide + :guide + :leaf-handle + node
+ ;; | `--- N22 :no-guide + :guide + :last-leaf-handle + node
+ ;; [+]-- N3 :no-guide + node-handle + :close-handle + node
+
+ :no-leaf-handle "*---- "
+ :close-handle "-- "
+ :no-guide " "
+ :open-handle "-, "
+ :guide " | "
+ :leaf-handle " |--- "
+ :last-leaf-handle " `--- ")
+
+(defun tree-widget-format-handler (widget escape)
+ "Convenient %p format handler to insert a leaf node prefix.
+WIDGET is a tree leaf node and ESCAPE a format character."
+ (cond
+
+ ;; If %p format insert the leaf node prefix.
+ ((eq escape ?p)
+ (if (widget-get widget :indent)
+ (insert-char ? (widget-get widget :indent)))
+ (insert
+ (or (widget-get widget :tree-widget-leaf-handle)
+ "")))
+
+ ;; For other ESCAPE values call the WIDGET super class format
+ ;; handler.
+ (t
+ (let ((handler (tree-widget-get-super widget :format-handler)))
+ (if handler
+ (funcall handler widget escape))))))
+
+(defun tree-widget-value-delete (widget)
+ "Delete tree WIDGET children."
+ ;; Delete children
+ (widget-children-value-delete widget)
+ ;; Delete node child
+ (widget-delete (widget-get widget :tree-widget-node))
+ (widget-put widget :tree-widget-node nil))
+
+(defun tree-widget-value-create (widget)
+ "Create the tree WIDGET children."
+ (let ((args (widget-get widget :args))
+ (open (widget-get widget :open))
+ (node (tree-widget-node widget))
+ children buttons prefix)
+ (cond
+
+ ;; Leaf node.
+ ((not (or args
+ ;; Take care of dynamic tree. If :has-children is
+ ;; non-nil let a chance to open the node later. So
+ ;; don't consider it as a leaf node even if it has not
+ ;; (yet) any children.
+ (and (widget-get widget :dynargs)
+ (widget-get widget :has-children))))
+
+ (insert (or (widget-get widget :tree-widget-leaf-handle)
+ (widget-get widget :no-leaf-handle)))
+ (widget-put widget :tree-widget-node
+ (widget-create-child-and-convert widget node)))
+
+ ;; Unfolded node.
+ (open
+
+ ;; Maybe the tree is dynamic.
+ (if (widget-get widget :dynargs)
+ (let ((newargs
+ ;; Request the definition of children.
+ (funcall (widget-get widget :dynargs) widget)))
+ ;; Maybe reuse definition from the :args cache.
+ (or (eq args newargs)
+ ;; Otherwise setup a new :args cache.
+ (widget-put
+ widget :args
+ (setq args (mapcar #'widget-convert newargs))))))
+
+ (setq buttons
+ (cons (widget-create-child-and-convert
+ widget tree-widget-node-handle-widget
+ :value nil :help-echo "Hide node")
+ buttons))
+ (insert (widget-get widget (if args
+ :open-handle
+ :close-handle)))
+ (widget-put widget :tree-widget-node
+ (widget-create-child-and-convert widget node))
+ (setq prefix
+ (concat (or (widget-get widget :tree-widget-prefix) "")
+ (or (widget-get widget :tree-widget-guide)
+ (widget-get widget :no-guide))))
+ (if (null args)
+ nil
+ (while (cdr args)
+ (insert prefix)
+ (setq children
+ (cons (widget-create-child-and-convert
+ widget (car args)
+ :tree-widget-prefix prefix
+ :tree-widget-guide (widget-get widget :guide)
+ :tree-widget-leaf-handle
+ (widget-get widget :leaf-handle))
+ children)
+ args (cdr args)))
+ ;; The last non tree child uses the :last-leaf-handle.
+ (insert prefix)
+ (setq children
+ (cons (widget-create-child-and-convert
+ widget (car args)
+ :tree-widget-prefix prefix
+ :tree-widget-leaf-handle
+ (widget-get widget :last-leaf-handle))
+ children))))
+
+ ;; Folded node.
+ (t
+
+ (setq buttons
+ (cons
+ (widget-create-child-and-convert
+ widget tree-widget-node-handle-widget
+ :value t :help-echo "Show node")
+ buttons))
+ (insert (widget-get widget :close-handle))
+ (widget-put widget :tree-widget-node
+ (widget-create-child-and-convert widget node))))
+
+ (widget-put widget :children (nreverse children))
+ (widget-put widget :buttons buttons)))
+
+;;;;
+;;;; Utilities
+;;;;
+
+(defun tree-widget-map (widget fun)
+ "For each WIDGET displayed child call function FUN.
+FUN is called with three arguments like this:
+
+ (FUN CHILD IS-NODE WIDGET)
+
+where:
+- - CHILD is the child widget.
+- - IS-NODE is non-nil if CHILD is WIDGET node widget."
+ (if (widget-get widget :tree-widget-node)
+ (let ((children (widget-get widget :children))
+ child)
+ (funcall fun (widget-get widget :tree-widget-node)
+ t widget)
+ (while children
+ (setq child (car children)
+ children (cdr children))
+ (if (tree-widget-p child)
+ ;; The child is a tree node.
+ (tree-widget-map child fun)
+ ;; Another non tree node.
+ (funcall fun child nil widget))))))
+
+;;;;
+;;;; Samples
+;;;;
+
+;;; Compatibility
+
+(cond ((featurep 'xemacs)
+
+ (defalias 'tree-widget-sample-overlay-lists
+ (lambda () (list (extent-list))))
+ (defalias 'tree-widget-sample-delete-overlay 'delete-extent))
+
+ (t
+
+ (defalias 'tree-widget-sample-overlay-lists 'overlay-lists)
+ (defalias 'tree-widget-sample-delete-overlay 'delete-overlay)))
+
+(defun tree-widget-example-1 ()
+ "A simple usage of the `tree-widget'."
+ (interactive)
+ (switch-to-buffer "*`tree-widget' example 1*")
+ (kill-all-local-variables)
+ (let ((inhibit-read-only t))
+ (erase-buffer))
+ (let ((all (tree-widget-sample-overlay-lists)))
+ (mapcar #'tree-widget-sample-delete-overlay (car all))
+ (mapcar #'tree-widget-sample-delete-overlay (cdr all)))
+
+ (widget-insert (format "%s. \n\n" (buffer-name)))
+
+ (widget-create
+ ;; Open this level.
+ 'tree-widget :open t
+ ;; Use a push button for this node.
+ :node '(push-button
+ :tag "Root"
+ :format "%[%t%]\n"
+ :notify
+ (lambda (&rest ignore)
+ (message "This is the Root node")))
+ ;; Add subtrees (their nodes defaut to items).
+ '(tree-widget :tag "Child-1")
+ '(tree-widget :tag "Child-2"
+ (tree-widget :tag "Child-2.1")
+ (tree-widget :tag "Child-2.2"
+ (tree-widget :tag "Child-2.2.1")
+ (tree-widget :tag "Child-2.2.2")))
+ '(tree-widget :tag "Child-3"
+ (tree-widget :tag "Child-3.1")
+ (tree-widget :tag "Child-3.2")))
+
+ (use-local-map widget-keymap)
+ (widget-setup))
+
+(defun tree-widget-example-2-dynargs (widget)
+ "Return the children definitions of WIDGET.
+Reuse the cached :args property value if exists."
+ (or (widget-get widget :args)
+ '((tree-widget :tag "Child-2.1")
+ (tree-widget :tag "Child-2.2"
+ (tree-widget :tag "Child-2.2.1")
+ (tree-widget :tag "Child-2.2.2")))))
+
+(defun tree-widget-example-2 ()
+ "A simple usage of the `tree-widget' with dynamic expansion."
+ (interactive)
+ (switch-to-buffer "*`tree-widget' example 2*")
+ (kill-all-local-variables)
+ (let ((inhibit-read-only t))
+ (erase-buffer))
+ (let ((all (tree-widget-sample-overlay-lists)))
+ (mapcar #'tree-widget-sample-delete-overlay (car all))
+ (mapcar #'tree-widget-sample-delete-overlay (cdr all)))
+
+ (widget-insert (format "%s. \n\n" (buffer-name)))
+
+ (widget-create
+ ;; Open this level.
+ 'tree-widget :open t
+ ;; Use a push button for this node.
+ :node '(push-button
+ :tag "Root"
+ :format "%[%t%]\n"
+ :notify
+ (lambda (&rest ignore)
+ (message "This is the Root node")))
+ ;; Add subtrees (their nodes defaut to items).
+ '(tree-widget :tag "Child-1")
+ ;; Dynamically retrieve children of this node.
+ '(tree-widget :tag "Child-2"
+ :dynargs tree-widget-example-2-dynargs
+ :has-children t)
+ '(tree-widget :tag "Child-3"
+ (tree-widget :tag "Child-3.1")
+ (tree-widget :tag "Child-3.2")))
+
+ (use-local-map widget-keymap)
+ (widget-setup))
+
+(provide 'tree-widget)
+
+;;; tree-widget.el ends here
\ No newline at end of file
Index: xemacs-packages/semantic/Makefile
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/semantic/Makefile,v
retrieving revision 1.11
diff -u -r1.11 Makefile
--- xemacs-packages/semantic/Makefile 2001/06/14 04:55:14 1.11
+++ xemacs-packages/semantic/Makefile 2001/08/15 05:28:15
@@ -17,18 +17,18 @@
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
-VERSION = 1.06
-AUTHOR_VERSION = 1.3.3
+VERSION = 1.07
+AUTHOR_VERSION = 1.4beta8
MAINTAINER = Eric M. Ludlam <zappo(a)gnu.org>
PACKAGE = semantic
PKG_TYPE = regular
-REQUIRES = semantic xemacs-base speedbar
+REQUIRES = eieio xemacs-base xemacs-devel edit-utils speedbar
CATEGORY = standard
ELCS = document-vars.elc document.elc semantic-bnf.elc semantic-c.elc \
- semantic-el.elc semantic-imenu.elc semantic-make.elc semantic-mode.elc \
+ semantic-ctxt.elc semantic-el.elc semantic-imenu.elc semantic-make.elc \
semantic-sb.elc semantic-util.elc semantic.elc sformat.elc working.elc \
- senator.elc senator-isearch.elc
+ senator.elc semantic-java.elc semantic-scm.elc semanticdb.elc semantic-load.el
EXTRA_SOURCES = semantic-util.el
INFO_FILES = $(PACKAGE).info*
Index: xemacs-packages/semantic/c.bnf
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/semantic/c.bnf,v
retrieving revision 1.4
diff -u -r1.4 c.bnf
--- xemacs-packages/semantic/c.bnf 2001/02/20 03:23:42 1.4
+++ xemacs-packages/semantic/c.bnf 2001/08/15 05:28:15
@@ -1,9 +1,9 @@
-# Simple BNF notation for top-level C elements.
+# C & C++ BNF language specification
#
-# Copyright (C) 1999, 2000 Eric M. Ludlam
+# Copyright (C) 1999, 2000, 2001 Eric M. Ludlam
#
# Author: Eric M. Ludlam <zappo(a)gnu.org>
-# X-RCS: $Id: c.bnf,v 1.4 2001/02/20 03:23:42 youngs Exp $
+# X-RCS: $Id: c.bnf,v 1.37 2001/06/03 14:01:13 zappo Exp $
#
# c.bnf is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -21,143 +21,331 @@
# Boston, MA 02111-1307, USA.
#
# $Log: c.bnf,v $
-# Revision 1.4 2001/02/20 03:23:42 youngs
-# Sync eieio to version 0.16; sync semantic to version 1.3.3
+# Revision 1.37 2001/06/03 14:01:13 zappo
+# Multi-inheritance for classes.
+# Structs like classes for C++.
+# No ; on name spaces.
+# Throws for methods.
+# (Bugs & patches from "Jesper Nordenberg" <mayhem(a)home.se>
+# and Norbert Lindlbauer <Norbert_Lindlbauer(a)betaresearch.de>)
+#
+# Revision 1.36 2001/05/25 01:12:10 zappo
+# (expression): Added string.
+#
+# Revision 1.35 2001/05/09 03:25:17 zappo
+# Added inline method support.
+# Store protection elements
+# Change enum parts to be integer variables.
+#
+# Revision 1.34 2001/05/01 16:52:40 zappo
+# Revamped lots of summary strings.
+# Added `type' as a possible expansion in classsubparts.
+#
+# Revision 1.33 2001/04/21 14:37:55 zappo
+# Spelling error for integer.
+#
+# Revision 1.32 2001/04/13 02:24:45 zappo
+# Added built in types (void, char, etc) and summaries.
+#
+# Revision 1.31 2001/04/07 02:43:48 zappo
+# Added name spaces, and references.
+#
+# Revision 1.30 2001/03/10 16:18:15 zappo
+# Added lots of summaries to %tokens.
+# variables and functions now share declmod and typedecl start
+# match, and then get recombobulated later. Prevents massive
+# reparsing.
+#
+# Revision 1.29 2001/02/24 15:24:24 zappo
+# Added a few optimizations for structure parts.
+# Used some %tokens in a few spots where I wasn't using them before.
+#
+# Revision 1.28 2001/02/20 20:36:19 zappo
+# Removed unused %put calls.
+#
+# Revision 1.27 2001/02/09 19:49:26 zappo
+# Added paren testing to argument lists.
+#
+# Revision 1.26 2001/02/09 11:47:32 zappo
+# Added type separation characters.
+# Added all constituents of DECLMOD into their own tokens.
+# Created a rule to create a list of declmods.
+#
+# Revision 1.25 2001/02/02 04:14:53 zappo
+# Added c++ to the list of language modes.
+# Added lots of operator symbol tokens.
+# Added DECLMOD symbol w/ complex regexp.
+# Added CLASS, OPERATOR, PUBLIC, PRIVATE, and PROTECTED token keywords.
+# Support parsing of a class.
+# Add class bit parsing for functions.
+# Add destructor bit parsing for functions.
+# Allow operator symbols for methods.
+# Added parent and destructor fields to extra-spec for functions.
+# The function rule now returns a function or prototype.
+#
+# Revision 1.24 2001/01/31 15:26:10 zappo
+# Added `codeblock' rule and `%scopestart'.
+#
+# Revision 1.23 2001/01/24 21:08:41 zappo
+# Added support for new token formats that use ASSOC.
+#
+# Revision 1.22 2001/01/06 14:35:40 zappo
+# Put `type' `t' onto some tokens.
+# Struct and enums now match the braces, and return nil.
+# Enum parts now have a token type of 'enum.
+# Added ... to fuction arg lists.
+# Match parens for arg lists.
#
-# Revision 1.20 2000/10/30 01:34:23 zappo
-# Tidied up opt-array stuff.
+# [...]
#
-# Revision 1.19 2000/09/27 02:08:04 zappo
-# Moved `type' to be before `function' and `variable' in `declaration'.
-#
-# Revision 1.18 2000/09/21 03:35:08 zappo
-# Fixed up struct/union variable declaration section to use new lexical
-# tokens for struct/union.
-#
-# Revision 1.17 2000/09/19 04:22:31 zappo
-# Added %keywordtable
-#
-# Revision 1.16 2000/09/14 19:23:27 zappo
-# Updated to use %token to make new tokens for use in RULES.
-#
-# Revision 1.15 2000/09/11 23:00:32 zappo
-# Use new BNF settings section.
-#
-# Revision 1.14 2000/07/05 14:41:31 zappo
-# Support multiple continuous decl modifiers.
-# Added modifiers into variables.
-#
-# Revision 1.13 2000/07/01 18:15:31 zappo
-# Updated for new elements in the tokens.
-#
-# Revision 1.12 2000/06/13 14:37:48 zappo
-# The table has moved.
-#
-# Revision 1.11 2000/05/06 01:32:57 zappo
-# Use EXPANDFULL for enums, and for argument lists to functions.
-#
-# Revision 1.10 2000/04/29 12:54:15 zappo
-# Added support for Linux __P items.
-# Added support for "..." fn prototypes.
-#
-# Revision 1.9 2000/04/28 18:57:49 zappo
-# Added system flag to include files.
-#
-# Revision 1.8 2000/04/25 14:46:42 zappo
-# structparts now uses EXPANDFULL to get positional information for it's
-# sub parts. This simplified STRUCTSUBPARTS nonterminal
-#
-# Revision 1.7 2000/04/23 15:34:28 zappo
-# Added copyright information.
-#
-# Revision 1.6 2000/04/20 23:55:03 zappo
-# Macros split from 'variable' nt.
-# Added knr-argument parsing.
-#
-# Revision 1.5 2000/04/16 22:34:07 zappo
-# Added `filename' for include rules.
-#
-# Revision 1.4 1999/12/17 20:53:16 zappo
-# Added a splice , for varnamelist.
-#
-# Revision 1.3 1999/06/06 14:20:24 zappo
-# Fixed up some language definitions.
-#
-# Revision 1.2 1999/05/18 14:08:56 zappo
-# Fixed up the returns of some nonterminals.
-#
# Revision 1.1 1999/05/17 17:28:30 zappo
# Initial revision
#
%start declaration
+%scopestart codeblock
%outputfile semantic-c.el
%parsetable semantic-toplevel-c-bovine-table
%keywordtable semantic-c-keyword-table
-%languagemode c-mode
+%languagemode (c-mode c++-mode)
%setupfunction semantic-default-c-setup
%(setq semantic-expand-nonterminal 'semantic-expand-c-nonterminal
semantic-flex-extensions semantic-flex-c-extensions
semantic-dependency-include-path semantic-default-c-path
imenu-create-index-function 'semantic-create-imenu-index
+ semantic-type-relation-separator-character '("."
"->")
+ semantic-command-separation-character ";"
document-comment-start "/*"
document-comment-line-prefix " *"
document-comment-end " */"
)%
-%token HASH punctuation "#"
%token INCLUDE "include"
%token DEFINE "define"
+%token HASH punctuation "#"
%token PERIOD punctuation "."
%token COLON punctuation ":"
%token SEMICOLON punctuation ";"
%token STAR punctuation "*"
+%token AMPERSAND punctuation "&"
+%token DIVIDE punctuation "/"
+%token PLUS punctuation "+"
+%token MINUS punctuation "-"
+%token BANG punctuation "!"
%token EQUAL punctuation "="
+%token LESS punctuation "<"
+%token GREATER punctuation ">"
%token COMA punctuation ","
+%token TILDE punctuation "~"
+
+%token EXTERN "extern"
+%put EXTERN summary "Declaration Modifier: extern <type> <name>
..."
+%token STATIC "static"
+%put STATIC summary "Declaration Modifier: static <type> <name>
..."
+%token CONST "const"
+%put CONST summary "Declaration Modifier: const <type> <name>
..."
+%token VOLATILE "volatile"
+%put VOLATILE summary "Declaration Modifier: volatile <type> <name>
..."
+%token SIGNED "signed"
+%put SIGNED summary "Numeric Type Modifier: signed <numeric type> <name>
..."
+%token UNSIGNED "unsigned"
+%put UNSIGNED summary "Numeric Type Modifier: unsigned <numeric type>
<name> ..."
+
+%token INLINE "inline"
+%put INLINE "Function Modifier: inline <return type> <name>(...)
{...};"
+%token VIRTUAL "virtual"
+%put VIRTUAL summary "Method Modifier: virtual <type> <name>(...)
..."
+
%token STRUCT "struct"
+%put STRUCT summary "Structure Type Declaration: struct [name] { ... };"
%token UNION "union"
+%put UNION summary "Union Type Declaration: union [name] { ... };"
%token ENUM "enum"
+%put ENUM summary "Enumeration Type Declaration: enum [name] { ... };"
%token TYPEDEF "typedef"
-
+%put TYPEDEF summary "Arbitrary Type Declaration: typedef <typedeclaration>
<name>;"
+%token CLASS "class"
+%put CLASS summary "Class Declaration: class <name>[:parents] { ... };"
+%token NAMESPACE "namespace"
+%put NAMESPACE summary "Namespace Declaration: namespace <name> { ...
};"
+
+%token THROW "throw"
+%put THROW summary "<type> <methoddef> (<method args>) throw
(<exception>) ..."
+
+# Leave these alone for now.
+%token OPERATOR "operator"
+%token PUBLIC "public"
+%token PRIVATE "private"
+%token PROTECTED "protected"
+
+
+# These aren't used for parsing, but is a useful place to describe the keywords.
+%token IF "if"
+%token ELSE "else"
+%put {IF ELSE} summary "if (<condition>) { code } [ else { code } ]"
+
+%token DO "do"
+%token WHILE "while"
+%put DO summary " do { code } while (<condition>);"
+%put WHILE summary "do { code } while (<condition>); or while
(<condition>) { code };"
+
+%token FOR "for"
+%put FOR summary "for(<init>; <condition>; <increment>) { code
}"
+
+%token SWITCH "switch"
+%token CASE "case"
+%token DEFAULT "default"
+%put {SWITCH CASE DEFAULT} summary
+"switch (<variable>) { case <constvalue>: code; ... default: code;
}"
+
+%token RETURN "return"
+%put RETURN summary "return <value>;"
+
+%token BREAK "break"
+%put BREAK summary "Non-local exit within a loop or switch (for, do/while, switch):
break;"
+%token CONTINUE "continue"
+%put CONTINUE summary "Non-local continue within a lool (for, do/while):
continue;"
+
+%token SIZEOF "sizeof"
+%put SIZEOF summary "Compile time macro: sizeof(<type or variable>) // size in
bytes"
+
+# Types
+%token VOID "void"
+%put VOID summary "Built in typeless type: void"
+%token CHAR "char"
+%put CHAR summary "Integral Character Type: (0 to 256)"
+%token SHORT "short"
+%put SHORT summary "Integral Primitive Type: (-32768 to 32767)"
+%token INT "int"
+%put INT summary "Integral Primitive Type: (-2147483648 to 2147483647)"
+%token LONG "long"
+%put LONG summary "Integral primitive type (-9223372036854775808 to
9223372036854775807)"
+%token FLOAT "float"
+%put FLOAT summary "Primitive floating-point type (single-precision 32-bit IEEE
754)"
+%token DOUBLE "double"
+%put DOUBLE summary "Primitive floating-point type (double-precision 64-bit IEEE
754)"
-declaration : include
- | macro
+declaration : macro
| type
- | function
- | variable
- | prototype
+ | var-or-fun
| define
;
-
-include : HASH INCLUDE punctuation "<" filename punctuation
">"
- ( ,$4 include t nil )
- | HASH INCLUDE string
- ( (read $3) include nil nil )
- ;
+codeblock : define
+ | var-or-fun
+ | type # type is less likely to be used here.
+ ;
+
+macro : HASH macro-or-include
+ ( ,$2 )
+ ;
+
+macro-or-include : DEFINE symbol opt-expression
+ ( $2 variable nil $3
+ (ASSOC const t)
+ nil
+ )
+ | INCLUDE LESS filename GREATER
+ ( ,$3 include t nil )
+ | INCLUDE string
+ ( (read $2) include nil nil )
+ ;
+
+# This is used in struct parts.
+define : HASH DEFINE symbol opt-expression
+ ( $2 variable nil $3
+ (ASSOC const t)
+ nil
+ )
+ ;
+
filename : symbol PERIOD symbol
( (concat $1 $2 $3) )
- | symbol punctuation "/" filename
+ | symbol DIVIDE filename
( (concat $1 $2 (car $3)) )
;
-
-structparts : semantic-list
- (EXPANDFULL $1 structsubparts)
+
+# In C++, structures can have the same things as classes.
+# So delete this somday in the figure.
+#
+#structparts : semantic-list
+# (EXPANDFULL $1 structsubparts)
+# ;
+#
+#structsubparts : open-paren "{"
+# ( nil )
+# | close-paren "}"
+# ( nil )
+# | var-or-fun
+# | define
+# # sometimes there are defines in structs.
+# ;
+
+classparts : semantic-list
+ (EXPANDFULL $1 classsubparts)
;
+
+classsubparts : open-paren "{"
+ ( nil )
+ | close-paren "}"
+ ( nil )
+ | opt-class-protection COLON
+ ( ,$1 label )
+ | var-or-fun
+ | type
+ | define
+ ( ,$1 protection )
+ # In C++, this label in a classsubpart represents
+ # PUBLIC or PRIVATE bits. Ignore them for now.
+ | EMPTY
+ ;
+
+opt-class-parents : COLON class-parents
+ ( $2 )
+ | EMPTY
+ ( )
+ ;
+
+class-parents : opt-class-protection symbol COMA class-parents
+ ( ,(cons $2 $4 ) )
+ | opt-class-protection symbol
+ ( $2 )
+ ;
-structsubparts : variable
- | define
- # sometimes there are defines in structs.
+opt-class-protection : PUBLIC
+ | PRIVATE
+ | PROTECTED
+ ;
+
+namespaceparts : semantic-list
+ (EXPANDFULL $1 namespacesubparts)
;
+namespacesubparts : open-paren "{"
+ ( nil )
+ | close-paren "}"
+ ( nil )
+ | type
+ | var-or-fun
+ | define
+ | opt-class-protection COLON
+ ( $1 protection )
+ # In C++, this label in a classsubpart represents
+ # PUBLIC or PRIVATE bits. Ignore them for now.
+ | EMPTY
+ ;
enumparts : semantic-list
(EXPANDFULL $1 enumsubparts)
;
enumsubparts : symbol opt-assign
- ( $1 )
+ ( $1 variable "int" ,$2 (ASSOC const t) nil)
+ | open-paren "{"
+ ( nil )
+ | close-paren "}"
+ ( nil )
;
opt-name : symbol
@@ -165,8 +353,8 @@
( nil )
;
-typesimple : STRUCT opt-name structparts
- ( ,$2 type $1 $3 nil nil nil )
+typesimple : struct-or-class opt-name opt-class-parents classparts
+ ( ,$2 type ,$1 $4 ,$3 nil nil )
| UNION opt-name structparts
( ,$2 type $1 $3 nil nil nil )
| ENUM opt-name enumparts
@@ -175,8 +363,14 @@
( $3 type $1 nil $2 nil nil )
;
+struct-or-class: STRUCT
+ | CLASS
+ ;
+
type : typesimple SEMICOLON
( ,$1 )
+ | NAMESPACE symbol namespaceparts
+ ( $2 type $1 $3 nil nil nil )
;
opt-stars : STAR opt-stars
@@ -185,19 +379,34 @@
( 0 )
;
-declmods : symbol
"\\(_+\\)?\\(extern\\|static\\|const\\|volitile\\|signed\\|unsigned\\)"
declmods
- ( ,(cons $1 $2 ) )
- | symbol
"\\(_+\\)?\\(extern\\|static\\|const\\|volitile\\|signed\\|unsigned\\)"
- ( $1 )
+declmods : DECLMOD declmods
+ ( ,(cons ,(car ,$1) $2 ) )
+ | DECLMOD
+ ( ,$1 )
| EMPTY
()
;
+
+DECLMOD : EXTERN
+ | STATIC
+ | CONST
+ | VOLATILE
+ | SIGNED
+ | UNSIGNED
+ | VIRTUAL
+ | INLINE
+ ;
-# dont deal with the stars just yet.
-typeform : typeformbase opt-stars
+# Don't deal with the stars or reference just yet.
+typeform : typeformbase opt-stars opt-ref
( ,$1 )
;
+# C++: A type can be modified into a reference by "&"
+opt-ref : AMPERSAND
+ | EMPTY
+ ;
+
typeformbase : typesimple
( ,$1 )
| STRUCT symbol
@@ -206,10 +415,55 @@
( $2 type $1 )
| ENUM symbol
( $2 type $1 )
+ | builtintype
+ ( ,$1 )
| symbol
( $1 )
;
-
+
+builtintype : VOID
+ | CHAR
+ | SHORT
+ | INT
+ | LONG
+ | FLOAT
+ | DOUBLE
+ ;
+
+var-or-fun : declmods typeform var-or-func-decl
+ ( ,(semantic-c-reconstitute-token ,$3 $1 $2 ) )
+ # it is possible for a function to not have a type, and
+ # it is then assumed to be an int. How annoying.
+ | declmods var-or-func-decl
+ ( ,(semantic-c-reconstitute-token ,$2 $1 nil ) )
+ ;
+
+var-or-func-decl : opt-class opt-destructor functionname arg-list
+ opt-throw
+ fun-or-proto-end
+ ( ,$3 'function
+ ;; Extra stuff goes in here.
+ ;; Continue with the stuff we found in
+ ;; this definition
+ $1 $2 $4 $5)
+ | varnamelist SEMICOLON
+ ( $1 'variable )
+ ;
+
+opt-throw : THROW semantic-list
+ ( EXPAND $2 throw-exception-list )
+ | EMPTY
+ ;
+
+# Is this true? I don't actually know.
+throw-exception-list : symbol COMA throw-exception-list
+ ( ,(cons $1 $3) )
+ | symbol close-paren ")"
+ ( $1 )
+ | open-paren "(" throw-exception-list
+ ( ,$2 )
+ ;
+
opt-bits : COLON symbol
( $2 )
| EMPTY
@@ -230,19 +484,6 @@
( nil )
;
-macro : HASH DEFINE symbol opt-expression
- ( $3 variable nil t $4 nil nil )
- ;
-
-variable : variabledef SEMICOLON
- ( ,$1 )
- ;
-
-variabledef : declmods typeform varnamelist
- ( $3 variable $2 (if $1 (string-match "const" (car $1))) nil
- (if (and $1 (string-match "const" (car $1))) (cdr $1) $1) nil )
- ;
-
opt-restrict : symbol "\\<\\(__\\)?restrict\\>"
| EMPTY
;
@@ -253,9 +494,11 @@
# I should store more in this def, but leave it simple for now.
variablearg : declmods typeform varname
- ( (car $3) variable $2 (if $1 (string-match "const" (car $1)))
- nil (if (and $1 (string-match "const" (car $1))) (cdr $1) $1)
- nil )
+ ( (car $3) variable $2 nil
+ (ASSOC const (if (member "const" $1) t nil)
+ typemodifiers (delete "const" $1))
+ nil
+ )
;
varnamelist : varname COMA varnamelist
@@ -264,11 +507,23 @@
( $1 )
;
+opt-class : symbol COLON COLON
+ ( $1 )
+ | EMPTY
+ ( nil )
+ ;
+
+opt-destructor : TILDE
+ ( t )
+ | EMPTY
+ ( nil )
+ ;
+
arg-list : symbol "\\<__?P\\>" semantic-list
(EXPAND $2 arg-list-p)
- | semantic-list knr-arguments
+ | semantic-list "^(" knr-arguments
( ,$2 )
- | semantic-list
+ | semantic-list "^("
(EXPANDFULL $1 arg-sub-list)
;
@@ -284,35 +539,61 @@
arg-sub-list : variablearg
( ,$1 )
- | PERIOD PERIOD PERIOD
- close-paren ")"
+ | PERIOD PERIOD PERIOD close-paren ")"
( "..." )
+ | open-paren "("
+ ( nil )
+ | close-paren ")"
+ ( nil )
;
-functiondef : declmods typeform symbol arg-list
- ( $3 function $2 $4 $1 nil )
- ;
+operatorsym : LESS LESS
+ ( "<<" )
+ | GREATER GREATER
+ ( ">>" )
+ | EQUAL EQUAL
+ ( "==" )
+ | LESS EQUAL
+ ( "<=" )
+ | GREATER EQUAL
+ ( ">=" )
+ | BANG EQUAL
+ ( "!=" )
+ | LESS
+ | GREATER
+ | STAR
+ | PLUS
+ | MINUS
+ | DIVIDE
+ | EQUAL
+ ;
-prototype : functiondef SEMICOLON
- ( ,$1 )
- ;
+functionname : OPERATOR operatorsym
+ ( ,$2 )
+ | symbol
+ ( $1 )
+ ;
-function : functiondef semantic-list
- ( ,$1 )
- ;
+fun-or-proto-end: SEMICOLON
+ ( t )
+ | semantic-list
+ ( nil )
+ ;
opt-expression : expression
| EMPTY ( nil )
;
-# Use expressiosn for parsing only. Don't actually return anything
-# for now. Hopefully we can't fix this later.
+# Use expression for parsing only. Don't actually return anything
+# for now. Hopefully we can fix this later.
expression : symbol
- ( nil )
+ ( )
| punctuation "[!*&~]" symbol
- ( nil )
+ ( )
+ | string
+ ( )
| semantic-list
- ( nil )
+ ( )
# | expression "+-*/%^|&" expression
# ( nil )
;
Index: xemacs-packages/semantic/document-vars.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/semantic/document-vars.el,v
retrieving revision 1.4
diff -u -r1.4 document-vars.el
--- xemacs-packages/semantic/document-vars.el 2001/02/20 03:23:43 1.4
+++ xemacs-packages/semantic/document-vars.el 2001/08/15 05:28:15
@@ -1,10 +1,10 @@
;;; document-vars.el --- Default settings for the document package.
-;;; Copyright (C) 2000 Eric M. Ludlam
+;;; Copyright (C) 2000, 2001 Eric M. Ludlam
;; Author: Eric M. Ludlam <zappo(a)gnu.org>
;; Keywords: doc
-;; X-RCS: $Id: document-vars.el,v 1.4 2001/02/20 03:23:43 youngs Exp $
+;; X-RCS: $Id: document-vars.el,v 1.2 2001/05/01 16:51:33 zappo Exp $
;; This file is not part of GNU Emacs.
@@ -34,7 +34,7 @@
(defcustom document-copyright-notice-file nil
"*A file name containing a copyright notice.
It will be reformatted in the header to have the correct prefix character.
-See the %N token in document-file-comment"
+See the %N token in `document-file-comment'"
:group 'document
:type 'file)
Index: xemacs-packages/semantic/document.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/semantic/document.el,v
retrieving revision 1.5
diff -u -r1.5 document.el
--- xemacs-packages/semantic/document.el 2001/02/20 03:23:43 1.5
+++ xemacs-packages/semantic/document.el 2001/08/15 05:28:16
@@ -1,13 +1,11 @@
;;; document.el --- Use the bovinator to aid in generating documentation.
-;;; Copyright (C) 2000 Eric M. Ludlam
+;;; Copyright (C) 2000, 2001 Eric M. Ludlam
;; Author: Eric M. Ludlam <zappo(a)gnu.org>
;; Keywords: doc
-;; X-RCS: $Id: document.el,v 1.5 2001/02/20 03:23:43 youngs Exp $
+;; X-RCS: $Id: document.el,v 1.9 2001/04/13 16:46:46 zappo Exp $
-;; This file is not part of GNU Emacs.
-
;; Semantic is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
@@ -33,6 +31,10 @@
;; Document then provides some rules for creating English Text based
;; on the name of a given function, it's return type, or variable
;; type. It also has output rules for texinfo, or comments.
+;;
+;; NOTE: Some of the user level commands in document.el dealing with
+;; texinfo files have been obsoleted commands in semantic-texi, which
+;; can not insert foriegn tokens.
(require 'sformat)
(require 'document-vars)
@@ -99,7 +101,9 @@
(error "No file found for your documentation"))
(set-buffer (marker-buffer document-current-output-file))
(goto-char document-current-output-file)
+ (insert "\n")
(document-insert-texinfo cdi cdib)
+ (insert "\n")
(setq document-current-output-file (point-marker))
))
@@ -114,13 +118,16 @@
;;
(defun document-insert-texinfo (nonterm buffer)
"Insert texinfo documentation about NONTERM from BUFFER."
- (insert "\n")
(let ((tt (semantic-token-token nonterm)))
(insert "@"
(cond ((eq tt 'variable)
- "defvar")
+ (if (semantic-token-extra-spec nonterm 'user-visible)
+ "deffn Option"
+ "defvar"))
((eq tt 'function)
- "defun")
+ (if (semantic-token-extra-spec nonterm 'user-visible)
+ "deffn Command"
+ "defun"))
((eq tt 'type)
"deftype")
(t (error "Don't know how to document that")))
@@ -141,12 +148,16 @@
(document-generate-documentation nonterm buffer)))
(insert "\n@end "
(cond ((eq tt 'variable)
- "defvar")
+ (if (semantic-token-extra-spec nonterm 'user-visible)
+ "deffn"
+ "defvar"))
((eq tt 'function)
- "defun")
+ (if (semantic-token-extra-spec nonterm 'user-visible)
+ "deffn"
+ "defun"))
((eq tt 'type)
"deftype"))
- "\n")))
+ )))
(defun document-insert-defun-comment (nonterm buffer)
"Insert mode-comment documentation about NONTERM from BUFFER."
@@ -266,18 +277,20 @@
;;
(defun document-generate-documentation (nonterm buffer)
"Return a plain string documenting NONTERM from BUFFER."
- (let ((doc ;; Second, does this thing have docs in the source buffer which
- ;; an override method might be able to find?
- (semantic-find-documentation nonterm)
- ))
- (if (not doc)
- (document-generate-new-documentation nonterm buffer)
- ;; Ok, now lets see what sort of formatting there might be,
- ;; and see about removing some of it.. (Tables of arguments,
- ;; and that sort of thing.)
- nil
- ;; Return the string.
- doc)))
+ (save-excursion
+ (set-buffer buffer)
+ (let ((doc ;; Second, does this thing have docs in the source buffer which
+ ;; an override method might be able to find?
+ (semantic-find-documentation nonterm)
+ ))
+ (if (not doc)
+ (document-generate-new-documentation nonterm buffer)
+ ;; Ok, now lets see what sort of formatting there might be,
+ ;; and see about removing some of it.. (Tables of arguments,
+ ;; and that sort of thing.)
+ nil
+ ;; Return the string.
+ doc))))
(defun document-generate-new-documentation (nonterm buffer)
"Look at elements of NONTERM in BUFFER to make documentation.
@@ -764,7 +777,7 @@
;; run the elisp version through also.
(let ((case-fold-search nil))
(while (string-match
- "\\(^\\|[^{]\\)\\<\\([A-Z0-9_]+\\)\\>\\($\\|[^}]\\)"
+ "\\(^\\|[^{]\\)\\<\\([A-Z0-9_-]+\\)\\>\\($\\|[^}]\\)"
string)
(setq string (concat (substring string 0 (match-beginning 2))
"@var{"
@@ -784,6 +797,7 @@
`variable' => @code{variable}
`class' => @code{class} @xref{class}
`unknown' => @code{unknonwn}
+ \"text\" => ``text''
'quoteme => @code{quoteme}
non-nil => non-@code{nil}
t => @code{t}
@@ -808,6 +822,8 @@
(setq string (replace-match "@code{\\2}" t nil string 2)))
(while (string-match "\\( \\|^\\)\\(\\(\\(C-\\|M-\\|S-\\)+\\([^
\t\n]\\|RET\\|SPC\\|TAB\\)\\)\\|\\(RET\\|SPC\\|TAB\\)\\)\\( \\|$\\)" string)
(setq string (replace-match "@kbd{\\2}" t nil string 2)))
+ (while (string-match "\"\\(.+\\)\"" string)
+ (setq string (replace-match "``\\1''" t nil string 0)))
string)
;;; Buffer finding and managing
Index: xemacs-packages/semantic/java.bnf
===================================================================
RCS file: java.bnf
diff -N java.bnf
--- /dev/null Tue Aug 14 14:29:33 2001
+++ java.bnf Tue Aug 14 22:28:16 2001
@@ -0,0 +1,653 @@
+# BNF grammar for Java
+#
+# Copyright (C) 2000, 2001 Paul F. Kinnucan, Jr.
+# Copyright (C) 2001 David Ponce
+#
+# Author: Paul F. Kinnucan, Jr. <paulk(a)mathworks.com>
+# David Ponce <david(a)dponce.com>
+#
+# $Id: java.bnf,v 1.11 2001/05/23 13:39:52 ponced Exp $
+#
+# java.bnf is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This software is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Emacs; see the file COPYING. If not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# --------
+# Settings
+# --------
+%outputfile semantic-java.el
+%parsetable semantic-toplevel-java-bovine-table
+%keywordtable semantic-java-keyword-table
+%languagemode java-mode
+%setupfunction semantic-default-java-setup
+
+%(progn
+ (setq
+ ;; Java is case sensitive
+ semantic-case-fold nil
+ ;; special handling of multiple variable declarations/statement
+ semantic-expand-nonterminal 'semantic-expand-java-nonterminal
+ ;; function to use when creating items in imenu
+ semantic-imenu-summary-function 'semantic-prototype-nonterminal
+ ;; function to use for creating the imenu
+ imenu-create-index-function 'semantic-create-imenu-index
+ ;; Character used to separation a parent/child relationship
+ semantic-type-relation-separator-character '(".")
+ semantic-command-separation-character ";"
+ document-comment-start "/**"
+ document-comment-line-prefix " *"
+ document-comment-end " */"
+ ;; speedbar and imenu buckets name
+ semantic-symbol->name-assoc-list '((type . "Classes")
+ (variable . "Variables")
+ (function . "Methods")
+ (include . "Imports")
+ (package . "Package"))
+ ;; Semantic navigation inside 'type children
+ senator-step-at-token-ids '(function variable)
+ )
+ ;; Needed by `semantic-find-doc-snarf-comment'.
+ (set (make-local-variable 'block-comment-end) "\\s-*\\*/")
+ )%
+
+%token ABSTRACT "abstract"
+%put ABSTRACT summary
+"Class|Method declaration modifier: abstract {class|<type>} <name>
..."
+
+%token BOOLEAN "boolean"
+%put BOOLEAN summary
+"Primitive logical quantity type (true or false)"
+
+%token BREAK "break"
+%put BREAK summary
+"break [<label>] ;"
+
+%token BYTE "byte"
+%put BYTE summary
+"Integral primitive type (-128 to 127)"
+
+%token CASE "case"
+%put CASE summary
+"switch(<expr>) {case <const-expr>: <stmts> ... }"
+
+%token CATCH "catch"
+%put CATCH summary
+"try {<stmts>} catch(<parm>) {<stmts>} ... "
+
+%token CHAR "char"
+%put CHAR summary
+"Integral primitive type ('\u0000' to '\uffff') (0 to 65535)"
+
+%token CLASS "class"
+%put CLASS summary
+"Class declaration: class <name>"
+
+%token CONST "const"
+%put CONST summary
+"Unused reserved word"
+
+%token CONTINUE "continue"
+%put CONTINUE summary
+"continue [<label>] ;"
+
+%token DEFAULT "default"
+%put DEFAULT summary
+"switch(<expr>) { ... default: <stmts>}"
+
+%token DO "do"
+%put DO summary
+"do <stmt> while (<expr>);"
+
+%token DOUBLE "double"
+%put DOUBLE summary
+"Primitive floating-point type (double-precision 64-bit IEEE 754)"
+
+%token ELSE "else"
+%put ELSE summary
+"if (<expr>) <stmt> else <stmt>"
+
+%token EXTENDS "extends"
+%put EXTENDS summary
+"SuperClass|SuperInterfaces declaration: extends <name> [, ...]"
+
+%token FINAL "final"
+%put FINAL summary
+"Class|Member declaration modifier: final {class|<type>} <name>
..."
+
+%token FINALLY "finally"
+%put FINALLY summary
+"try {<stmts>} ... finally {<stmts>}"
+
+%token FLOAT "float"
+%put FLOAT summary
+"Primitive floating-point type (single-precision 32-bit IEEE 754)"
+
+%token FOR "for"
+%put FOR summary
+"for ([<init-expr>]; [<expr>]; [<update-expr>])
<stmt>"
+
+%token GOTO "goto"
+%put GOTO summary
+"Unused reserved word"
+
+%token IF "if"
+%put IF summary
+"if (<expr>) <stmt> [else <stmt>]"
+
+%token IMPLEMENTS "implements"
+%put IMPLEMENTS summary
+"Class SuperInterfaces declaration: implements <name> [, ...]"
+
+%token IMPORT "import"
+%put IMPORT summary
+"Import package declarations: import <package>"
+
+%token INSTANCEOF "instanceof"
+
+%token INT "int"
+%put INT summary
+"Integral primitive type (-2147483648 to 2147483647)"
+
+%token INTERFACE "interface"
+%put INTERFACE summary
+"Interface declaration: interface <name>"
+
+%token LONG "long"
+%put LONG summary
+"Integral primitive type (-9223372036854775808 to 9223372036854775807)"
+
+%token NATIVE "native"
+%put NATIVE summary
+"Method declaration modifier: native <type> <name> ..."
+
+%token NEW "new"
+
+%token PACKAGE "package"
+%put PACKAGE summary
+"Package declaration: package <name>"
+
+%token PRIVATE "private"
+%put PRIVATE summary
+"Access level modifier: private {class|interface|<type>} <name>
..."
+
+%token PROTECTED "protected"
+%put PROTECTED summary
+"Access level modifier: protected {class|interface|<type>} <name>
..."
+
+%token PUBLIC "public"
+%put PUBLIC summary
+"Access level modifier: public {class|interface|<type>} <name>
..."
+
+%token RETURN "return"
+%put RETURN summary
+"return [<expr>] ;"
+
+%token SHORT "short"
+%put SHORT summary
+"Integral primitive type (-32768 to 32767)"
+
+%token STATIC "static"
+%put STATIC summary
+"Declaration modifier: static {class|interface|<type>} <name>
..."
+
+%token STRICTFP "strictfp"
+%put STRICTFP summary
+"Declaration modifier: strictfp {class|interface|<type>} <name>
..."
+
+%token SUPER "super"
+
+%token SWITCH "switch"
+%put SWITCH summary
+"switch(<expr>) {[case <const-expr>: <stmts> ...] [default:
<stmts>]}"
+
+
+%token SYNCHRONIZED "synchronized"
+%put SYNCHRONIZED summary
+"synchronized (<expr>) ... | Method decl. modifier: synchronized <type>
<name> ..."
+
+%token THIS "this"
+
+%token THROW "throw"
+%put THROW summary
+"throw <expr> ;"
+
+%token THROWS "throws"
+%put THROWS summary
+"Method|Constructor declaration: throws <classType>, ..."
+
+%token TRANSIENT "transient"
+%put TRANSIENT summary
+"Field declaration modifier: transient <type> <name> ..."
+
+%token TRY "try"
+%put TRY summary
+"try {<stmts>} [catch(<parm>) {<stmts>} ...] [finally
{<stmts>}]"
+
+%token VOID "void"
+%put VOID summary
+"Method return type: void <name> ..."
+
+%token VOLATILE "volatile"
+%put VOLATILE summary
+"Field declaration modifier: volatile <type> <name> ..."
+
+%token WHILE "while"
+%put WHILE summary
+"while (<expr>) <stmt> | do <stmt> while (<expr>);"
+
+# --------------------------
+# Official javadoc line tags
+# --------------------------
+
+# Javadoc tags are identified by a 'javadoc' keyword property. The
+# value of this property must be itself a property list where the
+# following properties are recognized:
+#
+# - `seq' (mandatory) is the tag sequence number used to check if tags
+# are correctly ordered in a javadoc comment block.
+#
+# - `usage' (mandatory) is the list of token categories for which this
+# documentation tag is allowed.
+#
+# - `opt' (optional) if non-nil indicates this is an optional tag.
+# By default tags are mandatory.
+#
+# - `with-name' (optional) if non-nil indicates that this tag is
+# followed by an identifier like in "@param <var-name> description"
+# or "@exception <class-name> description".
+#
+# - `with-ref' (optional) if non-nil indicates that the tag is
+# followed by a reference like in "@see <reference>".
+
+%token AUTHOR "author"
+%put AUTHOR javadoc (seq 1 usage (type))
+%token VERSION "version"
+%put VERSION javadoc (seq 2 usage (type))
+%token PARAM "param"
+%put PARAM javadoc (seq 3 usage (function) with-name t)
+#%token RETURN "return"
+%put RETURN javadoc (seq 4 usage (function))
+%token EXCEPTION "exception"
+%put EXCEPTION javadoc (seq 5 usage (function) with-name t)
+#%token THROWS "throws"
+%put THROWS javadoc (seq 6 usage (function) with-name t)
+%token SEE "see"
+%put SEE javadoc (seq 7 usage (type function variable) opt t with-ref t)
+%token SINCE "since"
+%put SINCE javadoc (seq 8 usage (type function variable) opt t)
+%token SERIAL "serial"
+%put SERIAL javadoc (seq 9 usage (variable) opt t)
+%token SERIALDATA "serialData"
+%put SERIALDATA javadoc (seq 10 usage (function) opt t)
+%token SERIALFIELD "serialField"
+%put SERIALFIELD javadoc (seq 11 usage (variable) opt t)
+%token DEPRECATED "deprecated"
+%put DEPRECATED javadoc (seq 12 usage (type function variable) opt t)
+
+# --------
+# Grammar
+# --------
+bovine-toplevel : package_declaration
+ | import_declaration
+ | type_declaration
+ ;
+
+number : symbol "[0-9]" punctuation "\\." symbol
"[0-9Ee]"
+ punctuation "[-+]" symbol "[0-9fFdD]"
+ | symbol "[0-9]" punctuation "\\." symbol
"[0-9EefFdD]"
+ | symbol "[0-9fFdD]"
+ ;
+
+literal : number
+ | qualified_name
+ | string
+ ;
+
+type : reference_type
+ (,$1)
+ | primitive_type
+ (,$1)
+ ;
+
+primitive_type : BOOLEAN | BYTE | SHORT | INT | LONG | CHAR | FLOAT | DOUBLE
+ ;
+
+reference_type : array_type
+ (,$1)
+ | qualified_name
+ (,$1)
+ ;
+
+array_type : primitive_type dims
+ ((concat (car $1) (car $2)))
+ | qualified_name dims
+ ((concat (car $1) (car $2)))
+ ;
+
+qualified_name : symbol punctuation "\\." qualified_name
+ ((concat $1 $2 (car $3)))
+ | symbol
+ ($1)
+ ;
+
+## TOP-LEVEL ENTRY: package definition.
+## ("NAME" package DETAIL "DOCSTRING")
+package_declaration : PACKAGE qualified_name punctuation ";"
+ (,$2 package nil nil)
+ ;
+
+
+## TOP-LEVEL ENTRY: import definition.
+## ("FILE" include SYSTEM "DOCSTRING")
+import_declaration : IMPORT qualified_name punctuation ";"
+ (,$2 include nil nil)
+ | IMPORT qualified_name punctuation "\\." punctuation
"*" punctuation ";"
+ ((concat (car $2) $3 $4) include nil nil)
+ ;
+
+type_declaration : punctuation ";"
+ | class_declaration
+ | interface_declaration
+ ;
+
+modifiers_opt : modifiers
+ (,$1)
+ | EMPTY
+ ;
+
+modifiers : modifier modifiers
+ (,(cons (car $1) ,$2))
+ | modifier
+ (,$1)
+ ;
+
+modifier : PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT
+ | FINAL | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | STRICTFP
+ ;
+
+## TOP-LEVEL ENTRY: class definition.
+## ("NAME" type "TYPE" PART-LIST PARENTS EXTRA-SPECS
"DOCSTRING")
+class_declaration : modifiers_opt CLASS qualified_name class_parents class_body
+ ( ,$3 type "class" $5 $4
+ (ASSOC typemodifiers $1)
+ nil
+ )
+ ;
+
+# class_parents := nil | (["extends_this" | nil] ["implements_this1"
... "implements_thisN"])
+class_parents: super interfaces
+ (,(append $1 $2))
+ | interfaces super
+ (,(append $2 $1))
+ | super
+ (,$1)
+ | interfaces
+ (,(cons nil $1))
+ | EMPTY
+ ;
+
+super : EXTENDS qualified_name
+ (,$2)
+ ;
+
+interfaces : IMPLEMENTS qualified_name_list
+ (,$2)
+ ;
+
+qualified_name_list : qualified_name punctuation "," qualified_name_list
+ (,(cons (car $1) ,$3))
+ | qualified_name
+ (,$1)
+ ;
+
+class_body : semantic-list # ::= {class_body_declarations}
+ (EXPANDFULL $1 class_body_declarations)
+ ;
+
+class_body_declarations : class_declaration
+ (,$1)
+ | interface_declaration
+ (,$1)
+ | field_declaration
+ (,$1)
+ | method_declaration
+ (,$1)
+ #| static_initializer
+ | constructor_declaration
+ (,$1)
+ #| block
+ ;
+
+## TOP-LEVEL ENTRY: variable definition.
+## ("NAME" variable "TYPE" DEFAULT-VALUE EXTRA-SPECS
"DOCSTRING")
+field_declaration : modifiers_opt type variable_declarators punctuation ";"
+ (,$3 variable ,$2 nil
+ (ASSOC typemodifiers $1)
+ nil)
+ ;
+
+## The following rule is used by `semantic-expand-java-nonterminal' to
+## reparse declaration of multiple variables in the same statement.
+## Reparsing is done with `semantic-bovinate-from-nonterminal-full' to
+## get correct START END information for each variable token.
+field_declaration_multi : modifiers_opt type variable_declarator punctuation
","
+ (,$3)
+ | modifiers_opt type variable_declarator punctuation
";"
+ (,$3)
+ | variable_declarator punctuation ","
+ (,$1)
+ | variable_declarator punctuation ";"
+ (,$1)
+ ;
+
+variable_declarators : variable_declarator variable_declarators_opt
+ ((cons (car $1) (car $2)))
+ ;
+
+variable_declarators_opt: punctuation "," variable_declarators
+ (,$2)
+ | EMPTY
+ ;
+
+variable_declarator : variable_declarator_id variable_assign_opt
+ (,$1)
+ ;
+
+variable_assign_opt: punctuation "=" variable_initializer
+ | EMPTY
+ ;
+
+variable_declarator_id : symbol dims
+ ((concat $1 (car $2)))
+ | symbol
+ ($1)
+ ;
+
+variable_initializer : array_initializer
+ | expression
+ ;
+
+method_declaration : method_header method_body
+ (,$1)
+ ;
+
+## TOP-LEVEL ENTRY: method definition.
+## ("NAME" function "TYPE" ARG-LIST EXTRA-SPECS
"DOCSTRING")
+method_header : modifiers_opt method_type symbol formal_parameter_list_opt throws_opt
+ ($3 function ,$2 $4
+ (ASSOC typemodifiers $1 throws $5)
+ nil)
+ ;
+
+method_type: VOID
+ ($1)
+ | type
+ (,$1)
+ ;
+
+formal_parameter_list_opt : semantic-list # ::= (formal_parameter_list)
+ (EXPANDFULL $1 formal_parameter_list)
+ | EMPTY
+ ;
+
+formal_parameter_list : formal_parameter punctuation ","
+ (,$1)
+ | formal_parameter
+ (,$1)
+ ;
+
+formal_parameter-modifier : FINAL
+ | EMPTY
+ ;
+
+## TOP-LEVEL ENTRY: variable definition.
+## ("NAME" variable "TYPE" DEFAULT-VALUE EXTRA-SPECS
"DOCSTRING")
+formal_parameter : formal_parameter-modifier type variable_declarator_id
+ (,$3 variable ,$2 nil
+ (ASSOC typemodifiers $1)
+ nil)
+ ;
+
+throws_opt : throws
+ (,$1)
+ | EMPTY
+ ;
+
+throws : THROWS qualified_name_list
+ (,$2)
+ ;
+
+method_body : punctuation ";"
+ | block
+ ;
+
+#static_initializer : STATIC block
+# ;
+
+## TOP-LEVEL ENTRY: constructor definition.
+## ("NAME" function "TYPE" ARG-LIST EXTRA-SPECS
"DOCSTRING")
+constructor_declaration : modifiers_opt symbol formal_parameter_list_opt throws_opt
+ constructor_body
+ ($2 function nil $3
+ (ASSOC typemodifiers $1 throws $4)
+ nil)
+ ;
+
+constructor_body : block
+ ;
+
+## TOP-LEVEL ENTRY: interface definition.
+## ("NAME" type "TYPE" PART-LIST PARENTS EXTRA-SPECS
"DOCSTRING")
+interface_declaration : modifiers_opt INTERFACE symbol interface_parents interface_body
+ ($3 type "interface" $5 $4
+ (ASSOC typemodifiers $1)
+ nil)
+ ;
+
+# interface_parents := nil | ("extends_this1" ... "extends_thisN")
+interface_parents : EXTENDS qualified_name_list
+ (,$2)
+ | EMPTY
+ ;
+
+interface_body : semantic-list # ::= { interface_body_declarations }
+ (EXPANDFULL $1 interface_body_declarations)
+ ;
+
+interface_body_declarations : class_declaration
+ (,$1)
+ | interface_declaration
+ (,$1)
+ | method_header punctuation ";"
+ (,$1)
+ | field_declaration
+ (,$1)
+ ;
+
+array_initializer : semantic-list "\\`{" # ::= {expression, expression, ...}
+ ;
+
+block : semantic-list "\\`{" # ::= {statements}
+ ;
+
+primary : array_creation_expression
+ | primary_no_new_array primary_dim_opt
+ ;
+
+primary_dim_opt : semantic-list "\\`\\["
+ | EMPTY
+ ;
+
+primary_no_new_array : qualified_name semantic-list "\\`(" #
method_invocation
+ | class_instance_creation_expression
+ | semantic-list "\\`(" # (expression)
+ | array_type punctuation "\\." CLASS
+ | literal
+ ;
+
+class_instance_creation_expression : NEW qualified_name semantic-list "\\`("
+ semantic-list "\\`{" # ::= {
class_body_declarations }
+ | NEW qualified_name semantic-list "\\`("
+ ;
+
+## array_creation_expression : NEW qualified_name dims array_initializer
+## | NEW qualified_name dims #dim_exprs dims_opt
+## ;
+array_creation_expression : NEW array_type array_initializer
+ | NEW array_type #dim_exprs dims_opt
+ ;
+
+dims_opt : dims
+ (,$1)
+ | EMPTY
+ (nil)
+ ;
+
+dims: semantic-list "\\`\\[" dims_opt
+ ((concat "[]" (car ,$2)))
+ ;
+
+field_access : primary punctuation "\\." symbol
+ | qualified_name
+ ;
+
+postfix_expression : primary postfix_operator_opt
+ ;
+
+postfix_operator_opt: punctuation "[-+]" punctuation "[-+]"
+ | EMPTY
+ ;
+
+unary_expression : punctuation "[-+^!]" unary_expression
+ | punctuation "[-+]" punctuation "[-+]"
unary_expression
+ | semantic-list "\\`(" unary_expression # cast
+ | postfix_expression
+ ;
+
+operator: punctuation "[-+*/%=<>^~&|!?:.]" # added DOT as
field/method access operator
+ | INSTANCEOF
+ ;
+
+operators: operator operators
+ | operator
+ ;
+
+operators_expression_opt: operators expression
+ | EMPTY
+ ;
+
+expression: unary_expression operators_expression_opt
+ ;
+
+# End of java.bnf
\ No newline at end of file
Index: xemacs-packages/semantic/make.bnf
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/semantic/make.bnf,v
retrieving revision 1.4
diff -u -r1.4 make.bnf
--- xemacs-packages/semantic/make.bnf 2001/02/20 03:23:43 1.4
+++ xemacs-packages/semantic/make.bnf 2001/08/15 05:28:16
@@ -1,9 +1,9 @@
# Simple BNF notation for Makefiles.
#
-# Copyright (C) 1999, 2000 Eric M. Ludlam
+# Copyright (C) 1999, 2000, 2001 Eric M. Ludlam
#
# Author: Eric M. Ludlam <zappo(a)gnu.org>
-# X-RCS: $Id: make.bnf,v 1.4 2001/02/20 03:23:43 youngs Exp $
+# X-RCS: $Id: make.bnf,v 1.7 2001/04/13 02:01:59 zappo Exp $
#
# make.bnf is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -21,9 +21,13 @@
# Boston, MA 02111-1307, USA.
#
# $Log: make.bnf,v $
-# Revision 1.4 2001/02/20 03:23:43 youngs
-# Sync eieio to version 0.16; sync semantic to version 1.3.3
+# Revision 1.7 2001/04/13 02:01:59 zappo
+# Added a keyword table, and several new tokens and summaries.
+# Added support for the include macro.
#
+# Revision 1.6 2001/01/24 21:09:21 zappo
+# Added support for new token formats that use ASSOC.
+#
# Revision 1.5 2000/11/13 21:06:42 zappo
# Fixed comment.
#
@@ -42,8 +46,9 @@
%start Makefile
%outputfile semantic-make.el
+%keywordtable semantic-make-keyword-table
%parsetable semantic-toplevel-make-bovine-table
-%languagemode make-mode
+%languagemode makefile-mode
%setupfunction semantic-default-make-setup
%quotemode backquote
@@ -66,35 +71,50 @@
imenu-create-index-function 'semantic-create-imenu-index
)%
+%token IF "if"
+%token ELSE "else"
+%token ENDIF "endif"
+%put { IF ELSE ENDIF } summary "Conditional: if (expression) ... else ...
endif"
+%token INCLUDE "include"
+%put INCLUDE summary "Macro: include filename1 filename2 ..."
+
+%token COLON punctuation ":"
+%token PLUS punctuation "+"
+%token EQUAL punctuation "="
Makefile : variable
| rule
| conditional
+ | include
;
variable: symbol equals elements
- (,$1 variable nil nil ,$3 nil nil)
+ (,$1 variable nil ,$3 nil nil)
;
rule: symbol colons elements commands
(,$1 function nil ,$3 nil nil)
;
-conditional: symbol "if" symbol newline
- ( nil )
- | symbol "else" newline
- ( nil )
- | symbol "endif" newline
- ( nil )
+conditional: IF symbol newline
+ ( )
+ | ELSE newline
+ ( )
+ | ENDIF newline
+ ( )
;
-equals: punctuation ":" punctuation "=" ()
- | punctuation "+" punctuation "=" ()
- | punctuation "=" ()
+include: INCLUDE symbol elements
+ (,$2 include nil)
+ ;
+
+equals: COLON EQUAL ()
+ | PLUS EQUAL ()
+ | EQUAL ()
;
-colons: punctuation ":" punctuation ":" ()
- | punctuation ":" ()
+colons: COLON COLON ()
+ | COLON ()
;
elements: symbol elements
Index: xemacs-packages/semantic/scheme.bnf
===================================================================
RCS file: scheme.bnf
diff -N scheme.bnf
--- /dev/null Tue Aug 14 14:29:33 2001
+++ scheme.bnf Tue Aug 14 22:28:16 2001
@@ -0,0 +1,89 @@
+# Scheme BNF language specification
+#
+# Copyright (C) 2001 Eric M. Ludlam
+#
+# Author: Eric M. Ludlam <zappo(a)gnu.org>
+# X-RCS: $Id: scheme.bnf,v 1.3 2001/05/23 23:09:12 zappo Exp $
+#
+# This is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This software is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Emacs; see the file COPYING. If not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+%start scheme
+%outputfile semantic-scm.el
+%parsetable semantic-toplevel-scheme-bovine-table
+%keywordtable semantic-scheme-keyword-table
+%languagemode scheme-mode
+%setupfunction semantic-default-scheme-setup
+
+%(setq semantic-symbol->name-assoc-list '( (variable . "Variables")
+ ;;(type . "Types")
+ (function . "Functions")
+ (include . "Loads")
+ (package . "DefinModule"))
+ imenu-create-index-function 'semantic-create-imenu-index
+ semantic-dependency-include-path semantic-default-scheme-path
+ imenu-create-index-function 'semantic-create-imenu-index
+ document-comment-start ";;"
+ document-comment-line-prefix ";;"
+ document-comment-end "\n"
+ )%
+
+%token DEFINE "define"
+%put DEFINE summary "Function: (define symbol expression)"
+%token DEFINE-MODULE "define-module"
+%put DEFINE-MODULE summary "Function: (define-module (name arg1 ...)) "
+%token LOAD "load"
+%put LOAD summary "Function: (load \"filename\")"
+
+scheme : semantic-list
+ (EXPAND $1 scheme-list 4)
+ ;
+
+scheme-list : open-paren "(" scheme-in-list
+ ( ,$2 )
+ ;
+
+scheme-in-list: DEFINE symbol expression
+ ( $2 variable nil $3 nil )
+ | DEFINE name-args opt-doc
+ ( (car ,$2) function (cdr ,$2) nil ,$3 )
+ | DEFINE-MODULE name-args
+ ( (nth (length $2) $2 ) provide nil)
+ | LOAD string
+ ( (file-name-nondirectory (read $2)) require (read $2) )
+ | symbol
+ ( $1 code )
+ ;
+
+name-args: semantic-list
+ (EXPAND $1 name-arg-expand)
+ ;
+
+name-arg-expand : open-paren name-arg-expand
+ ( ,$2 )
+ | symbol name-arg-expand
+ ( ,(cons $1 ,$2) )
+ | EMPTY
+ ( )
+ ;
+
+opt-doc : string
+ | EMPTY
+ ;
+
+expression : symbol
+ | semantic-list
+ | string
+ ;
\ No newline at end of file
Index: xemacs-packages/semantic/semantic-bnf.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/semantic/semantic-bnf.el,v
retrieving revision 1.4
diff -u -r1.4 semantic-bnf.el
--- xemacs-packages/semantic/semantic-bnf.el 2001/02/20 03:23:43 1.4
+++ xemacs-packages/semantic/semantic-bnf.el 2001/08/15 05:28:17
@@ -1,11 +1,11 @@
;;; semantic-bnf.el --- Semantic details for some languages
-;;; Copyright (C) 1999, 2000 Eric M. Ludlam
+;;; Copyright (C) 1999, 2000, 2001 Eric M. Ludlam
;; Author: Eric M. Ludlam <zappo(a)gnu.org>
;; Version: 0.2
;; Keywords: parse
-;; X-RCS: $Id: semantic-bnf.el,v 1.4 2001/02/20 03:23:43 youngs Exp $
+;; X-RCS: $Id: semantic-bnf.el,v 1.40 2001/05/07 11:32:26 zappo Exp $
;; Semantic-bnf is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
@@ -34,6 +34,9 @@
;;
(require 'semantic)
+(eval-when-compile
+ (require 'speedbar)
+ (require 'senator))
;;; Code:
(defvar semantic-setup-code-delimiters '("^\\s-*;; Code generated from" .
@@ -81,42 +84,95 @@
;; When loading lisp rules, use READ to convert
;; into a list we can pretty print later.
,(semantic-lambda
- (let ((r (buffer-substring
+ (let ((r (buffer-substring-no-properties
(car (car vals))
(cdr (car vals)))))
(list (symbol-name (car (read r))) 'setting r))))
-; (symbol "token" symbol symbol
-; ,(semantic-lambda
-; (list (nth 1 vals) 'token (nth 2 vals))))
- (symbol "start" symbol
- ,(semantic-lambda
- (list (nth 1 vals) 'start)))
- (symbol "token" symbol string
- ,(semantic-lambda
- (list (nth 1 vals) 'keyword "symbol" (nth 2 vals))))
- (symbol "token" symbol symbol string
- ,(semantic-lambda
- (list (nth 1 vals) 'token
- (nth 2 vals) (nth 3 vals))))
- (symbol "outputfile" symbol punctuation "." symbol
"\\bel\\b"
- ,(semantic-lambda
- (list (concat (nth 1 vals) ".el") 'outputfile)))
- (symbol "parsetable" symbol
- ,(semantic-lambda
- (list (nth 1 vals) 'parsetable)))
- (symbol "keywordtable" symbol
- ,(semantic-lambda
- (list (nth 1 vals) 'keywordtable)))
- (symbol "languagemode" symbol
- ,(semantic-lambda
- (list (nth 1 vals) 'languagemode)))
- (symbol "setupfunction" symbol
- ,(semantic-lambda
- (list (nth 1 vals) 'setupfunction)))
- (symbol "quotemode" symbol
+ ; (symbol "token" symbol symbol
+ ; ,(semantic-lambda
+ ; (list (nth 1 vals) 'token (nth 2 vals))))
+ (START symbol
+ ,(semantic-lambda
+ (list (nth 1 vals) 'start)))
+ (SCOPESTART symbol
+ ,(semantic-lambda
+ (list (nth 1 vals) 'scopestart)))
+ (TOKEN symbol string
+ ,(semantic-lambda
+ (list (nth 1 vals) 'keyword "symbol" (nth 2 vals))))
+ (TOKEN symbol symbol string
+ ,(semantic-lambda
+ (list (nth 1 vals) 'token
+ (nth 2 vals) (nth 3 vals))))
+ (PUT symbol symbol put-value
+ ,(semantic-lambda
+ (list (nth 1 vals) 'put
+ (list (nth 1 vals))
+ (list (apply 'list (nth 2 vals) 'property (nth 3 vals))))))
+ (PUT symbol semantic-list
+ ,(semantic-lambda
+ (list (nth 1 vals) 'put
+ (list (nth 1 vals))
+ (semantic-bovinate-from-nonterminal-full
+ (car (nth 2 vals)) (cdr (nth 2 vals))
+ `put-value-list))))
+ (PUT semantic-list symbol put-value
+ ,(semantic-lambda
+ (let ((names (semantic-bovinate-from-nonterminal-full
+ (car (nth 1 vals)) (cdr (nth 1 vals))
+ `put-name-list)))
+ (list (car (car names)) 'put names
+ (list (apply 'list (nth 2 vals) 'property (nth 3 vals)))))))
+ (PUT semantic-list semantic-list
+ ,(semantic-lambda
+ (let ((names (semantic-bovinate-from-nonterminal-full
+ (car (nth 1 vals)) (cdr (nth 1 vals))
+ `put-name-list)))
+ (list (car (car names)) 'put names
+ (semantic-bovinate-from-nonterminal-full
+ (car (nth 2 vals)) (cdr (nth 2 vals))
+ `put-value-list)))))
+ (OUTPUTFILE symbol punctuation "." symbol "\\bel\\b"
+ ,(semantic-lambda
+ (list (concat (nth 1 vals) ".el") 'outputfile)))
+ (PARSETABLE symbol
+ ,(semantic-lambda
+ (list (nth 1 vals) 'parsetable)))
+ (KEYWORDTABLE symbol
+ ,(semantic-lambda
+ (list (nth 1 vals) 'keywordtable)))
+ (LANGUAGEMODE symbol
+ ,(semantic-lambda
+ (list (nth 1 vals) 'languagemode)))
+ (LANGUAGEMODE semantic-list
+ ,(semantic-lambda
+ (let ((r (buffer-substring-no-properties
+ (car (nth 1 vals))
+ (cdr (nth 1 vals)))))
+ (list r 'languagemode))))
+ (SETUPFUNCTION symbol
+ ,(semantic-lambda
+ (list (nth 1 vals) 'setupfunction)))
+ (QUOTEMODE symbol
+ ,(semantic-lambda
+ (list (nth 1 vals) 'quotemode)))
+ )
+ (put-name-list
+ (open-paren ,(semantic-lambda (list nil)))
+ (close-paren ,(semantic-lambda (list nil)))
+ (symbol ,(semantic-lambda (list (nth 0 vals) 'name))))
+ (put-value-list
+ (open-paren ,(semantic-lambda (list nil)))
+ (close-paren ,(semantic-lambda (list nil)))
+ (symbol put-value
,(semantic-lambda
- (list (nth 1 vals) 'quotemode)))
+ (apply 'list (nth 0 vals) 'property (nth 1 vals))))
)
+ (put-value
+ (symbol ,(semantic-lambda (list (nth 0 vals))))
+ (string ,(semantic-lambda (list (nth 0 vals))))
+ (semantic-list
+ ,(semantic-lambda (list (semantic-flex-text (cons 1 (nth 0 vals)))))))
(rule-list
(match-list lambda-fn rule-or-list
,(semantic-lambda
@@ -146,6 +202,27 @@
)
"Bovine table used to convert a BNF language file into a bovine table.")
+(defvar semantic-bnf-keyword-table
+ (semantic-flex-make-keyword-table
+ `( ("start" . START)
+ ("scopestart" . SCOPESTART)
+ ("token" . TOKEN)
+ ("put" . PUT)
+ ("outputfile" . OUTPUTFILE)
+ ("parsetable" . PARSETABLE)
+ ("keywordtable" . KEYWORDTABLE)
+ ("languagemode" . LANGUAGEMODE)
+ ("setupfunction" . SETUPFUNCTION)
+ ("quotemode" . QUOTEMODE)
+ )
+ `(("put" summary "%put <keyword> <lisp expression>")
+ ("token" summary "%token <keyword> [syntax]
\"matchtext\"")
+ ("start" summary "%start <starting rule name>")
+ ("scopestart" summary "%scopestart <starting scope (code) rule
name>")
+ ("languagemode" summary "%languagemode [ lispsymbol | ( lispsym
lispsym ...) ]")
+ ))
+ "Keyword table used for Semantic BNF files.")
+
;;; Conversion routines
;;
@@ -153,23 +230,41 @@
"Insert a token expand function based on LST."
(let ((argv (1- (string-to-int (substring (symbol-name (car (cdr lst)))
1)))))
- (insert "\n")
+ (insert "\n ")
(insert "(semantic-bovinate-from-nonterminal "
"(car (nth " (int-to-string argv) " vals)) "
"(cdr (nth " (int-to-string argv) " vals)) "
"'" (symbol-name (car (cdr (cdr lst))))
- ")\n")))
+ ")\n ")))
(defun semantic-bnf-EXPANDFULL (lst)
"Insert a token full expand function based on LST."
(let ((argv (1- (string-to-int (substring (symbol-name (car (cdr lst)))
1)))))
- (insert "\n")
+ (insert "\n ")
(insert "(semantic-bovinate-from-nonterminal-full "
"(car (nth " (int-to-string argv) " vals)) "
"(cdr (nth " (int-to-string argv) " vals)) "
"'" (symbol-name (car (cdr (cdr lst))))
- ")\n")))
+ ")\n ")))
+
+(defun semantic-bnf-ASSOC (lst quotemode)
+ "Handle an ASSOC list based on LST.
+QUOTEMODE is the current mode of quotation."
+ (let ((lst (cdr lst))
+ l)
+ (while lst
+ ;; quote the key
+ (setq l (cons (list 'quote (car lst)) l)
+ lst (cdr lst))
+ ;; push the value
+ (if lst
+ (setq l (cons (car lst) l)
+ lst (cdr lst))))
+ ;; substitute ASSOC by call to semantic-bovinate-make-assoc-list
+ ;; and do BNF lambda substitution on the whole expression
+ (semantic-bnf-lambda-substitute
+ (cons 'semantic-bovinate-make-assoc-list (nreverse l)) quotemode t)))
(defun semantic-bnf-lambda-substitute (lst quotemode &optional inplace)
"Insert LST substituting based on rules for the BNF converter.
@@ -185,15 +280,21 @@
(semantic-bnf-lambda-substitute (car lst) quotemode nil)
(insert ")")
(setq lst nil inplace nil))
- (insert "(list")
- (setq inplace t))
- )
- (if inplace (insert " (")))
+ (if (and (= (length lst) 1) (symbolp (car lst)))
+ (progn
+ (insert " '" (symbol-name (car lst)))
+ (setq lst nil inplace nil))
+ (insert "(list")
+ (setq inplace t))
+ )))
(cond ((eq (car lst) 'EXPAND)
(semantic-bnf-EXPAND lst))
((eq (car lst) 'EXPANDFULL)
(semantic-bnf-EXPANDFULL lst))
+ ((eq (car lst) 'ASSOC)
+ (semantic-bnf-ASSOC lst quotemode))
(t
+ (if inplace (insert " ("))
(let ((inlist nil))
(while lst
(cond ((eq (car lst) nil)
@@ -206,11 +307,11 @@
(if (and (not inlist) (not inplace))
(progn (insert " (list")
(setq inlist t)))
- (if (and inplace (not fn) (not (eq (car (car lst)) 'EXPAND)))
- (insert " (append"))
- (semantic-bnf-lambda-substitute (car lst) quotemode (and fn (not (eq fn
'quote))))
- (if (and inplace (not fn) (not (eq (car (car lst)) 'EXPAND)))
- (insert ")"))
+; (if (and inplace (not fn) (not (eq (car (car lst)) 'EXPAND)))
+; (insert " (append"))
+ (semantic-bnf-lambda-substitute (car lst) quotemode t);(and fn (not (eq fn
'quote))))
+; (if (and inplace (not fn) (not (eq (car (car lst)) 'EXPAND)))
+; (insert ")"))
))
((symbolp (car lst))
(let ((n (symbol-name (car lst))) ;the name
@@ -247,18 +348,22 @@
(setq inlist nil))))
(insert " (nth " (int-to-string val) " vals)")
(if (and (not x) (not inplace)) (setq inlist t)))
- (if (and (not inlist) (not inplace))
+ (if (and (not inlist) (not inplace) )
(progn (insert " (list")
(setq inlist t)))
- (insert " " (if inplace "" "'") n)))))
+ (insert " "
+ (if (or inplace (eq (car lst) t)) "" "'")
+ n; " "
+ )))))
(t
(if (and (not inlist) (not inplace))
(progn (insert " (list")
(setq inlist t)))
(insert (format " %S" (car lst)))))
(setq lst (cdr lst)))
- (if inlist (insert ")")))))
- (if inplace (insert ")")))
+ (if inlist (insert ")")))
+ (if inplace (insert ")"))))
+ )
(defun semantic-bnf-lambda-convert (semliststr vals quotemode)
"Convert SEMLISTSTR into Lisp code based on VALS.
@@ -270,9 +375,9 @@
;; We converted the lambda string into a list. Now write it
;; out as the bovine lambda expression, and do macro-like
;; conversion upon it.
- (insert "\n")
+ (insert "\n ")
(cond ((eq (car slsr) 'EXPAND)
- (insert ",(lambda (vals start end)\n")
+ (insert ",(lambda (vals start end)\n ")
(semantic-bnf-EXPAND slsr)
)
((and (listp (car slsr))
@@ -281,14 +386,15 @@
;; Use a simpler expander
)
(t
- (insert ",(semantic-lambda\n")
+ (insert " ,(semantic-lambda\n ")
(semantic-bnf-lambda-substitute slsr quotemode)
))
(insert ")"))))
-(defun semantic-bnf-to-bovine (file tokstream &optional start)
- "Insert the BNF file FILE into the current buffer as a bovine table.
-Inserts the token stream TOKSTREAM, and uses START is the starting token."
+(defun semantic-bnf-to-bovine (tokstream &optional start scopestart)
+ "Insert the BNF TOKSTREAM into the current buffer as a bovine table.
+Optional argument START is the token to start with.
+Optional argument SCOPESTART is the token to start subscopes with."
(interactive "FBNF file: ")
(let ((tl (float (length tokstream)))
(tokens (semantic-find-nonterminal-by-token 'token tokstream))
@@ -305,10 +411,13 @@
(matches (car (cdr (cdr (cdr rule))))))
(when (eq (car (cdr rule)) 'rule)
(insert "(")
- (if (and start (string= start (car rule)))
- (insert "bovine-toplevel")
- (insert (car rule)))
- (insert "\n")
+ (cond ((and start (string= start (car rule)))
+ (insert "bovine-toplevel"))
+ ((and scopestart (string= scopestart (car rule)))
+ (insert "bovine-inner-scope"))
+ (t
+ (insert (car rule))))
+ (insert "\n ")
(while matches
(let* ((mla (car matches))
(lamb (car mla))
@@ -328,13 +437,13 @@
(insert " " (car ml))))
(setq ml (cdr ml))))
(semantic-bnf-lambda-convert lamb (car (cdr mla)) quotemode)
- (insert ")\n"))
+ (insert ")\n "))
(setq matches (cdr matches)))
- (insert ") ; end " (car rule) "\n")))
+ (insert ") ; end " (car rule) "\n ")))
(setq tokstream (cdr tokstream))
(working-status (* 100.0 (- 1.0 (/ (float (length tokstream)) tl)))))
(working-status t))
- (insert ")\n")
+ (insert ")\n ")
))
;;; Output File hacks
@@ -421,8 +530,11 @@
parse table variable."
(let ((mode (semantic-find-nonterminal-by-token 'languagemode tokstream)))
(if mode
- (intern (semantic-token-name (car mode)))
- (semantic-bnf-find-languagemode-old))))
+ (let ((m (read (semantic-token-name (car mode)))))
+ (if (listp m)
+ m
+ (list m)))
+ (list (semantic-bnf-find-languagemode-old)))))
(defun semantic-bnf-find-setup-code (tokstream sourcefile)
"Find the setup code based on TOKSTREAM.
@@ -462,13 +574,22 @@
(let ((m (string-match ";"
(car semantic-setup-code-delimiters))))
(insert (substring (car semantic-setup-code-delimiters) m))
- (insert " " sourcefile "\n")
+ (insert " " sourcefile "\n ")
(save-excursion;; save in the middle
- (insert "\n" (substring (cdr semantic-setup-code-delimiters)
+ (insert "\n " (substring (cdr semantic-setup-code-delimiters)
m))
- (insert " " sourcefile "\n"))
+ (insert " " sourcefile "\n "))
t)
))))))
+
+(defvar semantic-bnf-indent-table t
+ "Non nil means to indent the large table during creation.")
+
+(defun semantic-bnf-generate-and-load-no-indent ()
+ "Call `semantic-bnf-genrate-and-load' without indenting the table."
+ (interactive)
+ (let ((semantic-bnf-indent-table nil))
+ (semantic-bnf-generate-and-load)))
(defun semantic-bnf-generate-and-load ()
"Take the current BNF, auto-generate it into a table, and load it."
@@ -484,6 +605,8 @@
(keydest (semantic-bnf-find-keyword-destination tok))
(mode (semantic-bnf-find-languagemode tok))
(start (semantic-find-nonterminal-by-token 'start tok))
+ (scopestart (semantic-find-nonterminal-by-token 'scopestart tok))
+ (setup-fn (semantic-find-nonterminal-by-token 'setupfunction tok))
)
(if (not dest)
(error "You must specify a destination table in your BNF file"))
@@ -497,14 +620,37 @@
(delete-region (point) (save-excursion (forward-sexp 1) (point))))
(delete-blank-lines)
(let ((key (semantic-find-nonterminal-by-token 'keyword tok))
+ keys
+ (put (semantic-find-nonterminal-by-token 'put tok))
(start (point)))
(if (not key)
- (insert "nil\n")
+ (insert "nil\n ")
(insert "(semantic-flex-make-keyword-table \n `(")
+ ;; Get all the keys
(while key
- (insert " (" (nth 3 (car key)) " . " (car (car key))
")\n")
+ (insert " (" (nth 3 (car key)) " . " (car (car key)) ")\n
")
(setq key (cdr key)))
- (insert "))\n"))
+ (insert ")\n '(\n ")
+ ;; Now get all properties
+ (while put
+ (setq keys (nth 2 (car put)))
+ (while keys
+ (setq key (semantic-find-nonterminal-by-token 'keyword tok))
+ (let ((a (assoc (if (listp (car keys))
+ (car (car keys))
+ (car keys))
+ key)))
+ (if (not a) (error "Token %s not found" (car keys)))
+ (let ((pairs (nth 3 (car put))))
+ (while pairs
+ (insert " ("
+ (nth 3 a) " "
+ (car (car pairs)) " "
+ (car (cdr (cdr (car pairs)))) ")\n ")
+ (setq pairs (cdr pairs)))))
+ (setq keys (cdr keys)))
+ (setq put (cdr put)))
+ (insert "))\n "))
(save-excursion
(indent-region start (point) nil)))
(eval-defun nil))
@@ -519,16 +665,23 @@
(when var
;; The bovine table
(insert "(setq semantic-toplevel-bovine-table "
- (semantic-token-name (car var)) ")\n"))
+ (semantic-token-name (car var)) "\n ")
+ (insert "semantic-toplevel-bovine-table-source \""
+ fname "\")\n")
+ )
;; Keytable setup
(when key
(insert "(setq semantic-flex-keywords-obarray "
- (semantic-token-name (car key)) ")\n"))
+ (semantic-token-name (car key)) ")\n "))
+ ;; Is there more than one major mode?
+ (if (and (listp mode) (> (length mode) 1))
+ (insert "(setq semantic-equivalent-major-modes '"
+ (format "%S" mode) ")\n"))
;; Add in user specified settings
(let ((settings (semantic-find-nonterminal-by-token 'setting tok)))
(while settings
(insert (nth 2 (car settings)))
- (insert "\n")
+ (insert "\n ")
(setq settings (cdr settings))))
(point))
nil)
@@ -539,26 +692,117 @@
(if (looking-at "\\s-*\\(`?(\\|nil\\)")
(delete-region (point) (save-excursion (forward-sexp 1) (point))))
(delete-blank-lines)
- (semantic-bnf-to-bovine (buffer-file-name bb) tok
- (if start (semantic-token-name (car start))))
- (message "Indenting table....")
- (save-excursion
- (indent-region (progn (re-search-backward "(defvar")
- (goto-char (match-beginning 0))
- (point))
- (progn (forward-sexp 1) (point))
- nil))
+ (semantic-bnf-to-bovine
+ tok (if start (semantic-token-name (car start)))
+ (if scopestart (semantic-token-name (car scopestart))))
+ (if semantic-bnf-indent-table
+ (save-excursion
+ (message "Indenting table....")
+ (indent-region (progn (re-search-backward "(defvar")
+ (goto-char (match-beginning 0))
+ (point))
+ (progn (forward-sexp 1) (point))
+ nil)))
(eval-defun nil))
(message "Done.")
- (if mode
- (save-excursion
- (let ((bufs (buffer-list)))
- (while bufs
- (set-buffer (car bufs))
- (if (eq major-mode mode)
- (funcall mode))
- (setq bufs (cdr bufs))))))))
+ (when mode
+ (save-excursion
+ (let ((bufs (buffer-list)))
+ (while bufs
+ (set-buffer (car bufs))
+ (if (member major-mode mode)
+ (progn
+ (if setup-fn
+ (funcall (intern (semantic-token-name (car setup-fn))))
+ (funcall mode)))
+ )
+ (setq bufs (cdr bufs)))))
+ )))
+
+(defun semantic-bnf-generate-one-rule ()
+ "Generate code for one rule in a temporary buffer."
+ (interactive)
+ (semantic-bovinate-toplevel t)
+ (let ((r (semantic-current-nonterminal)))
+ (if (or (not r) (not (eq (semantic-token-token r) 'rule)))
+ (error "No rule to expand nearby"))
+ (pop-to-buffer "*Rule Expansion*" t)
+ (save-excursion
+ (set-buffer "*Rule Expansion*")
+ (erase-buffer)
+ (insert "Expanding rule [" (semantic-token-name r) "]\n\n")
+ (semantic-bnf-to-bovine (list r)))))
+;;; Debugging support
+;;
+;; Source level debugging if a BNF table requires a few simple functions.
+(defun semantic-bnf-skip-string-or-comment ()
+ "Return non-nil if point was moved after a string or comment."
+ (let ((state (parse-partial-sexp (save-excursion
+ (beginning-of-line) (point))
+ (point))))
+ (cond ((nth 3 state) ;; string
+ (re-search-backward "\\s\"")
+ (forward-sexp)
+ t)
+ ((nth 4 state) ;; comment
+ (forward-line)
+ t)
+ (t
+ nil))))
+
+(defun semantic-bnf-find-state-position (rule matchlistindex matchindex)
+ "Find the current debugger position in the current buffer.
+RULE is a symbol representing the rule name we are currently in.
+MATCHLISTINDEX is the index to the current match list being tested.
+MATCHINDEX is the index into the matchlist being tested."
+ (let* ((start (car (semantic-find-nonterminal-by-token 'start (current-buffer))))
+ (sn (symbol-name rule))
+ (findme (if (and start (eq rule 'bovine-toplevel))
+ (semantic-token-name start)
+ (symbol-name rule)))
+ (r (semantic-find-nonterminal-by-name
+ findme (semantic-find-nonterminal-by-token
+ 'rule (current-buffer)))))
+ (if (not r)
+ (error "Semantic debugger error: Cannot find rule %s" findme))
+ ;; Find the rule
+ (goto-char (semantic-token-start r))
+ ;; find the matchlist
+ (re-search-forward ":\\s-*")
+ (while (/= matchlistindex 0)
+ (re-search-forward "\\s-*|\\s-*")
+ ;; If point is in a comment or a string skip it
+ (or (semantic-bnf-skip-string-or-comment)
+ (setq matchlistindex (1- matchlistindex)))
+ )
+ ;; find the specific token we are matching
+ (while (/= matchindex 0)
+ (when (semantic-bnf-looking-at-%token-not-keyword)
+ (setq matchindex (1- matchindex)))
+ (forward-sexp 1)
+ (setq matchindex (1- matchindex))
+ )
+ (skip-chars-forward " \t\n")
+ ;; Leave the cursor here, and let them highlight if for us
+ (current-buffer)
+ ))
+
+(defun semantic-bnf-looking-at-%token-not-keyword ()
+ "Return non-nil if the token following the cursor is a %token.
+Some tokens are keywords. Make sure we know the difference."
+ (when (looking-at "\\s-*\\(\\(\\w\\|\\s_\\)+\\)")
+ (semantic-find-nonterminal-by-name
+ (match-string 1)
+ (semantic-find-nonterminal-by-token 'token (current-buffer)))))
+
+(defun semantic-bnf-find-source-on-load-path (sourcefile)
+ "Find the BNF file SOURCEFILE on the Emacs `load-path'.
+Once found, put it in a buffer, and return it."
+ (let ((sf (locate-library sourcefile)))
+ (if sf (find-file-noselect sf)))
+ )
+
;;; Semantic BNF mode
;;
;; Major mode for editing BNF files. More importantly, define a syntax
@@ -575,8 +819,6 @@
(modify-syntax-entry ?\; "." semantic-bnf-syntax-table)
(modify-syntax-entry ?\" "\"" semantic-bnf-syntax-table)
(modify-syntax-entry ?- "_" semantic-bnf-syntax-table)
- (modify-syntax-entry ?( "(" semantic-bnf-syntax-table)
- (modify-syntax-entry ?) ")(" semantic-bnf-syntax-table)
(modify-syntax-entry ?# "<" semantic-bnf-syntax-table)
(modify-syntax-entry ?\n ">" semantic-bnf-syntax-table)
'foo
@@ -586,10 +828,15 @@
"Hook run when starting BNF mode.")
(defvar semantic-bnf-mode-keywords
- '(("^\\(\\w+\\)\\s-*:" 1 font-lock-function-name-face)
+ `((";\\s-*[^#\n ].*$" 0 font-lock-comment-face)
+ ("^\\(\\w+\\)\\s-*:" 1 font-lock-function-name-face)
("\\<\\(EMPTY\\|symbol\\|punctuation\\|string\\|semantic-list\
\\|\\(open\\|close\\)-paren\\|comment\\)\\>"
1 font-lock-keyword-face)
+ ("(\\s-*\\(ASSOC\\|EXPAND\\(FULL\\)?\\)\\>"
+ 1 ,(if (featurep 'xemacs)
+ 'font-lock-preprocessor-face
+ 'font-lock-builtin-face))
("\\$[0-9]+" 0 font-lock-variable-name-face)
("%" 0 font-lock-reference-face)
("%\\(\\w+\\)" 1 font-lock-type-face)
@@ -606,10 +853,20 @@
(define-key semantic-bnf-map "|" 'semantic-bnf-electric-punctuation)
(define-key semantic-bnf-map ";" 'semantic-bnf-electric-punctuation)
(define-key semantic-bnf-map "#" 'semantic-bnf-electric-punctuation)
- (define-key semantic-bnf-map "\C-c\C-c"
'semantic-bnf-generate-and-load)
+ (define-key semantic-bnf-map "%" 'semantic-bnf-electric-punctuation)
+ (define-key semantic-bnf-map "(" 'semantic-bnf-electric-punctuation)
+ (define-key semantic-bnf-map ")" 'semantic-bnf-electric-punctuation)
+ (define-key semantic-bnf-map "\C-c\C-c"
'semantic-bnf-generate-and-load-no-indent)
+ (define-key semantic-bnf-map "\C-cc" 'semantic-bnf-generate-and-load)
+ (define-key semantic-bnf-map "\C-cr" 'semantic-bnf-generate-one-rule)
+ (define-key semantic-bnf-map "\M-\t" 'semantic-bnf-complete)
)
-(speedbar-add-supported-extension ".bnf")
+(if (featurep 'speedbar)
+ (speedbar-add-supported-extension ".bnf")
+ (add-hook 'speedbar-load-hook
+ (lambda ()
+ (speedbar-add-supported-extension ".bnf"))))
(defalias 'bnf-mode 'semantic-bnf-mode)
(defun semantic-bnf-mode ()
@@ -624,8 +881,8 @@
(setq comment-start-skip "# *")
(set-syntax-table semantic-bnf-syntax-table)
(use-local-map semantic-bnf-map)
- (make-local-variable 'semantic-toplevel-bovine-table)
(setq semantic-toplevel-bovine-table semantic-bovine-bnf-table)
+ (setq semantic-flex-keywords-obarray semantic-bnf-keyword-table)
(make-local-variable 'indent-line-function)
(setq indent-line-function 'semantic-bnf-indent)
(make-local-variable 'font-lock-defaults)
@@ -636,13 +893,125 @@
;; simplifying our keywords significantly
((?_ . "w") (?- . "w"))))
(setq semantic-symbol->name-assoc-list
- '( (keyword . "Keywords")
- (token . "Tokens")
- (rule . "Rules")
+ '( (keyword . "Keyword")
+ (token . "Token")
+ (rule . "Rule")
)
imenu-create-index-function 'semantic-create-imenu-index)
+ (semantic-install-function-overrides
+ '( (abbreviate-nonterminal . semantic-bnf-abbreviate-nonterminal)
+ (summarize-nonterminal . semantic-bnf-summarize-nonterminal)
+ (eldoc-current-symbol-info . semantic-bnf-ecsi)
+ (nonterminal-children . semantic-bnf-nonterminal-children)
+ )
+ t)
+ (make-local-variable 'semantic-face-alist)
+ (setq semantic-face-alist
+ (append semantic-face-alist
+ '( (rule . font-lock-function-name-face)
+ (keyword . font-lock-keyword-face)
+ (token . font-lock-variable-name-face) )
+ ))
+
(run-hooks 'semantic-bnf-mode-hook))
+(defun semantic-bnf-nonterminal-children (token &optional positiononly)
+ "Return the children belonging to TOKEN.
+These children may or not be full tokens for bnf files, but will have
+overlays associated with them.
+Optional argument POSITIONONLY is passed to the default function but is not
+used locally."
+ (if (eq (semantic-token-token token) 'put)
+ (let ((a (nth 2 token))
+ (b (nth 3 token)))
+ (if (not (semantic-token-with-position-p (car a)))
+ (setq a nil))
+ (if (not (semantic-token-with-position-p (car b)))
+ (setq b nil))
+ (append a b)
+ )
+ (semantic-nonterminal-children-default token))
+ )
+
+(defun semantic-bnf-abbreviate-nonterminal (token &optional parent color)
+ "Return a string abbreviation of TOKEN.
+Optional PARENT is not used.
+Optional COLOR is used to flag if color is added to the text."
+ (let ((tok (semantic-token-token token))
+ (name (semantic-name-nonterminal token parent color)))
+ (cond
+ ((eq tok 'rule) (concat name ":"))
+ ((eq tok 'setting) "%settings%")
+ ((or (eq tok 'token) (eq tok 'keyword)) name)
+ (t (concat "%" (symbol-name tok) " " name)))))
+
+(defun semantic-bnf-summarize-nonterminal (token &optional parent color)
+ "Return a string summarizing TOKEN.
+Optional PARENT is not used.
+Optional argument COLOR determines if color is added to the text."
+ (let ((tok (semantic-token-token token))
+ (name (semantic-name-nonterminal token parent color))
+ (label nil)
+ (desc nil))
+ (cond
+ ((eq tok 'rule)
+ (setq label "Rule: "
+ desc (concat " with "
+ (int-to-string (length (nth 3 token)))
+ " match lists.")))
+ ((eq tok 'keyword)
+ (setq label "Keyword: "
+ desc (concat " " (nth 3 token))))
+ ((eq tok 'token)
+ (setq label "Token: "
+ desc (concat " " (nth 2 token) " " (nth 3 token))))
+ (t (setq desc
+ (semantic-bnf-abbreviate-nonterminal token parent color))))
+ (if (and color label)
+ (setq label (semantic-colorize-text label 'label)))
+ (if (and color label desc)
+ (setq desc (semantic-colorize-text desc 'comment)))
+ (if label
+ (concat label name desc)
+ ;; Just a description is the abbreviated version
+ desc))
+ )
+
+(defvar semantic-bnf-syntax-help
+ `( ("symbol" . "Syntax: A symbol of alpha numeric and symbol
characters")
+ ("punctuation" . "Syntax: Punctuation character.")
+ ("semantic-list" . "Syntax: A list delimited by any valid list
characters")
+ ("open-paren" . "Syntax: Open Parenthisis character")
+ ("close-paren" . "Syntax: Close Parenthisis character")
+ ("string" . "Syntax: String character delemeted text")
+ ("comment" . "Syntax: Comment character delimited text")
+ ("EMPTY" . "Syntax: Match empty text")
+ ("ASSOC" . "Lambda Key: (ASSOC key1 value1 key2 value2 ...)")
+ ("EXPAND" . "Lambda Key: (EXPAND <list id>
<rule>)")
+ ("EXPANDFULL" . "Lambda Key: (EXPANDFULL <list id>
<rule>)")
+ ("$1" . "Match Value: Value from match list in slot 1")
+ ("$2" . "Match Value: Value from match list in slot 2")
+ ("$3" . "Match Value: Value from match list in slot 3")
+ ("$4" . "Match Value: Value from match list in slot 4")
+ ("$5" . "Match Value: Value from match list in slot 5")
+ ("$6" . "Match Value: Value from match list in slot 6")
+ ("$7" . "Match Value: Value from match list in slot 7")
+ ("$8" . "Match Value: Value from match list in slot 8")
+ ("$9" . "Match Value: Value from match list in slot 9")
+ ("nil" . "Value: Empty List, False, nothing.")
+ )
+ "Association of syntax elements, and the corresponding help.")
+
+(defun semantic-bnf-ecsi ()
+ "Return an info string about the current context."
+ (let* ((sym (semantic-ctxt-current-symbol))
+ (summ (assoc (car sym) semantic-bnf-syntax-help))n
+ (found (cdr summ)))
+ (if found
+ found
+ (senator-eldoc-print-current-symbol-info-default)
+ )))
+
(defun semantic-bnf-electric-punctuation ()
"Insert and reindent for the symbol just typed in."
(interactive)
@@ -660,32 +1029,100 @@
t)
(error nil)))
+(defun semantic-bnf-in-lambda-continuation-p (&optional point)
+ "Non-nil if POINT is in a settings block."
+ (condition-case nil
+ (save-excursion
+ (if point (goto-char point) (setq point (point)))
+ (beginning-of-line)
+ (condition-case nil
+ (while t
+ (up-list -1))
+ (error nil))
+ (end-of-line)
+ (< (point) point)
+ )
+ (error nil)))
+
+(defun semantic-bnf-previous-colon-indentation ()
+ "Calculation the indentation of the last colon oporator.
+Returns the previous colon's column."
+ (save-excursion
+ (let ((p (point))
+ (ci (progn
+ (if (re-search-backward "^\\s-*\\(\\w\\|\\s_\\)+\\s-*:" nil t)
+ (progn
+ (beginning-of-line)
+ (- (match-end 0) 1 (point)))
+ 0)))
+ (cp (point))
+ (sc nil))
+ (goto-char p)
+ (while (and (re-search-backward "^\\s-*;\\s-*$" nil t)
+ (semantic-bnf-in-lambda-continuation-p)))
+ (if (looking-at "\\s-*;")
+ (setq sc t))
+ (if sc
+ (if (< (point) cp)
+ ci
+ 0)
+ ci))))
+
+(defun semantic-bnf-do-lisp-indent (&optional point)
+ "Run the stander Emacs Lisp indenter on a line of code.
+Optional argument POINT is the position on the line to indent."
+ (condition-case nil
+ (save-excursion
+ (if point (goto-char point) (setq point (point)))
+ (up-list -1)
+ (condition-case nil
+ (while t
+ (up-list -1))
+ (error nil))
+ (save-restriction
+ (beginning-of-line)
+ (narrow-to-region (point) point)
+ (goto-char point)
+ (with-syntax-table emacs-lisp-mode-syntax-table
+ (lisp-indent-line))))
+ (error nil)))
+
(defun semantic-bnf-indent ()
"Indent the current line according to BNF rules."
(interactive)
(if (semantic-bnf-in-settings-p)
- (lisp-indent-line)
- (save-excursion
- (beginning-of-line)
- (let ((indent (current-indentation)))
- (if (looking-at "\\s-*\\(\\w\\|\\s_\\)+\\s-*:")
- (delete-horizontal-space)
- (save-excursion
- (forward-line -1)
- (if (looking-at "\\s-*\\(\\w\\|\\s_\\)+\\s-*:")
- (setq indent (- (match-end 0) (point) 1))
- (if (looking-at "\\s-*;")
- (setq indent 0)
- (if (looking-at "\\s-*[|#]")
- (setq indent (current-indentation))
- (setq indent (- (current-indentation) 2))))))
- (if (not (looking-at "\\s-*[|;#]"))
- (setq indent (+ 2 indent)))
- (if (= (current-indentation) indent)
- nil
- (delete-horizontal-space)
- (indent-to indent))))))
+ (semantic-bnf-do-lisp-indent)
+ (if (semantic-bnf-in-lambda-continuation-p)
+ (semantic-bnf-do-lisp-indent)
+ (save-excursion
+ (beginning-of-line)
+ (let ((indent (semantic-bnf-previous-colon-indentation)))
+ (cond
+ ((or (looking-at "\\s-*\\(\\w\\|\\s_\\)+\\s-*:")
+ (looking-at "\\s-*%"))
+ (delete-horizontal-space))
+ (t
+ (save-excursion
+ (if (and (not (looking-at "\\s-*[|;#]"))
+ (/= indent 0))
+ (setq indent (+ 2 indent))))
+ (if (= (current-indentation) indent)
+ nil
+ (delete-horizontal-space)
+ (indent-to indent))))))))
(if (bolp) (if (looking-at "\\s-+") (end-of-line))))
+
+
+(defun semantic-bnf-complete ()
+ "Complete the symbol under point from various sources."
+ (interactive)
+ (if (or (semantic-bnf-in-settings-p)
+ (semantic-bnf-in-lambda-continuation-p))
+ ;; In a lisp part... do lisp completion
+ (lisp-complete-symbol)
+ ;; In BNF part, to BNF completion.
+ (require 'senator)
+ (senator-complete-symbol)))
(add-to-list 'auto-mode-alist '("\\.bnf$" . semantic-bnf-mode))
Index: xemacs-packages/semantic/semantic-c.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/semantic/semantic-c.el,v
retrieving revision 1.5
diff -u -r1.5 semantic-c.el
--- xemacs-packages/semantic/semantic-c.el 2001/06/01 03:18:26 1.5
+++ xemacs-packages/semantic/semantic-c.el 2001/08/15 05:28:17
@@ -1,13 +1,13 @@
;;; semantic-c.el --- Semantic details for C
-;;; Copyright (C) 1999, 2000 Eric M. Ludlam
+;;; Copyright (C) 1999, 2000, 2001 Eric M. Ludlam
;; Author: Eric M. Ludlam <zappo(a)gnu.org>
-;; X-RCS: $Id: semantic-c.el,v 1.5 2001/06/01 03:18:26 youngs Exp $
+;; X-RCS: $Id: semantic-c.el,v 1.31 2001/07/13 16:04:35 zappo Exp $
;; This file is not part of GNU Emacs.
-;; Semantic-ex is free software; you can redistribute it and/or modify
+;; This is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
@@ -34,255 +34,442 @@
(require 'semantic)
(require 'backquote)
+(eval-when-compile
+ (require 'semantic-ctxt)
+ (require 'document))
+
;;; Code:
(defvar semantic-toplevel-c-bovine-table
- `((bovine-toplevel
- ( include)
- ( macro)
- ( type)
- ( function)
- ( variable)
- ( prototype)
- ( define)
- ) ; end declaration
- (include
- ( punctuation "\\b#\\b" INCLUDE punctuation "<" filename
punctuation ">"
- ,(semantic-lambda
- (nth 3 vals) (list 'include 't nil)))
- ( punctuation "\\b#\\b" INCLUDE string
- ,(semantic-lambda
- (list ( read (nth 2 vals)) 'include nil nil)))
- ) ; end include
- (filename
- ( symbol punctuation "\\b\\.\\b" symbol
- ,(semantic-lambda
- (list ( concat (nth 0 vals) (nth 1 vals) (nth 2 vals)))))
- ( symbol punctuation "/" filename
- ,(semantic-lambda
- (list ( concat (nth 0 vals) (nth 1 vals) ( car (nth 2 vals))))))
- ) ; end filename
- (structparts
- ( semantic-list
- ,(semantic-lambda
-
- (semantic-bovinate-from-nonterminal-full (car (nth 0 vals)) (cdr (nth 0 vals))
'structsubparts)
- ))
- ) ; end structparts
- (structsubparts
- ( variable)
- ( define)
- ) ; end structsubparts
- (enumparts
- ( semantic-list
- ,(semantic-lambda
-
- (semantic-bovinate-from-nonterminal-full (car (nth 0 vals)) (cdr (nth 0 vals))
'enumsubparts)
- ))
- ) ; end enumparts
- (enumsubparts
- ( symbol opt-assign
- ,(semantic-lambda
- (list (nth 0 vals))))
- ) ; end enumsubparts
- (opt-name
- ( symbol)
- (
- ,(semantic-lambda
- (list nil)))
- ) ; end opt-name
- (typesimple
- ( STRUCT opt-name structparts
- ,(semantic-lambda
- (nth 1 vals) (list 'type (nth 0 vals) (nth 2 vals) nil nil nil)))
- ( UNION opt-name structparts
- ,(semantic-lambda
- (nth 1 vals) (list 'type (nth 0 vals) (nth 2 vals) nil nil nil)))
- ( ENUM opt-name enumparts
- ,(semantic-lambda
- (nth 1 vals) (list 'type (nth 0 vals) (nth 2 vals) nil nil nil)))
- ( TYPEDEF typeform symbol
- ,(semantic-lambda
- (list (nth 2 vals) 'type (nth 0 vals) nil (nth 1 vals) nil nil)))
- ) ; end typesimple
- (type
- ( typesimple punctuation "\\b;\\b"
- ,(semantic-lambda
- (nth 0 vals)))
- ) ; end type
- (opt-stars
- ( punctuation "\\b\\*\\b" opt-stars
- ,(semantic-lambda
- (list ( 1+ ( car (nth 1 vals))))))
- (
- ,(semantic-lambda
- (list 0)))
- ) ; end opt-stars
- (declmods
- ( symbol
"\\(_+\\)?\\(extern\\|static\\|const\\|volatile\\|signed\\|unsigned\\)"
declmods
- ,(semantic-lambda
- ( cons (nth 0 vals) (nth 1 vals))))
- ( symbol
"\\(_+\\)?\\(extern\\|static\\|const\\|volatile\\|signed\\|unsigned\\)"
- ,(semantic-lambda
- (list (nth 0 vals))))
- (
- ,(semantic-lambda
- ))
- ) ; end declmods
- (typeform
- ( typeformbase opt-stars
- ,(semantic-lambda
- (nth 0 vals)))
- ) ; end typeform
- (typeformbase
- ( typesimple
- ,(semantic-lambda
- (nth 0 vals)))
- ( STRUCT symbol
- ,(semantic-lambda
- (list (nth 1 vals) 'type (nth 0 vals))))
- ( UNION symbol
- ,(semantic-lambda
- (list (nth 1 vals) 'type (nth 0 vals))))
- ( ENUM symbol
- ,(semantic-lambda
- (list (nth 1 vals) 'type (nth 0 vals))))
- ( symbol
- ,(semantic-lambda
- (list (nth 0 vals))))
- ) ; end typeformbase
- (opt-bits
- ( punctuation "\\b:\\b" symbol
- ,(semantic-lambda
- (list (nth 1 vals))))
- (
- ,(semantic-lambda
- (list nil)))
- ) ; end opt-bits
- (opt-array
- ( semantic-list "\\[.*\\]$" opt-array
- ,(semantic-lambda
- (list ( cons 1 ( car (nth 1 vals))))))
- (
- ,(semantic-lambda
- (list nil)))
- ) ; end opt-array
- (opt-assign
- ( punctuation "\\b=\\b" expression
- ,(semantic-lambda
- (list (nth 1 vals))))
- (
- ,(semantic-lambda
- (list nil)))
- ) ; end opt-assign
- (macro
- ( punctuation "\\b#\\b" DEFINE symbol opt-expression
- ,(semantic-lambda
- (list (nth 2 vals) 'variable nil 't (nth 3 vals) nil nil)))
- ) ; end macro
- (variable
- ( variabledef punctuation "\\b;\\b"
- ,(semantic-lambda
- (nth 0 vals)))
- ) ; end variable
- (variabledef
- ( declmods typeform varnamelist
- ,(semantic-lambda
- (list (nth 2 vals) 'variable (nth 1 vals) ( if (nth 0 vals) ( string-match
"const" ( car (nth 0 vals)))) nil ( if ( and (nth 0 vals) ( string-match
"const" ( car (nth 0 vals)))) ( cdr (nth 0 vals)) (nth 0 vals)) nil)))
- ) ; end variabledef
- (opt-restrict
- ( symbol "\\<\\(__\\)?restrict\\>")
- ()
- ) ; end opt-restrict
- (varname
- ( opt-stars opt-restrict symbol opt-bits opt-array opt-assign
- ,(semantic-lambda
- (list (nth 2 vals)) (nth 0 vals) (nth 3 vals) (nth 4 vals) (nth 5 vals)))
- ) ; end varname
- (variablearg
- ( declmods typeform varname
- ,(semantic-lambda
- (list ( car (nth 2 vals)) 'variable (nth 1 vals) ( if (nth 0 vals) ( string-match
"const" ( car (nth 0 vals)))) nil ( if ( and (nth 0 vals) ( string-match
"const" ( car (nth 0 vals)))) ( cdr (nth 0 vals)) (nth 0 vals)) nil)))
- ) ; end variablearg
- (varnamelist
- ( varname punctuation "\\b,\\b" varnamelist
- ,(semantic-lambda
- ( cons (nth 0 vals) (nth 2 vals))))
- ( varname
- ,(semantic-lambda
- (list (nth 0 vals))))
- ) ; end varnamelist
- (arg-list
- ( symbol "\\<__?P\\>" semantic-list
- ,(lambda (vals start end)
-
- (semantic-bovinate-from-nonterminal (car (nth 1 vals)) (cdr (nth 1 vals))
'arg-list-p)
- ))
- ( semantic-list knr-arguments
- ,(semantic-lambda
- (nth 1 vals)))
- ( semantic-list
- ,(semantic-lambda
-
- (semantic-bovinate-from-nonterminal-full (car (nth 0 vals)) (cdr (nth 0 vals))
'arg-sub-list)
- ))
- ) ; end arg-list
- (knr-arguments
- ( variablearg punctuation "\\b;\\b" knr-arguments
- ,(semantic-lambda
- ( cons (nth 0 vals) (nth 2 vals))))
- ( variablearg punctuation "\\b;\\b"
- ,(semantic-lambda
- (list (nth 0 vals))))
- ) ; end knr-arguments
- (arg-list-p
- ( open-paren "(" semantic-list close-paren ")"
- ,(semantic-lambda
-
- (semantic-bovinate-from-nonterminal-full (car (nth 1 vals)) (cdr (nth 1 vals))
'arg-sub-list)
- ))
- ) ; end arg-list-p
- (arg-sub-list
- ( variablearg
- ,(semantic-lambda
- (nth 0 vals)))
- ( punctuation "\\b\\.\\b" punctuation "\\b\\.\\b" punctuation
"\\b\\.\\b" close-paren ")"
- ,(semantic-lambda
- (list "...")))
- ) ; end arg-sub-list
- (functiondef
- ( declmods typeform symbol arg-list
- ,(semantic-lambda
- (list (nth 2 vals) 'function (nth 1 vals) (nth 3 vals) (nth 0 vals) nil)))
- ) ; end functiondef
- (prototype
- ( functiondef punctuation "\\b;\\b"
- ,(semantic-lambda
- (nth 0 vals)))
- ) ; end prototype
- (function
- ( functiondef semantic-list
- ,(semantic-lambda
- (nth 0 vals)))
- ) ; end function
- (opt-expression
- ( expression)
- (
- ,(semantic-lambda
- (list nil)))
- ) ; end opt-expression
- (expression
- ( symbol
- ,(semantic-lambda
- (list nil)))
- ( punctuation "[!*&~]" symbol
- ,(semantic-lambda
- (list nil)))
- ( semantic-list
- ,(semantic-lambda
- (list nil)))
- ) ; end expression
- )
- "C language specification.")
+`((bovine-toplevel
+ ( macro)
+ ( type)
+ ( var-or-fun)
+ ( define)
+ ) ; end declaration
+ (bovine-inner-scope
+ ( define)
+ ( var-or-fun)
+ ( type)
+ ) ; end codeblock
+ (macro
+ ( punctuation "\\b#\\b" macro-or-include
+ ,(semantic-lambda
+ (nth 1 vals)))
+ ) ; end macro
+ (macro-or-include
+ ( DEFINE symbol opt-expression
+ ,(semantic-lambda
+ (list (nth 1 vals) 'variable nil (nth 2 vals) ( semantic-bovinate-make-assoc-list
'const t) nil)))
+ ( INCLUDE punctuation "\\b<\\b" filename punctuation
"\\b>\\b"
+ ,(semantic-lambda
+ (nth 2 vals) (list 'include t nil)))
+ ( INCLUDE string
+ ,(semantic-lambda
+ (list ( read (nth 1 vals)) 'include nil nil)))
+ ) ; end macro-or-include
+ (define
+ ( punctuation "\\b#\\b" DEFINE symbol opt-expression
+ ,(semantic-lambda
+ (list (nth 1 vals) 'variable nil (nth 2 vals) ( semantic-bovinate-make-assoc-list
'const t) nil)))
+ ) ; end define
+ (filename
+ ( symbol punctuation "\\b\\.\\b" symbol
+ ,(semantic-lambda
+ (list ( concat (nth 0 vals) (nth 1 vals) (nth 2 vals)))))
+ ( symbol punctuation "\\b/\\b" filename
+ ,(semantic-lambda
+ (list ( concat (nth 0 vals) (nth 1 vals) ( car (nth 2 vals))))))
+ ) ; end filename
+ (classparts
+ ( semantic-list
+ ,(semantic-lambda
+
+ (semantic-bovinate-from-nonterminal-full (car (nth 0 vals)) (cdr (nth 0 vals))
'classsubparts)
+ ))
+ ) ; end classparts
+ (classsubparts
+ ( open-paren "{"
+ ,(semantic-lambda
+ (list nil)))
+ ( close-paren "}"
+ ,(semantic-lambda
+ (list nil)))
+ ( opt-class-protection punctuation "\\b:\\b"
+ ,(semantic-lambda
+ (nth 0 vals) (list 'label)))
+ ( var-or-fun)
+ ( type)
+ ( define
+ ,(semantic-lambda
+ (nth 0 vals) (list 'protection)))
+ ()
+ ) ; end classsubparts
+ (opt-class-parents
+ ( punctuation "\\b:\\b" class-parents
+ ,(semantic-lambda
+ (list (nth 1 vals))))
+ (
+ ,(semantic-lambda
+ ))
+ ) ; end opt-class-parents
+ (class-parents
+ ( opt-class-protection symbol punctuation "\\b,\\b" class-parents
+ ,(semantic-lambda
+ ( cons (nth 1 vals) (nth 3 vals))))
+ ( opt-class-protection symbol
+ ,(semantic-lambda
+ (list (nth 1 vals))))
+ ) ; end class-parents
+ (opt-class-protection
+ ( PUBLIC)
+ ( PRIVATE)
+ ( PROTECTED)
+ ) ; end opt-class-protection
+ (namespaceparts
+ ( semantic-list
+ ,(semantic-lambda
+
+ (semantic-bovinate-from-nonterminal-full (car (nth 0 vals)) (cdr (nth 0 vals))
'namespacesubparts)
+ ))
+ ) ; end namespaceparts
+ (namespacesubparts
+ ( open-paren "{"
+ ,(semantic-lambda
+ (list nil)))
+ ( close-paren "}"
+ ,(semantic-lambda
+ (list nil)))
+ ( type)
+ ( var-or-fun)
+ ( define)
+ ( opt-class-protection punctuation "\\b:\\b"
+ ,(semantic-lambda
+ (list (nth 0 vals) 'protection)))
+ ()
+ ) ; end namespacesubparts
+ (enumparts
+ ( semantic-list
+ ,(semantic-lambda
+
+ (semantic-bovinate-from-nonterminal-full (car (nth 0 vals)) (cdr (nth 0 vals))
'enumsubparts)
+ ))
+ ) ; end enumparts
+ (enumsubparts
+ ( symbol opt-assign
+ ,(semantic-lambda
+ (list (nth 0 vals) 'variable "int") (nth 1 vals) (list (
semantic-bovinate-make-assoc-list 'const t) nil)))
+ ( open-paren "{"
+ ,(semantic-lambda
+ (list nil)))
+ ( close-paren "}"
+ ,(semantic-lambda
+ (list nil)))
+ ) ; end enumsubparts
+ (opt-name
+ ( symbol)
+ (
+ ,(semantic-lambda
+ (list nil)))
+ ) ; end opt-name
+ (typesimple
+ ( struct-or-class opt-name opt-class-parents classparts
+ ,(semantic-lambda
+ (nth 1 vals) (list 'type) (nth 0 vals) (list (nth 3 vals)) (nth 2 vals) (list nil
nil)))
+ ( UNION opt-name structparts
+ ,(semantic-lambda
+ (nth 1 vals) (list 'type (nth 0 vals) (nth 2 vals) nil nil nil)))
+ ( ENUM opt-name enumparts
+ ,(semantic-lambda
+ (nth 1 vals) (list 'type (nth 0 vals) (nth 2 vals) nil nil nil)))
+ ( TYPEDEF typeform symbol
+ ,(semantic-lambda
+ (list (nth 2 vals) 'type (nth 0 vals) nil (nth 1 vals) nil nil)))
+ ) ; end typesimple
+ (struct-or-class
+ ( STRUCT)
+ ( CLASS)
+ ) ; end struct-or-class
+ (type
+ ( typesimple punctuation "\\b;\\b"
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ( NAMESPACE symbol namespaceparts
+ ,(semantic-lambda
+ (list (nth 1 vals) 'type (nth 0 vals) (nth 2 vals) nil nil nil)))
+ ) ; end type
+ (opt-stars
+ ( punctuation "\\b\\*\\b" opt-stars
+ ,(semantic-lambda
+ (list ( 1+ ( car (nth 1 vals))))))
+ (
+ ,(semantic-lambda
+ (list 0)))
+ ) ; end opt-stars
+ (declmods
+ ( DECLMOD declmods
+ ,(semantic-lambda
+ ( cons ( car (nth 0 vals)) (nth 1 vals))))
+ ( DECLMOD
+ ,(semantic-lambda
+ (nth 0 vals)))
+ (
+ ,(semantic-lambda
+ ))
+ ) ; end declmods
+ (DECLMOD
+ ( EXTERN)
+ ( STATIC)
+ ( CONST)
+ ( VOLATILE)
+ ( SIGNED)
+ ( UNSIGNED)
+ ( VIRTUAL)
+ ( INLINE)
+ ) ; end DECLMOD
+ (typeform
+ ( typeformbase opt-stars opt-ref
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ) ; end typeform
+ (opt-ref
+ ( punctuation "\\b&\\b")
+ ()
+ ) ; end opt-ref
+ (typeformbase
+ ( typesimple
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ( STRUCT symbol
+ ,(semantic-lambda
+ (list (nth 1 vals) 'type (nth 0 vals))))
+ ( UNION symbol
+ ,(semantic-lambda
+ (list (nth 1 vals) 'type (nth 0 vals))))
+ ( ENUM symbol
+ ,(semantic-lambda
+ (list (nth 1 vals) 'type (nth 0 vals))))
+ ( builtintype
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ( symbol
+ ,(semantic-lambda
+ (list (nth 0 vals))))
+ ) ; end typeformbase
+ (builtintype
+ ( VOID)
+ ( CHAR)
+ ( SHORT)
+ ( INT)
+ ( LONG)
+ ( FLOAT)
+ ( DOUBLE)
+ ) ; end builtintype
+ (var-or-fun
+ ( declmods typeform var-or-func-decl
+ ,(semantic-lambda
+ ( semantic-c-reconstitute-token (nth 2 vals) (nth 0 vals) (nth 1 vals))))
+ ( declmods var-or-func-decl
+ ,(semantic-lambda
+ ( semantic-c-reconstitute-token (nth 1 vals) (nth 0 vals) nil)))
+ ) ; end var-or-fun
+ (var-or-func-decl
+ ( opt-class opt-destructor functionname arg-list opt-throw fun-or-proto-end
+ ,(semantic-lambda
+ (nth 2 vals) (list 'function (nth 0 vals) (nth 1 vals) (nth 3 vals) (nth 4
vals))))
+ ( varnamelist punctuation "\\b;\\b"
+ ,(semantic-lambda
+ (list (nth 0 vals) 'variable)))
+ ) ; end var-or-func-decl
+ (opt-throw
+ ( THROW semantic-list
+ ,(lambda (vals start end)
+
+ (semantic-bovinate-from-nonterminal (car (nth 1 vals)) (cdr (nth 1 vals))
'throw-exception-list)
+ ))
+ ()
+ ) ; end opt-throw
+ (throw-exception-list
+ ( symbol punctuation "\\b,\\b" throw-exception-list
+ ,(semantic-lambda
+ ( cons (nth 0 vals) (nth 2 vals))))
+ ( symbol close-paren ")"
+ ,(semantic-lambda
+ (list (nth 0 vals))))
+ ( open-paren "(" throw-exception-list
+ ,(semantic-lambda
+ (nth 1 vals)))
+ ) ; end throw-exception-list
+ (opt-bits
+ ( punctuation "\\b:\\b" symbol
+ ,(semantic-lambda
+ (list (nth 1 vals))))
+ (
+ ,(semantic-lambda
+ (list nil)))
+ ) ; end opt-bits
+ (opt-array
+ ( semantic-list "\\[.*\\]$" opt-array
+ ,(semantic-lambda
+ (list ( cons 1 ( car (nth 1 vals))))))
+ (
+ ,(semantic-lambda
+ (list nil)))
+ ) ; end opt-array
+ (opt-assign
+ ( punctuation "\\b=\\b" expression
+ ,(semantic-lambda
+ (list (nth 1 vals))))
+ (
+ ,(semantic-lambda
+ (list nil)))
+ ) ; end opt-assign
+ (opt-restrict
+ ( symbol "\\<\\(__\\)?restrict\\>")
+ ()
+ ) ; end opt-restrict
+ (varname
+ ( opt-stars opt-restrict symbol opt-bits opt-array opt-assign
+ ,(semantic-lambda
+ (list (nth 2 vals)) (nth 0 vals) (nth 3 vals) (nth 4 vals) (nth 5 vals)))
+ ) ; end varname
+ (variablearg
+ ( declmods typeform varname
+ ,(semantic-lambda
+ (list ( car (nth 2 vals)) 'variable (nth 1 vals) nil (
semantic-bovinate-make-assoc-list 'const ( if ( member "const" (nth 0 vals))
t nil) 'typemodifiers ( delete "const" (nth 0 vals))) nil)))
+ ) ; end variablearg
+ (varnamelist
+ ( varname punctuation "\\b,\\b" varnamelist
+ ,(semantic-lambda
+ ( cons (nth 0 vals) (nth 2 vals))))
+ ( varname
+ ,(semantic-lambda
+ (list (nth 0 vals))))
+ ) ; end varnamelist
+ (opt-class
+ ( symbol punctuation "\\b:\\b" punctuation "\\b:\\b"
+ ,(semantic-lambda
+ (list (nth 0 vals))))
+ (
+ ,(semantic-lambda
+ (list nil)))
+ ) ; end opt-class
+ (opt-destructor
+ ( punctuation "\\b~\\b"
+ ,(semantic-lambda
+ (list t)))
+ (
+ ,(semantic-lambda
+ (list nil)))
+ ) ; end opt-destructor
+ (arg-list
+ ( symbol "\\<__?P\\>" semantic-list
+ ,(lambda (vals start end)
+
+ (semantic-bovinate-from-nonterminal (car (nth 1 vals)) (cdr (nth 1 vals))
'arg-list-p)
+ ))
+ ( semantic-list "^(" knr-arguments
+ ,(semantic-lambda
+ (nth 1 vals)))
+ ( semantic-list "^("
+ ,(semantic-lambda
+
+ (semantic-bovinate-from-nonterminal-full (car (nth 0 vals)) (cdr (nth 0 vals))
'arg-sub-list)
+ ))
+ ) ; end arg-list
+ (knr-arguments
+ ( variablearg punctuation "\\b;\\b" knr-arguments
+ ,(semantic-lambda
+ ( cons (nth 0 vals) (nth 2 vals))))
+ ( variablearg punctuation "\\b;\\b"
+ ,(semantic-lambda
+ (list (nth 0 vals))))
+ ) ; end knr-arguments
+ (arg-list-p
+ ( open-paren "(" semantic-list close-paren ")"
+ ,(semantic-lambda
+
+ (semantic-bovinate-from-nonterminal-full (car (nth 1 vals)) (cdr (nth 1 vals))
'arg-sub-list)
+ ))
+ ) ; end arg-list-p
+ (arg-sub-list
+ ( variablearg
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ( punctuation "\\b\\.\\b" punctuation "\\b\\.\\b" punctuation
"\\b\\.\\b" close-paren ")"
+ ,(semantic-lambda
+ (list "...")))
+ ( open-paren "("
+ ,(semantic-lambda
+ (list nil)))
+ ( close-paren ")"
+ ,(semantic-lambda
+ (list nil)))
+ ) ; end arg-sub-list
+ (operatorsym
+ ( punctuation "\\b<\\b" punctuation "\\b<\\b"
+ ,(semantic-lambda
+ (list "<<")))
+ ( punctuation "\\b>\\b" punctuation "\\b>\\b"
+ ,(semantic-lambda
+ (list ">>")))
+ ( punctuation "\\b=\\b" punctuation "\\b=\\b"
+ ,(semantic-lambda
+ (list "==")))
+ ( punctuation "\\b<\\b" punctuation "\\b=\\b"
+ ,(semantic-lambda
+ (list "<=")))
+ ( punctuation "\\b>\\b" punctuation "\\b=\\b"
+ ,(semantic-lambda
+ (list ">=")))
+ ( punctuation "\\b!\\b" punctuation "\\b=\\b"
+ ,(semantic-lambda
+ (list "!=")))
+ ( punctuation "\\b<\\b")
+ ( punctuation "\\b>\\b")
+ ( punctuation "\\b\\*\\b")
+ ( punctuation "\\b\\+\\b")
+ ( punctuation "\\b-\\b")
+ ( punctuation "\\b/\\b")
+ ( punctuation "\\b=\\b")
+ ) ; end operatorsym
+ (functionname
+ ( OPERATOR operatorsym
+ ,(semantic-lambda
+ (nth 1 vals)))
+ ( symbol
+ ,(semantic-lambda
+ (list (nth 0 vals))))
+ ) ; end functionname
+ (fun-or-proto-end
+ ( punctuation "\\b;\\b"
+ ,(semantic-lambda
+ (list t)))
+ ( semantic-list
+ ,(semantic-lambda
+ (list nil)))
+ ) ; end fun-or-proto-end
+ (opt-expression
+ ( expression)
+ (
+ ,(semantic-lambda
+ (list nil)))
+ ) ; end opt-expression
+ (expression
+ ( symbol
+ ,(semantic-lambda
+ ))
+ ( punctuation "[!*&~]" symbol
+ ,(semantic-lambda
+ ))
+ ( string
+ ,(semantic-lambda
+ ))
+ ( semantic-list
+ ,(semantic-lambda
+ ))
+ ) ; end expression
+ )
+ "C language specification.")
(defvar semantic-flex-c-extensions
'(("^#\\(if\\(def\\)?\\|else\\|endif\\)" . semantic-flex-c-if))
@@ -304,7 +491,7 @@
(let ((vl nil)
(basety (semantic-token-type nonterm))
(ty "")
- (mods (semantic-token-variable-modifiers nonterm))
+ (mods (semantic-token-variable-extra-spec nonterm 'typemodifiers))
(suffix "")
(lst (semantic-token-name nonterm))
(cur nil)
@@ -314,31 +501,32 @@
(setq cur (car lst))
(if (nth 2 cur)
(setq suffix (concat ":" (nth 2 cur))))
- (if (nth 3 cur)
- (setq suffix (concat suffix
- "[" (int-to-string
- (length (nth 3 cur))) "]")))
(if (= (length basety) 1)
(progn
(setq ty (car basety))
(if (nth 1 cur)
(setq ty (concat ty (make-string (nth 1 cur) ?*)))))
(setq ty basety))
- (setq vl (cons (list (car cur)
- 'variable
- ty
- (semantic-token-variable-const nonterm)
- (nth 4 cur)
- mods
- suffix
- (semantic-token-docstring nonterm)
- (semantic-token-overlay nonterm))
- vl))
+ (setq vl (cons
+ (list
+ (car cur) ;name
+ 'variable
+ ty ;type
+ (nth 4 cur) ;default value
+ (semantic-bovinate-make-assoc-list
+ 'const (semantic-token-variable-const nonterm)
+ 'suffix suffix
+ 'typemodifiers mods
+ 'dereference (length (nth 3 cur))
+ )
+ (semantic-token-docstring nonterm) ;doc
+ (semantic-token-overlay nonterm))
+ vl))
(setq lst (cdr lst)))
vl))
((and (listp (car nonterm))
(eq (semantic-token-token (car nonterm)) 'variable))
- ;; Argument lists come in this way. Append all the expandsions!
+ ;; Argument lists come in this way. Append all the expansions!
(let ((vl nil))
(while nonterm
(setq vl (append (semantic-expand-c-nonterminal (car vl))
@@ -348,6 +536,120 @@
(t nil))
nil))
+(defun semantic-c-reconstitute-token (tokenpart declmods typedecl)
+ "Reconstitute a token TOKENPART with DECLMODS and TYPEDECL.
+This is so we don't have to match the same starting text several times."
+ (cond ((eq (nth 1 tokenpart) 'variable)
+ (list (car tokenpart)
+ 'variable
+ (or typedecl "int") ;type
+ nil ;default value (filled with expand)
+ (semantic-bovinate-make-assoc-list
+ 'const (if (member "const" declmods) t nil)
+ 'typemodifiers (delete "const" declmods))
+ nil)
+ )
+ ((eq (nth 1 tokenpart) 'function)
+ (list (car tokenpart)
+ 'function
+ (or typedecl "int") ;type
+ (nth 4 tokenpart) ;arglist
+ (semantic-bovinate-make-assoc-list
+ 'const (if (member "const" declmods) t nil)
+ 'typemodifiers (delete "const" declmods)
+ 'parent (car (nth 2 tokenpart))
+ 'destructor (car (nth 3 tokenpart) )
+ ;; Even though it is "throw" in C++, we use
+ ;; `throws' as a common name for things that toss
+ ;; exceptions about.
+ 'throws (nth 5 tokenpart))
+ nil)
+ )
+ ))
+
+(defvar semantic-c-keyword-table
+ (semantic-flex-make-keyword-table
+ `( ("include" . INCLUDE)
+ ("define" . DEFINE)
+ ("extern" . EXTERN)
+ ("static" . STATIC)
+ ("const" . CONST)
+ ("volatile" . VOLATILE)
+ ("signed" . SIGNED)
+ ("unsigned" . UNSIGNED)
+ ("inline" . INLINE)
+ ("virtual" . VIRTUAL)
+ ("struct" . STRUCT)
+ ("union" . UNION)
+ ("enum" . ENUM)
+ ("typedef" . TYPEDEF)
+ ("class" . CLASS)
+ ("namespace" . NAMESPACE)
+ ("throw" . THROW)
+ ("operator" . OPERATOR)
+ ("public" . PUBLIC)
+ ("private" . PRIVATE)
+ ("protected" . PROTECTED)
+ ("if" . IF)
+ ("else" . ELSE)
+ ("do" . DO)
+ ("while" . WHILE)
+ ("for" . FOR)
+ ("switch" . SWITCH)
+ ("case" . CASE)
+ ("default" . DEFAULT)
+ ("return" . RETURN)
+ ("break" . BREAK)
+ ("continue" . CONTINUE)
+ ("sizeof" . SIZEOF)
+ ("void" . VOID)
+ ("char" . CHAR)
+ ("short" . SHORT)
+ ("int" . INT)
+ ("long" . LONG)
+ ("float" . FLOAT)
+ ("double" . DOUBLE)
+ )
+ '(
+ ("extern" summary "Declaration Modifier: extern <type>
<name> ...")
+ ("static" summary "Declaration Modifier: static <type>
<name> ...")
+ ("const" summary "Declaration Modifier: const <type>
<name> ...")
+ ("volatile" summary "Declaration Modifier: volatile <type>
<name> ...")
+ ("signed" summary "Numeric Type Modifier: signed <numeric type>
<name> ...")
+ ("unsigned" summary "Numeric Type Modifier: unsigned <numeric
type> <name> ...")
+ ("virtual" summary "Method Modifier: virtual <type>
<name>(...) ...")
+ ("struct" summary "Structure Type Declaration: struct [name] { ...
};")
+ ("union" summary "Union Type Declaration: union [name] { ...
};")
+ ("enum" summary "Enumeration Type Declaration: enum [name] { ...
};")
+ ("typedef" summary "Arbitrary Type Declaration: typedef
<typedeclaration> <name>;")
+ ("class" summary "Class Declaration: class <name>[:parents] {
... };")
+ ("namespace" summary "Namespace Declaration: namespace <name> {
... };")
+ ("throw" summary "<type> <methoddef> (<method
args>) throw (<exception>) ...")
+ ("if" summary "if (<condition>) { code } [ else { code }
]")
+ ("else" summary "if (<condition>) { code } [ else { code }
]")
+ ("do" summary " do { code } while (<condition>);")
+ ("while" summary "do { code } while (<condition>); or while
(<condition>) { code };")
+ ("for" summary "for(<init>; <condition>;
<increment>) { code }")
+ ("switch" summary "switch (<variable>) { case
<constvalue>: code; ... default: code; }")
+ ("case" summary "switch (<variable>) { case <constvalue>:
code; ... default: code; }")
+ ("default" summary "switch (<variable>) { case
<constvalue>: code; ... default: code; }")
+ ("return" summary "return <value>;")
+ ("break" summary "Non-local exit within a loop or switch (for,
do/while, switch): break;")
+ ("continue" summary "Non-local continue within a lool (for,
do/while): continue;")
+ ("sizeof" summary "Compile time macro: sizeof(<type or
variable>) // size in bytes")
+ ("void" summary "Built in typeless type: void")
+ ("char" summary "Integral Character Type: (0 to 256)")
+ ("short" summary "Integral Primitive Type: (-32768 to 32767)")
+ ("int" summary "Integral Primitive Type: (-2147483648 to
2147483647)")
+ ("long" summary "Integral primitive type (-9223372036854775808 to
9223372036854775807)")
+ ("float" summary "Primitive floating-point type (single-precision
32-bit IEEE 754)")
+ ("double" summary "Primitive floating-point type (double-precision
64-bit IEEE 754)")
+ ))
+ "Some keywords used in C.")
+
+
+;;; Override methods & Variables
+;;
(defcustom semantic-default-c-path '("/usr/include"
"/usr/dt/include"
"/usr/X11R6/include")
"Default set of include paths for C code.
@@ -366,36 +668,69 @@
:group 'c
:type '(repeat (string :tag "Type")))
-(defvar semantic-c-keyword-table
- (semantic-flex-make-keyword-table
- `( ("include" . INCLUDE)
- ("define" . DEFINE)
- ("struct" . STRUCT)
- ("union" . UNION)
- ("enum" . ENUM)
- ("typedef" . TYPEDEF)
- ))
- "Some keywords used in C.")
+(defun semantic-c-nonterminal-protection (token &optional parent)
+ "Return the protection of TOKEN in PARENT.
+Override function for `semantic-nonterminal-protection'."
+ (let ((mods (semantic-token-type-modifiers token))
+ (prot nil))
+ ;; Check the modifiers for protection if we are not a child
+ ;; of some class type.
+ (when (or (not parent) (not (eq (semantic-token-token parent) 'type)))
+ (while (and (not prot) mods)
+ (if (stringp (car mods))
+ (let ((s (car mods)))
+ ;; A few silly defaults to get things started.
+ (cond ((or (string= s "extern")
+ (string= s "export"))
+ 'public)
+ ((string= s "static")
+ 'private))))
+ (setq mods (cdr mods))))
+ ;; If we have a typed parent, look for :public style labels.
+ (when (and parent (eq (semantic-token-token parent) 'type))
+ (let ((pp (semantic-token-type-parts parent)))
+ (while (and pp (not (eq (car pp) token)))
+ (when (eq (semantic-token-token (car pp)) 'label)
+ (setq prot
+ (cond ((string= (semantic-token-name (car pp)) "public")
+ 'public)
+ ((string= (semantic-token-name (car pp)) "private")
+ 'private)
+ ((string= (semantic-token-name (car pp)) "protected")
+ 'protected)))
+ )
+ (setq pp (cdr pp)))))
+ prot))
+
(defun semantic-default-c-setup ()
"Set up a buffer for semantic parsing of the C language."
(setq semantic-default-built-in-types semantic-default-c-built-in-types)
;; Code generated from c.bnf
- (setq semantic-toplevel-bovine-table semantic-toplevel-c-bovine-table)
+ (setq semantic-toplevel-bovine-table semantic-toplevel-c-bovine-table
+ semantic-toplevel-bovine-table-source "c.bnf")
(setq semantic-flex-keywords-obarray semantic-c-keyword-table)
+ (setq semantic-equivalent-major-modes '(c-mode c++-mode))
+ (semantic-install-function-overrides
+ '( (nonterminal-protection . semantic-c-nonterminal-protection)
+ )
+ nil)
(setq semantic-expand-nonterminal 'semantic-expand-c-nonterminal
semantic-flex-extensions semantic-flex-c-extensions
semantic-dependency-include-path semantic-default-c-path
imenu-create-index-function 'semantic-create-imenu-index
+ semantic-type-relation-separator-character '("." "->")
+ semantic-command-separation-character ";"
document-comment-start "/*"
document-comment-line-prefix " *"
document-comment-end " */"
)
-
+
;; End code generated from c.bnf
)
(add-hook 'c-mode-hook 'semantic-default-c-setup)
+(add-hook 'c++-mode-hook 'semantic-default-c-setup)
(provide 'semantic-c)
Index: xemacs-packages/semantic/semantic-ctxt.el
===================================================================
RCS file: semantic-ctxt.el
diff -N semantic-ctxt.el
--- /dev/null Tue Aug 14 14:29:33 2001
+++ semantic-ctxt.el Tue Aug 14 22:28:17 2001
@@ -0,0 +1,499 @@
+;;; semantic-ctxt.el --- Context calculations for Semantic tools.
+
+;;; Copyright (C) 1999, 2000, 2001 Eric M. Ludlam
+
+;; Author: Eric M. Ludlam <zappo(a)gnu.org>
+;; Keywords: syntax
+;; X-RCS: $Id: semantic-ctxt.el,v 1.9 2001/04/21 14:42:41 zappo Exp $
+
+;; This file is not part of GNU Emacs.
+
+;; Semantic is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This software is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+;;
+;; Semantic, as a tool, provides a nice list of searchable tokens.
+;; That information can provide some very accurate answers if the current
+;; context of a position is known.
+;;
+;; This library provides the hooks needed for a language to specify how
+;; the current context is calculated.
+;;
+(require 'semantic)
+(eval-when-compile (require 'semanticdb))
+
+;;; Code:
+;;
+(defvar semantic-command-separation-character
+ ";"
+ "String which indicates the end of a command.
+Used for identifying the end of a single command.")
+(make-variable-buffer-local 'semantic-command-separation-character)
+
+(defvar semantic-function-argument-separation-character
+ ","
+ "String which indicates the end of a command.
+Used for identifying the end of a single command.")
+(make-variable-buffer-local 'semantic-function-argument-separation-character)
+
+;;; Local variable parsing.
+;;
+(defun semantic-up-context (&optional point)
+ "Move point up one context from POINT.
+Return non-nil if there are no more context levels.
+Overloaded functions using `up-context' take no parameters."
+ (if point (goto-char (point)))
+ (let ((s (semantic-fetch-overload 'up-context)))
+ (if s (funcall s)
+ (semantic-up-context-default)
+ )))
+
+(defun semantic-up-context-default ()
+ "Move the point up and out one context level.
+Works with languages that use parenthetical grouping."
+ ;; By default, assume that the language uses some form of parenthetical
+ ;; do dads for their context.
+ (condition-case nil
+ (progn
+ (up-list -1)
+ nil)
+ (error t)))
+
+(defun semantic-beginning-of-context (&optional point)
+ "Move POINT to the beginning of the current context.
+Return non-nil if there is no upper context.
+The default behavior uses `semantic-up-context'. It can
+be overridden with `beginning-of-context'."
+ (if point (goto-char (point)))
+ (let ((s (semantic-fetch-overload 'beginning-of-context)))
+ (if s (funcall s)
+ (semantic-beginning-of-context-default)
+ )))
+
+(defun semantic-beginning-of-context-default ()
+ "Move point to the beginning of the current context via parenthisis.
+Return non-nil if there is no upper context."
+ (if (semantic-up-context)
+ t
+ (forward-char 1)
+ nil))
+
+(defun semantic-end-of-context (&optional point)
+ "Move POINT to the end of the current context.
+Return non-nil if there is no upper context.
+Be default, this uses `semantic-up-context', and assumes parenthetical
+block delimiters. This can be overridden with `end-of-context'."
+ (if point (goto-char (point)))
+ (let ((s (semantic-fetch-overload 'end-of-context)))
+ (if s (funcall s)
+ (semantic-end-of-context-default)
+ )))
+
+(defun semantic-end-of-context-default ()
+ "Move point to the end of the current context via parenthisis.
+Return non-nil if there is no upper context."
+ (if (semantic-up-context)
+ t
+ ;; Go over the list, and back over the end parenthisis.
+ (forward-sexp 1)
+ (forward-char -1)
+ nil))
+
+(defun semantic-get-local-variables (&optional point)
+ "Get the local variables based on POINT's context.
+Local variables are returned in Semantic token format.
+Be default, this calculates the current bounds using context blocks
+navigation, then uses the parser with `bovine-inner-scope' to
+parse tokens at the beginning of the context.
+This can be overriden with `get-local-variables'."
+ (save-excursion
+ (if point (goto-char (point)))
+ (let ((s (semantic-fetch-overload 'get-local-variables))
+ (case-fold-search semantic-case-fold))
+ (if s (funcall s)
+ (semantic-get-local-variables-default)
+ ))))
+
+(defun semantic-get-local-variables-default ()
+ "Get local values from a specific context.
+Uses the bovinator with the special top-symbol `bovine-inner-scope'
+to collect tokens, such as local variables or prototypes."
+ (working-status-forms "Local" "done"
+ (let ((semantic-bovination-working-type nil))
+ (semantic-bovinate-region-until-error
+ (point) (save-excursion (semantic-end-of-context) (point))
+ 'bovine-inner-scope))))
+
+(defun semantic-get-local-arguments (&optional point)
+ "Get arguments (variables) from the current context at POINT.
+Parameters are available if the point is in a function or method.
+This function returns a list of tokens. If the local token returns
+just a list of strings, then this function will convert them to tokens.
+Part of this behavior can be overridden with `get-local-arguments'."
+ (if point (goto-char (point)))
+ (let* ((s (semantic-fetch-overload 'get-local-arguments))
+ (case-fold-search semantic-case-fold)
+ (params (if s (funcall s)
+ (semantic-get-local-arguments-default)))
+ (rparams nil))
+ ;; convert unsafe params to the right thing.
+ (while params
+ (setq rparams
+ (cons (cond ((semantic-token-p (car params))
+ (car params))
+ ((stringp (car params))
+ (list (car params) 'variable))
+ (t (error "Unknown parameter element")))
+ rparams)
+ params (cdr params)))
+ (nreverse rparams)))
+
+(defun semantic-get-local-arguments-default ()
+ "Get arguments (variables) from the current context.
+Parameters are available if the point is in a function or method."
+ (let ((tok (semantic-current-nonterminal)))
+ (if (and tok (eq (semantic-token-token tok) 'function))
+ (semantic-token-function-args tok))))
+
+(defun semantic-get-all-local-variables (&optional point)
+ "Get all local variables for this context, and parent contexts.
+Local variables are returned in Semantic token format.
+Be default, this gets local variables, and local arguments.
+This can be overridden with `get-all-local-variables'.
+Optional argument POINT is the location to start getting the variables from."
+ (save-excursion
+ (if point (goto-char (point)))
+ (let ((s (semantic-fetch-overload 'get-all-local-variables))
+ (case-fold-search semantic-case-fold))
+ (if s (funcall s)
+ (semantic-get-all-local-variables-default)
+ ))))
+
+(defun semantic-get-all-local-variables-default ()
+ "Get all local variables for this context, and parent contexts.
+Local variables are returned in Semantic token format.
+Uses `semantic-beginning-of-context', `semantic-end-of-context',
+`semantic-up-context', and `semantic-get-local-variables' to collect
+this information."
+ (let ((varlist nil)
+ (sublist nil))
+ (save-excursion
+ (while (not (semantic-beginning-of-context))
+ ;; Get the local variables
+ (setq sublist (semantic-get-local-variables))
+ (if sublist
+ (setq varlist (cons sublist varlist)))
+ ;; Move out of this context to the next.
+ (semantic-up-context)))
+ ;; arguments to some local function
+ (setq sublist (semantic-get-local-arguments))
+ (if sublist (setq varlist (cons sublist varlist)))
+ ;; fix er up.
+ (nreverse varlist)))
+
+;;; Local context parsing
+;;
+;; Context parsing assumes a series of language independent commonalities.
+;; These terms are used to describe those contexts:
+;;
+;; command - One command in the language.
+;; symbol - The symbol the cursor is on.
+;; This would include a series of type/field when applicable.
+;; assignment - The variable currently being assigned to
+;; function - The function call the cursor is on/in
+;; argument - The index to the argument the cursor is on.
+;;
+;;
+(defun semantic-end-of-command ()
+ "Move to the end of the current command.
+Be default, uses `semantic-command-separation-character'.
+Override with `end-of-command'."
+ (let ((s (semantic-fetch-overload 'end-of-command))
+ (case-fold-search semantic-case-fold))
+ (if s (funcall s)
+ (semantic-end-of-command-default)
+ )))
+
+(defun semantic-end-of-command-default ()
+ "Move to the beginning of the current command.
+Depends on `semantic-command-separation-character' to find the
+beginning and end of a command."
+ (let ((nt (semantic-current-nonterminal)))
+ (if (re-search-forward (regexp-quote semantic-command-separation-character)
+ (if nt (semantic-token-end nt))
+ t)
+ (forward-char -1))))
+
+(defun semantic-beginning-of-command ()
+ "Move to the beginning of the current command.
+Be default, users `semantic-command-separation-character'.
+Override with `beginning-of-command'."
+ (let ((s (semantic-fetch-overload 'beginning-of-command))
+ (case-fold-search semantic-case-fold))
+ (if s (funcall s)
+ (semantic-beginning-of-command-default)
+ )))
+
+(defun semantic-beginning-of-command-default ()
+ "Move to the beginning of the current command.
+Depends on `semantic-command-separation-character' to find the
+beginning and end of a command."
+ (let ((nt (semantic-current-nonterminal)))
+ (if (or
+ (and nt
+ (re-search-backward (regexp-quote semantic-command-separation-character)
+ (semantic-token-start nt)
+ t))
+ (re-search-backward (regexp-quote semantic-command-separation-character)
+ nil
+ t))
+ (progn
+ ;; Here is a speedy way to skip over junk between the end of
+ ;; the last command, and the beginning of the next.
+ (forward-word 1)
+ (forward-word -1)))))
+
+(defun semantic-ctxt-current-symbol (&optional point)
+ "Return the current symbol the cursor is on at POINT in a list.
+This will include a list of type/field names when applicable.
+This can be overridden using `ctxt-current-symbol'."
+ (if point (goto-char (point)))
+ (let ((s (semantic-fetch-overload 'ctxt-current-symbol))
+ (case-fold-search semantic-case-fold))
+ (if s (funcall s)
+ (semantic-ctxt-current-symbol-default)
+ )))
+
+(defun semantic-ctxt-current-symbol-default ()
+ "Return the current symbol the cursor is on at POINT in a list.
+This will include a list of type/field names when applicable.
+Depends on `semantic-type-relation-separator-character'."
+ (let* ((fieldsep1 (mapconcat (lambda (a) (regexp-quote a))
+ semantic-type-relation-separator-character
+ "\\|"))
+ (fieldsep (concat "\\(" fieldsep1 "\\)\\(\\w\\|\\s_\\)"))
+ (symlist nil)
+ end begin)
+ (save-excursion
+ (if (looking-at "\\w\\|\\s_")
+ (forward-sexp 1)
+ ;; Not on a sym, are we at a separator char with no field
+ ;; specified yet?
+ (when (or (looking-at fieldsep1)
+ (save-excursion
+ (and (condition-case nil
+ (progn (forward-sexp -1)
+ (forward-sexp 1)
+ t)
+ (error nil))
+ (looking-at fieldsep1))))
+ (setq symlist (list ""))
+ (forward-sexp -1)
+ (forward-sexp 1)))
+ (setq end (point))
+ (condition-case nil
+ (while (save-excursion
+ (forward-char -1)
+ (looking-at "\\w\\|\\s_"))
+ ;; We have a symbol.. Do symbol things
+ (forward-sexp -1)
+ (setq symlist (cons (buffer-substring-no-properties (point) end)
+ symlist))
+ ;; Skip the next syntactic expression backwards, then go forwards.
+ (forward-sexp -1)
+ (forward-sexp 1)
+ (if (looking-at fieldsep)
+ (setq end (point))
+ (error nil))
+ )
+ (error nil)))
+ symlist))
+
+(defun semantic-ctxt-current-assignment (&optional point)
+ "Return the current assignment near the cursor at POINT.
+Return a list as per `semantic-ctxt-current-symbol'.
+Return nil if there is nothing relevant.
+Override with `ctxt-current-assignment'."
+ (if point (goto-char (point)))
+ (let ((s (semantic-fetch-overload 'ctxt-current-assignment))
+ (case-fold-search semantic-case-fold))
+ (if s (funcall s)
+ (semantic-ctxt-current-assignment-default)
+ )))
+
+(defun semantic-ctxt-current-assignment-default ()
+ "Return the current assignment near the cursor at POINT.
+By default, assume that \"=\" indicates an assignment."
+ (condition-case nil
+ (let* ((begin (save-excursion (semantic-beginning-of-command) (point)))
+ (upc (save-excursion (semantic-up-context) (point)))
+ (nearest (if (< begin upc) upc begin)))
+ (save-excursion
+ ;; TODO: Skip a regexp backwards with whitespace from the
+ ;; syntax table.
+ (skip-chars-backward " \t\n")
+ ;; Lets wander backwards till we find an assignment.
+ (while (and (not (= (preceding-char) ?=))
+ (> (point) nearest))
+ (forward-sexp -1)
+ (skip-chars-backward " \t\n")
+ )
+ ;; We are at an equals sign. Go backwards a sexp, and
+ ;; we'll have the variable
+ (forward-sexp -1)
+ (semantic-ctxt-current-symbol)))
+ (error nil)))
+
+(defun semantic-ctxt-current-function (&optional point)
+ "Return the current function the cursor is in at POINT.
+The function returned is the one accepting the arguments that
+the cursor is currently in.
+This can be overridden with `ctxt-current-function'."
+ (if point (goto-char (point)))
+ (let ((s (semantic-fetch-overload 'ctxt-current-function))
+ (case-fold-search semantic-case-fold))
+ (if s (funcall s)
+ (semantic-ctxt-current-function-default)
+ )))
+
+(defun semantic-ctxt-current-function-default ()
+ "Return the current symbol the cursor is on at POINT in a list."
+ (save-excursion
+ (semantic-up-context)
+ (when (looking-at "(")
+ (semantic-ctxt-current-symbol)))
+ )
+
+(defun semantic-ctxt-current-argument (&optional point)
+ "Return the current symbol the cursor is on at POINT.
+Override with `ctxt-current-argument'."
+ (if point (goto-char (point)))
+ (let ((s (semantic-fetch-overload 'ctxt-current-argument))
+ (case-fold-search semantic-case-fold))
+ (if s (funcall s)
+ (semantic-ctxt-current-argument-default)
+ )))
+
+ (defun semantic-ctxt-current-argument-default ()
+ "Return the current symbol the cursor is on at POINT in a list.
+Depends on `semantic-function-argument-separation-character'."
+ (when (semantic-ctxt-current-function)
+ (save-excursion
+ ;; Only get the current arg index if we are in function args.
+ (let ((p (point))
+ (idx 1))
+ (semantic-up-context)
+ (while (re-search-forward
+ (regexp-quote semantic-function-argument-separation-character)
+ p t)
+ (setq idx (1+ idx)))
+ idx))))
+
+;;; Context analysis routines
+;;
+;; These routines use the override methods to provides high level
+;; predicates, and to come up with intelligent suggestions about
+;; the current context.
+(defun semantic-suggest-lookup-item (name &optional tokentype returntype)
+ "Find a token definition matching NAME with TOKENTYPE.
+Optional RETURNTYPE is a return value to match against also."
+ (let* ((locals (semantic-get-all-local-variables))
+ (case-fold-search semantic-case-fold)
+ (option
+ (or (let ((found nil))
+ (while (and locals (not found))
+ (setq found (semantic-find-nonterminal-by-name
+ name (car locals) t)
+ locals (cdr locals)))
+ found)
+ (semantic-find-nonterminal-by-name
+ name (current-buffer) t)
+ (and (featurep 'semanticdb)
+ (semanticdb-minor-mode-p)
+ (semanticdb-find-nonterminal-by-name name nil t nil t)))))
+ ;; This part is lame right now. It needs to eventually
+ ;; do the tokentype and returntype filters across all databases.
+ ;; Some of the above return one token, instead of a list. Deal with
+ ;; that too.
+ (if (listp option)
+ (if (semantic-token-p option)
+ option
+ ;; `semanticdb-find-nonterminal-by-name' returns a list
+ ;; ((DB-TABLE . TOKEN) ...)
+ (setq option (cdr (car option))))
+ (if (stringp option)
+ (list option 'variable)
+ ))))
+
+(defun semantic-suggest-variable-token-hierarchy ()
+ "Analyze the current line, and return a series of tokens.
+The tokens represent a hierarchy of dereferences. For example, a
+variable name will return a list with one token representing that
+variable's declaration. If that variable is being dereferenced, then
+return a list starting with the variable declaration, followed by all
+fields being extracted.
+
+For example, in c, \"foo->bar\" would return a list (VARTOKEN FIELDTOKEN)
+where VARTOKEN is a semantic token of the variable foo's declaration.
+FIELDTOKEN is either a string, or a semantic token representing
+the field in foo's type."
+ (let ((v (semantic-ctxt-current-symbol))
+ (case-fold-search semantic-case-fold)
+ (name nil)
+ (tok nil)
+ (chil nil)
+ (toktype nil))
+ ;; First, take the first element of V, and find its type.
+ (setq tok (semantic-suggest-lookup-item (car v) 'variable))
+ ;; Now refer to it's type.
+ (setq toktype (semantic-token-type tok))
+ (if (and (semantic-token-p toktype)
+ (not (semantic-token-type-parts toktype)))
+ (setq toktype (semantic-suggest-lookup-item
+ (if (semantic-token-p toktype)
+ (semantic-token-name toktype)
+ (if (stringp toktype)
+ toktype
+ (error "Unknown token type")))
+ 'type)))
+ (if toktype
+ (cond ((and (semantic-token-p toktype)
+ (setq chil (semantic-nonterminal-children toktype)))
+ ;; We now have the type of the start variable. Now we
+ ;; have to match the list of additional fields with the
+ ;; children of the type we found.
+ (let ((chosenfields (cdr tok))
+ (returnlist (list toktype)))
+ (while chosenfields
+ ;; Find this field in the current toktype
+
+ (setq chosenfields (cdr chosenfields)))
+ (nreverse returnlist))
+ )
+ ((semantic-token-p toktype)
+ (list toktype))
+ ((stringp toktype)
+ (list (list toktype 'type)))
+ (t nil)))))
+
+(defun semantic-suggest-current-type ()
+ "Return the recommended type at the current location."
+ (let ((recommendation (semantic-suggest-variable-token-hierarchy)))
+ (car (nreverse recommendation))))
+
+(provide 'semantic-ctxt)
+
+;;; semantic-ctxt.el ends here
Index: xemacs-packages/semantic/semantic-el.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/semantic/semantic-el.el,v
retrieving revision 1.4
diff -u -r1.4 semantic-el.el
--- xemacs-packages/semantic/semantic-el.el 2001/02/20 03:23:43 1.4
+++ xemacs-packages/semantic/semantic-el.el 2001/08/15 05:28:17
@@ -1,9 +1,9 @@
-;;; semantic-ex.el --- Semantic details for some languages
+;;; semantic-el.el --- Semantic details for Emacs Lisp
-;;; Copyright (C) 1999, 2000 Eric M. Ludlam
+;;; Copyright (C) 1999, 2000, 2001 Eric M. Ludlam
;; Author: Eric M. Ludlam <zappo(a)gnu.org>
-;; X-RCS: $Id: semantic-el.el,v 1.4 2001/02/20 03:23:43 youngs Exp $
+;; X-RCS: $Id: semantic-el.el,v 1.48 2001/07/13 16:05:35 zappo Exp $
;; This file is not part of GNU Emacs.
@@ -34,152 +34,185 @@
`((bovine-toplevel
(semantic-list
,(lambda (vals start end)
- (let ((i (semantic-bovinate-from-nonterminal
- start end 'extract-toplevel nil
- ;; NOTE, currently the longest item we have is 6 long,
- ;; so only ask the flexer to go out 6 tokens.
- 6)))
- (append (nreverse (cdr (cdr (reverse i))))
- (list start end)))))
- (extract-toplevel))
- ;; When parsing at depth 0, we need to extract elements from semantic
- ;; lists at bovine-toplevel. This symbol provides the needed redirection.
- (extract-toplevel
- (function)
- (variable)
- (type)
- (include)
- (package)
- (method)
- (advice)
- (code)
- (comment) )
- ;; A type is defined by extended tools like CL, or EIEIO
- (type
- (open-paren symbol "defclass" symbol arg-list
- field-list doc-string
- ,(semantic-lambda
- (list (nth 2 vals) 'type
- "class"
- (nth 4 vals) (nth 3 vals) nil
- (car-safe (nth 5 vals))))))
- ;; A function is anything that starts with a (defun
- (function
- (open-paren symbol "defun\\|defmacro\\|defsubst" symbol arg-list
doc-string
- ,(semantic-lambda
- (list (nth 2 vals) 'function nil (nth 3 vals) nil
- (car-safe (nth 4 vals))))))
- (method
- (open-paren symbol "defmethod\\|defgeneric" symbol opt-label arg-list
- doc-string
- ,(semantic-lambda
- (list (nth 2 vals) 'function nil (nth 4 vals) nil
- (car-safe (nth 5 vals))))))
- (advice
- (open-paren symbol "defadvice" symbol arg-list
- doc-string
- ,(semantic-lambda
- (list (nth 2 vals) 'function nil (nth 3 vals) nil
- (car-safe (nth 4 vals))))))
- ;; A variable can be a defvar or defconst.
- (variable
- (open-paren symbol "defvar\\|defconst\\|defcustom\\|defface\\|defimage"
- symbol expression doc-string
- ,(semantic-lambda
- (list (nth 2 vals) 'variable nil
- (if (string= (nth 1 vals) "defconst") t nil)
- nil nil (car-safe (nth 4 vals))))))
- ;; In elisp, an include is just the require statement.
- (include
- (open-paren symbol "require" quote symbol
- ,(semantic-lambda
- (list (nth 3 vals) 'include nil nil))))
- ;; in elisp, a package statement is the same as the provide token.
- (package
- (open-paren symbol "provide" quote symbol opt-filestring close-paren
- ,(semantic-lambda
- (list (nth 3 vals) 'package (nth 4 vals) nil))))
- (opt-filestring
- (string)
- ( ,(lambda (vals start end) (list nil))))
- ;; Some random code stuck in there.
- (code
- (open-paren symbol
- ,(semantic-lambda
- (let ((sym (if (nth 1 vals) (intern-soft (nth 1 vals)))))
- (if (and sym (fboundp sym))
- (list (nth 1 vals) 'code))))))
- ;; Doc strings are sometimes optional, and always just return the
- ;; start position.
- (doc-string
- (string ,(lambda (vals start end) (list start start end)))
- (comment ,(lambda (vals start end) (list start start end)))
- ())
- ;; Quotes are oft optional in some cases
- (quote (punctuation "'"))
- ;; Backquotes are also optional for macro type thingies
- (backquote (punctuation "`"))
- ;; Something that can be evaluated out to something.
- (expression
- (quote expression ,(semantic-lambda (list (car (cdr vals)))))
- (backquote expression ,(semantic-lambda (list (car (cdr vals)))))
- (semantic-list) (symbol) (string))
- ;; An argument list to a function
- (arg-list
- (symbol "nil" ,(lambda (vals start end) (list nil)))
- (semantic-list ,(lambda (vals start end)
- (semantic-bovinate-from-nonterminal start end 'argsyms)
- ))
- ;; If it's already opened, what to do??
- )
- (argsyms
- (open-paren close-paren ,(semantic-lambda
- (list nil)))
- (open-paren argsyms ,(semantic-lambda (car (cdr vals))))
- (symbol argsyms ,(semantic-lambda
- (append (cons (car vals) (car (cdr vals))))))
- (semantic-list argsyms
- ,(semantic-lambda
- (let ((e (read (buffer-substring (car (nth 0 vals))
- (cdr (nth 0 vals))))))
- (cons (symbol-name (car e))
- (car (cdr vals))))))
- (symbol close-paren ,(semantic-lambda (list (car vals))))
- (semantic-list close-paren
- ,(semantic-lambda
- (let ((e (read (buffer-substring (car (nth 0 vals))
- (cdr (nth 0 vals))))))
- (list (symbol-name (car e)))))))
- ;; This guys is some number of argument symbols...
- (field-list
- (semantic-list
- ,(lambda (vals start end)
- (semantic-bovinate-from-nonterminal-full start end 'fieldsyms)
- )))
- (fieldsyms
- (semantic-list ,(semantic-lambda
- (let ((e (read (buffer-substring (car (nth 0 vals))
- (cdr (nth 0 vals))))))
- (list (symbol-name (car e))))))
- )
- ;; Labels
- (opt-label
- (symbol "^:" ,(semantic-lambda (car vals)))
- ())
+ (append (semantic-elisp-use-read (car vals))
+ (list start end)))))
)
"Top level bovination table for elisp.")
+(defun semantic-elisp-desymbolify (arglist)
+ "Convert symbols to strings for ARGLIST."
+ (let ((out nil))
+ (while arglist
+ (setq out
+ (cons
+ (if (symbolp (car arglist))
+ (symbol-name (car arglist))
+ (if (and (listp (car arglist))
+ (symbolp (car (car arglist))))
+ (symbol-name (car (car arglist)))
+ (format "%S" (car arglist))))
+ out)
+ arglist (cdr arglist)))
+ (nreverse out)))
+
+(defun semantic-elisp-form-to-doc-string (form)
+ "After reading a form FORM, covert it to a doc string.
+For Emacs Lisp, sometimes that string is non-existant.
+Recently discovered, sometimes it is a form which is evaluated
+at compile time, permitting compound strings."
+ (cond ((stringp form) form)
+ ((and (listp form) (eq (car form) 'concat)
+ (stringp (nth 1 form)))
+ (nth 1 form))
+ (t nil)))
+
+(defun semantic-elisp-use-read (sl)
+ "Use `read' on the semantic list SL.
+Return a bovination list to use."
+ (let* ((rt (read (buffer-substring (car sl) (cdr sl)))) ; read text
+ (ts (car rt)) ; type symbol
+ (tss (nth 1 rt))
+ (ss (if (not (listp tss)) tss
+ (if (eq (car tss) 'quote)
+ (nth 1 tss)
+ (car tss))))
+ (sn (format "%S" ss))
+ )
+ (cond
+ ((listp ts)
+ ;; If the first elt is a list, then it is some arbitrary code.
+ (list "anonymous" 'code))
+ ((or (eq ts 'defvar)
+ (eq ts 'defconst)
+ (eq ts 'defcustom)
+ (eq ts 'defface)
+ (eq ts 'defimage))
+ (let ((doc (semantic-elisp-form-to-doc-string (nth 3 rt))))
+ ;; Variables and constants
+ (list sn 'variable nil (nth 2 rt)
+ (semantic-bovinate-make-assoc-list
+ 'const (if (eq ts 'defconst) t nil)
+ 'user-visible (and doc
+ (> (length doc) 0)
+ (= (aref doc 0) ?*))
+ )
+ doc)
+ ))
+ ((or (eq ts 'defun)
+ (eq ts 'defsubst)
+ (eq ts 'defmacro))
+ ;; functions and macros
+ (list sn 'function nil (semantic-elisp-desymbolify (nth 2 rt))
+ (semantic-bovinate-make-assoc-list
+ 'user-visible (equal (car-safe (nth 4 rt)) 'interactive)
+ )
+ (nth 3 rt))
+ )
+ ((or (eq ts 'defmethod)
+ (eq ts 'defgeneric))
+ ;; methods
+ (let* ((a2 (nth 2 rt))
+ (a3 (nth 3 rt))
+ (args (if (listp a2) a2 a3))
+ (doc (nth (if (listp a2) 3 4) rt)))
+ (list sn 'function nil
+ (if (listp (car args))
+ (cons (symbol-name (car (car args)))
+ (semantic-elisp-desymbolify (cdr args)))
+ (semantic-elisp-desymbolify (cdr args)))
+ (semantic-bovinate-make-assoc-list
+ 'parent (symbol-name
+ (if (listp (car args)) (car (cdr (car args))))))
+ doc)
+ ))
+ ((eq ts 'defadvice)
+ ;; Advice
+ (list sn 'function nil (semantic-elisp-desymbolify (nth 2 rt))
+ nil (nth 3 rt)))
+ ((eq ts 'defclass)
+ ;; classes
+ (let ((docpart (nth 4 rt)))
+ (list sn 'type "class" (semantic-elisp-desymbolify (nth 3 rt))
+ (semantic-elisp-desymbolify (nth 2 rt))
+ (semantic-bovinate-make-assoc-list
+ 'typemodifiers
+ (semantic-elisp-desymbolify
+ (if (not (stringp docpart))
+ docpart))
+ )
+ (if (stringp docpart)
+ docpart
+ (car (cdr (member :documentation docpart))))))
+ )
+ ((eq ts 'defstruct)
+ ;; structs
+ (list sn 'type "struct" (semantic-elisp-desymbolify (nthcdr 2 rt))
+ nil ;(semantic-elisp-desymbolify (nth 2 rt))
+ nil (nth 4 rt))
+ )
+ ;; Now for other stuff
+ ((eq ts 'require)
+ (list sn 'include nil nil))
+ ((eq ts 'provide)
+ (list sn 'package (nth 3 rt) nil))
+ (t
+ ;; Other stuff
+ (list (symbol-name ts) 'code)
+ ))))
+
(defun semantic-elisp-find-dependency (token)
"Find the file BUFFER depends on described by TOKEN."
(let ((f (file-name-sans-extension
(locate-library (semantic-token-name token)))))
(concat f ".el")))
+(defun semantic-elisp-prototype-nonterminal (token &optional parent color)
+ "Return a prototype for the Emacs Lisp nonterminal TOKEN.
+PARENT and COLOR as for `semantic-prototype-nonterminal'."
+ (let* ((tok (semantic-token-token token))
+ (args (semantic-nonterminal-children token))
+ )
+ (if (eq tok 'function)
+ (concat (semantic-name-nonterminal token parent color) " ("
+ (mapconcat (lambda (a)
+ (if color
+ (if (string-match "^&" a)
+ ;; This is a keyword
+ (semantic-colorize-text a 'keyword)
+ (semantic-colorize-text a 'variable))
+ a))
+ args " ")
+ ")")
+ (semantic-prototype-nonterminal-default token parent color))))
+
+(defun semantic-elisp-find-documentation (token &optional nosnarf)
+ "Return the documentation string for TOKEN.
+Optional argument NOSNARF is ignored."
+ (let ((d (semantic-token-docstring token)))
+ (if (and d (> (length d) 0) (= (aref d 0) ?*))
+ (substring d 1)
+ d)))
+
+(defun semantic-elisp-insert-foreign-token (token tokenfile)
+ "Insert TOKEN from TOKENFILE at point.
+Attempts a simple prototype for calling or using TOKEN."
+ (cond ((eq (semantic-token-token token) 'function)
+ (insert "(" (semantic-token-name token) " )")
+ (forward-char -1))
+ (t
+ (insert (semantic-token-name token)))))
+
(defun semantic-default-elisp-setup ()
"Setup hook function for Emacs Lisp files and Semantic."
+ (semantic-install-function-overrides
+ '((find-dependency . semantic-elisp-find-dependency)
+ (prototype-nonterminal . semantic-elisp-prototype-nonterminal)
+ (concise-prototype-nonterminal . semantic-elisp-prototype-nonterminal)
+ (find-documentation . semantic-elisp-find-documentation)
+ (insert-foreign-token . semantic-elisp-insert-foreign-token)
+ )
+ t)
(setq semantic-toplevel-bovine-table semantic-toplevel-elisp-bovine-table
- semantic-override-table
- '((find-dependency . semantic-elisp-find-dependency))
semantic-symbol->name-assoc-list
'( (variable . "Variables")
(type . "Types")
Index: xemacs-packages/semantic/semantic-imenu.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/semantic/semantic-imenu.el,v
retrieving revision 1.4
diff -u -r1.4 semantic-imenu.el
--- xemacs-packages/semantic/semantic-imenu.el 2001/02/20 03:23:43 1.4
+++ xemacs-packages/semantic/semantic-imenu.el 2001/08/15 05:28:17
@@ -1,9 +1,11 @@
-;;; semantic-imenu.el --- Use the Bovinator as a imenu tag generateor
+;;; semantic-imenu.el --- Use the Bovinator as a imenu tag generator
-;;; Copyright (C) 2000 Paul Kinnucan & Eric Ludlam
+;;; Copyright (C) 2000, 2001 Paul Kinnucan & Eric Ludlam
+;;; Copyright (C) 2001 Eric Ludlam
-;; Author: Paul Kinnucan, Eric Ludlam
-;; X-RCS: $Id: semantic-imenu.el,v 1.4 2001/02/20 03:23:43 youngs Exp $
+;; Created By: Paul Kinnucan
+;; Maintainer: Eric Ludlam
+;; X-RCS: $Id: semantic-imenu.el,v 1.33 2001/05/14 16:28:34 zappo Exp $
;; This file is not part of GNU Emacs.
@@ -34,72 +36,167 @@
;; (setq imenu-create-index-function 'semantic-create-imenu-index)
;; ))
-(require 'semantic)
(condition-case nil
(require 'imenu)
(error nil))
+(require 'semantic)
+(eval-when-compile (require 'semanticdb)
+ )
+(condition-case nil
+ (progn
+ (require 'imenu)
+ (if (featurep 'xemacs)
+ ;; From David Ponce <david(a)dponce.com>
+ ;; Advice the XEmacs imenu function `imenu--create-menu-1' to
+ ;; handle menu separators.
+ (defadvice imenu--create-menu-1 (around semantic activate)
+ ;; Create a menu separator item if first argument (title)
+ ;; contains only hyphens and the second argument (list) is nil.
+ (if (and (null (ad-get-arg 1))
+ (not (string-match "[^-]" (ad-get-arg 0))))
+ (setq ad-return-value "-")
+ ad-do-it)))
+ )
+ (error nil))
+
+;; Because semantic imenu tokens will hose the current imenu handling
+;; code in speedbar, force semantic-sb in.
+(if (featurep 'speedbar)
+ (require 'semantic-sb)
+ (add-hook 'speedbar-load-hook (lambda () (require 'semantic-sb))))
+(defgroup semantic-imenu nil
+ "Parser Generator Imenu interface."
+ :group 'semantic
+ :group 'imenu
+ )
+
(defcustom semantic-imenu-summary-function 'semantic-abbreviate-nonterminal
"*Function to use when creating items in Imenu.
-Some useful functions are:
-`semantic-abbreviate-nonterminal'
-`semantic-summerize-nonterminal'
-`semantic-prototype-nonterminal'"
- :group 'imenu
- :type 'function)
+Some useful functions are found in `semantic-token->text-functions'."
+ :group 'semantic-imenu
+ :type semantic-token->text-custom-list)
(make-variable-buffer-local 'semantic-imenu-summary-function)
(defcustom semantic-imenu-bucketize-file t
"*Non-nil if tokens in a file are to be grouped into buckets."
- :group 'imenu
- :group 'semantic
+ :group 'semantic-imenu
:type 'boolean)
(make-variable-buffer-local 'semantic-imenu-bucketize-file)
(defcustom semantic-imenu-buckets-to-submenu t
"*Non-nil if buckets of tokens are to be turned into submenus.
This option is ignored if `semantic-imenu-bucketize-file' is nil."
- :group 'imenu
- :group 'semantic
+ :group 'semantic-imenu
:type 'boolean)
(make-variable-buffer-local 'semantic-imenu-buckets-to-submenu)
+(defcustom semantic-imenu-expand-type-parts t
+ "*Non-nil if types should have submenus with parts in it."
+ :group 'semantic-imenu
+ :type 'boolean)
+(make-variable-buffer-local 'semantic-imenu-expand-type-parts)
+
(defcustom semantic-imenu-bucketize-type-parts t
"*Non-nil if elements of a type should be placed grouped into buckets.
Nil means to keep them in the same order.
Overriden to nil if `semantic-imenu-bucketize-file' is nil."
- :group 'imenu
- :group 'semantic
+ :group 'semantic-imenu
:type 'boolean)
(make-variable-buffer-local 'semantic-imenu-bucketize-type-parts)
(defcustom semantic-imenu-sort-bucket-function nil
"*Function to use when sorting tags in the buckets of functions."
- :group 'imenu
- :group 'semantic
+ :group 'semantic-imenu
:type 'function)
(make-variable-buffer-local 'semantic-imenu-sort-bucket-function)
+(defcustom semantic-imenu-index-directory t
+ "*Non nil to index the entire directory for tags.
+Doesn't actually parse the entire directory, but displays tags for all files
+currently listed in the current Semantic database.
+This variable has no meaning if semanticdb is not active."
+ :group 'semantic-imenu
+ :type 'boolean)
+
+(defcustom semantic-imenu-auto-rebuild-directory-indexes t
+ "*If non-nil automatically rebuild directory index imenus.
+That is when a directory index imenu is updated, automatically rebuild
+other buffer local ones based on the same semanticdb."
+ :group 'semantic-imenu
+ :type 'boolean)
+
+(defvar semantic-imenu-directory-current-file nil
+ "When building a file index, this is the file name currently being built.")
+
+(defvar semantic-imenu-auto-rebuild-running nil
+ "Non-nil if `semantic-imenu-rebuild-directory-indexes' is running.")
+
+(defvar semantic-imenu-expandable-token 'type
+ "Tokens of this token type will be given submenu with children.
+By default, a `type' has interesting children. In Texinfo, however,
+a `section' has interesting children.")
+(make-variable-buffer-local 'semantic-imenu-expandable-token)
+
;;; Code:
+(defun semantic-imenu-token-overlay (token)
+ "Return the overlay belonging to TOKEN.
+If TOKEN doesn't have an overlay, and instead as a vector of positions,
+concoct a combination of file name, and position."
+ (let ((o (semantic-token-overlay token)))
+ (if (not (semantic-overlay-p o))
+ (let ((v (make-vector 3 nil)))
+ (aset v 0 semantic-imenu-directory-current-file)
+ (aset v 1 (aref o 0))
+ (aset v 2 (aref o 1))
+ v)
+ o)))
+
(defun semantic-imenu-goto-function (name position &optional rest)
"Move point associated with NAME to POSITION.
Used to override function `imenu-default-goto-function' so that we can continue
to use overlays to maintain the current position.
Optional argument REST is some extra stuff."
- (let ((os (semantic-overlay-start position)))
- (if os
- (imenu-default-goto-function name os rest)
- ;; This should never happen, but check anyway.
- (message "Imenu is out of date, try again. (internal bug)")
- (setq imenu--index-alist nil))))
+ (if (semantic-overlay-p position)
+ (let ((os (semantic-overlay-start position))
+ (ob (semantic-overlay-buffer position)))
+ (if os
+ (progn
+ (if (not (eq ob (current-buffer)))
+ (switch-to-buffer ob))
+ (imenu-default-goto-function name os rest))
+ ;; This should never happen, but check anyway.
+ (message "Imenu is out of date, try again. (internal bug)")
+ (setq imenu--index-alist nil)))
+ ;; When the POSITION is actually a pair of numbers in an array, then
+ ;; the file isn't loaded into the current buffer.
+ (if (vectorp position)
+ (let ((file (aref position 0))
+ (pos (aref position 1)))
+ (find-file file)
+ (imenu-default-goto-function name pos rest))
+ ;; When the POSITION is the symbol 'file-only' it means that this
+ ;; is a directory index entry and there is no tokens in this
+ ;; file. So just jump to the beginning of the file.
+ (if (eq position 'file-only)
+ (progn
+ (find-file name)
+ (imenu-default-goto-function name (point-min) rest))
+ (message "Semantic Imenu override problem. (Internal bug)")
+ (setq imenu--index-alist nil)))
+ ))
-(defun semantic-imenu-flush-fcn ()
+(defun semantic-imenu-flush-fcn (&optional ignore)
"This function is called as a hook to clear the imenu cache.
-This is added to `semantic-before-toplevel-cache-flush-hook'."
+This is added to `semantic-before-toplevel-cache-flush-hook' and
+`semantic-clean-token-hooks'. IGNORE arguments."
(if (eq imenu-create-index-function 'semantic-create-imenu-index)
(setq imenu--index-alist nil))
(remove-hook 'semantic-before-toplevel-cache-flush-hook
- 'semantic-imenu-flush-fcn))
+ 'semantic-imenu-flush-fcn t)
+ (remove-hook 'semantic-clean-token-hooks
+ 'semantic-imenu-flush-fcn t)
+ )
;;;###autoload
(defun semantic-create-imenu-index (&optional stream)
@@ -107,9 +204,66 @@
Uses the output of the Semantic Bovinator to create the index.
Optional argument STREAM is an optional stream of tokens used to create menus."
(setq imenu-default-goto-function 'semantic-imenu-goto-function)
- (add-hook 'semantic-before-toplevel-cache-flush-hook
- 'semantic-imenu-flush-fcn nil t)
- (semantic-create-imenu-index-1 stream))
+ (prog1
+ (if (and semantic-imenu-index-directory
+ (featurep 'semanticdb)
+ (semanticdb-minor-mode-p))
+ (semantic-create-imenu-directory-index stream)
+ (semantic-create-imenu-index-1 stream))
+ (add-hook 'semantic-before-toplevel-cache-flush-hook
+ 'semantic-imenu-flush-fcn nil t)
+ (add-hook 'semantic-clean-token-hooks
+ 'semantic-imenu-flush-fcn nil t)))
+
+(defun semantic-create-imenu-directory-index (&optional stream)
+ "Create an IMENU tag index based on all files active in semanticdb.
+Optional argument STREAM is the stream of tokens for the current buffer."
+ (if (not semanticdb-current-database)
+ (semantic-create-imenu-index-1 stream)
+ ;; We have a database, list all files, with the current file on top.
+ (let ((index (list
+ (cons (oref semanticdb-current-table file)
+ (or (semantic-create-imenu-index-1 stream)
+ ;; No tokens in this file
+ 'file-only))))
+ (tables (oref semanticdb-current-database tables)))
+ (working-status-forms "Imenu Directory Index" "done"
+ (while tables
+ (let ((semantic-imenu-directory-current-file
+ (oref (car tables) file))
+ tokens)
+ (when (and (not (eq (car tables) semanticdb-current-table))
+ (semanticdb-live-p (car tables))
+ (semanticdb-equivalent-mode (car tables))
+ )
+ (setq tokens (oref (car tables) tokens)
+ index (cons (cons semantic-imenu-directory-current-file
+ (or (and tokens
+ ;; don't pass nil stream because
+ ;; it will use the current
+ ;; buffer
+ (semantic-create-imenu-index-1
+ (oref (car tables) tokens)))
+ ;; no tokens in the file
+ 'file-only))
+ index)))
+ (setq tables (cdr tables)))
+ (working-dynamic-status))
+ (working-dynamic-status t))
+
+ ;; If enabled automatically rebuild other imenu directory
+ ;; indexes based on the same Semantic database
+ (or (not semantic-imenu-auto-rebuild-directory-indexes)
+ ;; If auto rebuild already in progress does nothing
+ semantic-imenu-auto-rebuild-running
+ (unwind-protect
+ (progn
+ (setq semantic-imenu-auto-rebuild-running t)
+ (semantic-imenu-rebuild-directory-indexes
+ semanticdb-current-database))
+ (setq semantic-imenu-auto-rebuild-running nil)))
+
+ (nreverse index))))
(defun semantic-create-imenu-index-1 (&optional stream)
"Create an imenu index for any buffer which supports Semantic.
@@ -144,7 +298,8 @@
(append index
;; do not create a menu separator in the parent menu
;; when creating a sub-menu
- (if (eq (semantic-token-token (car item)) 'type)
+ (if (eq (semantic-token-token (car item))
+ semantic-imenu-expandable-token)
(semantic-create-imenu-subindex item)
(cons
'("---")
@@ -159,47 +314,109 @@
item (cdr (car buckets)))
(semantic-create-imenu-subindex item))))
;; Else, group everything together
- (semantic-create-imenu-subindex tokens t))))
-
+ (semantic-create-imenu-subindex tokens))))
-(defun semantic-create-imenu-subindex (tokens &optional notypecheck)
- "From TOKENS, create an imenu index of interesting things.
-Optional argument NOTYPECHECK specifies not to make subgroups under types."
- (let (index token parts)
+(defun semantic-create-imenu-subindex (tokens)
+ "From TOKENS, create an imenu index of interesting things."
+ (let ((notypecheck (not semantic-imenu-expand-type-parts))
+ index token parts)
(while tokens
(setq token (car tokens))
(if (and (not notypecheck)
- (eq (semantic-token-token token) 'type))
+ (eq (semantic-token-token token)
+ semantic-imenu-expandable-token))
;; to keep an homogeneous menu organisation, type menu items
;; always have a sub-menu with at least the *typedef* item
;; (even if the token has no type parts)
- (setq parts (semantic-token-type-parts token)
- index (cons (cons
- (funcall semantic-imenu-summary-function token)
- ;; Add a menu for getting at the type definitions
- (cons (cons "*typedef*" (semantic-token-overlay token))
- (if parts
- (if (and semantic-imenu-bucketize-type-parts
- semantic-imenu-bucketize-file)
- (semantic-create-imenu-index-1 parts)
- (semantic-create-imenu-subindex
- (reverse parts))))))
- index))
+ (setq parts (semantic-nonterminal-children token)
+ index
+ (cons
+ (cons
+ (funcall semantic-imenu-summary-function token)
+ ;; Add a menu for getting at the type definitions
+ (if (and parts
+ ;; Note to self: enable menu items for sub parts
+ ;; even if they are not proper tokens.
+ (semantic-token-p (car parts)))
+ (cons (cons "*definition*"
+ (semantic-imenu-token-overlay token))
+ (if (and semantic-imenu-bucketize-type-parts
+ semantic-imenu-bucketize-file)
+ (semantic-create-imenu-index-1 parts)
+ (semantic-create-imenu-subindex parts)))
+ ;; There were no parts, or something like that, so
+ ;; instead just put the definition here.
+ (semantic-imenu-token-overlay token)
+ ))
+ index))
(setq index (cons (cons (funcall semantic-imenu-summary-function token)
- (semantic-token-overlay token))
+ (semantic-imenu-token-overlay token))
index)))
(setq tokens (cdr tokens)))
- ;; Imenu wasn't capturing this, so add the code from imenu.el
- ;; into this sub-sub section.
- (if imenu-sort-function
- (sort (let ((res nil)
- (oldlist index))
- ;; Copy list method from the cl package `copy-list'
- (while (consp oldlist) (push (pop oldlist) res))
- (if res ; in case, e.g. no functions defined
- (prog1 (nreverse res) (setcdr res oldlist))))
- imenu-sort-function)
- (nreverse index))))
+ (setq index
+ ;; Imenu wasn't capturing this, so add the code from imenu.el
+ ;; into this sub-sub section.
+ (if imenu-sort-function
+ (sort (let ((res nil)
+ (oldlist index))
+ ;; Copy list method from the cl package `copy-list'
+ (while (consp oldlist) (push (pop oldlist) res))
+ (if res ; in case, e.g. no functions defined
+ (prog1 (nreverse res) (setcdr res oldlist))))
+ imenu-sort-function)
+ (nreverse index)))
+ (if (> (length index) imenu-max-items)
+ (let ((count 0))
+ (setq index
+ (mapcar
+ (function
+ (lambda (menu)
+ (cons (format "From: %s" (caar menu)) menu)))
+ (imenu--split index imenu-max-items)))))
+ index))
+
+;;; directory imenu rebuilding.
+;;
+(defun semantic-imenu-rebuild-directory-indexes (db)
+ "Rebuild directory index imenus based on Semantic database DB."
+ (let ((l (buffer-list))
+ b)
+ (while l
+ (setq b (car l)
+ l (cdr l))
+ (if (and (not (eq b (current-buffer)))
+ (buffer-live-p b))
+ (with-current-buffer b
+ ;; If there is a buffer local Semantic index directory
+ ;; imenu
+ (when (and (eq imenu-create-index-function
+ 'semantic-create-imenu-index)
+ semanticdb-current-database
+ (eq semanticdb-current-database db))
+ (message "Building %s Semantic directory index imenu"
+ (buffer-name b))
+ ;; Rebuild the imenu
+ (imenu--cleanup)
+ (setq imenu--index-alist nil)
+ (funcall
+ (if (fboundp 'imenu-menu-filter)
+ ;; XEmacs imenu
+ 'imenu-menu-filter
+ ;; Emacs imenu
+ 'imenu-update-menubar))))))))
+
+(defun semantic-imenu-semanticdb-hook ()
+ "Function to be called from `semanticdb-mode-hooks'.
+Clears all imenu menus that may be depending on the database."
+ (semantic-map-buffers
+ #'(lambda ()
+ ;; Set up semanticdb environment if enabled.
+ (if (semanticdb-minor-mode-p)
+ (semanticdb-semantic-init-hook-fcn))
+ ;; Clear imenu cache to redraw the imenu.
+ (semantic-imenu-flush-fcn))))
+
+(add-hook 'semanticdb-mode-hooks 'semantic-imenu-semanticdb-hook)
;;; Interactive Utilities
;;
@@ -236,18 +453,24 @@
(defvar semantic-which-function 'semantic-default-which-function
"Function to convert semantic tokens into `which-function' text.")
+(defcustom semantic-which-function-use-color nil
+ "*Use color when displaying the current function with
`which-function'."
+ :group 'semantic-imenu
+ :type 'boolean)
+
(defun semantic-default-which-function (tokenlist)
- "Converts TOKENLIST into a string usable by `which-function'.
+ "Convert TOKENLIST into a string usable by `which-function'.
Returns the first token name in the list, unless it is a type,
in which case it concatenates them together."
(cond ((eq (length tokenlist) 1)
- (semantic-abbreviate-nonterminal (car tokenlist)))
- ((eq (semantic-token-token (car tokenlist)) 'type)
- (concat (semantic-token-name (car tokenlist)) "."
+ (semantic-abbreviate-nonterminal (car tokenlist) nil
semantic-which-function-use-color))
+ ((eq (semantic-token-token (car tokenlist))
+ semantic-imenu-expandable-token)
+ (concat (semantic-name-nonterminal (car tokenlist) semantic-which-function-use-color)
"."
;; recurse until we no longer have a type
;; or any tokens left.
(semantic-default-which-function (cdr tokenlist))))
- (t (semantic-abbreviate-nonterminal (car tokenlist)))))
+ (t (semantic-abbreviate-nonterminal (car tokenlist) nil
semantic-which-function-use-color))))
(defadvice which-function (around semantic-which activate)
"Choose the function to display via semantic if it is currently active."
Index: xemacs-packages/semantic/semantic-java.el
===================================================================
RCS file: semantic-java.el
diff -N semantic-java.el
--- /dev/null Tue Aug 14 14:29:33 2001
+++ semantic-java.el Tue Aug 14 22:28:18 2001
@@ -0,0 +1,930 @@
+;;; semantic-java.el --- Semantic details for Java
+
+;;; Copyright (C) 1999, 2000, 2001 David Ponce
+
+;; Author: David Ponce <david(a)dponce.com>
+;; X-RCS: $Id: semantic-java.el,v 1.18 2001/05/28 06:51:29 ponced Exp $
+
+;; This file is not part of GNU Emacs.
+
+;; semantic-java is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2, or (at
+;; your option) any later version.
+
+;; This software is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+;;
+;; Setup the Semantic Bovinator for Java. See also the grammar in
+;; java.bnf.
+
+;;; History:
+;;
+
+;;; Code:
+(require 'semantic)
+
+(eval-when-compile
+ (require 'semantic-ctxt)
+ (require 'semantic-imenu)
+ (require 'document)
+ (require 'senator))
+
+;; Generated parser table
+(defvar semantic-toplevel-java-bovine-table
+`((bovine-toplevel
+ ( package_declaration)
+ ( import_declaration)
+ ( type_declaration)
+ ) ; end bovine-toplevel
+ (number
+ ( symbol "[0-9]" punctuation "\\." symbol "[0-9Ee]"
punctuation "[-+]" symbol "[0-9fFdD]")
+ ( symbol "[0-9]" punctuation "\\." symbol "[0-9EefFdD]")
+ ( symbol "[0-9fFdD]")
+ ) ; end number
+ (literal
+ ( number)
+ ( qualified_name)
+ ( string)
+ ) ; end literal
+ (type
+ ( reference_type
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ( primitive_type
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ) ; end type
+ (primitive_type
+ ( BOOLEAN)
+ ( BYTE)
+ ( SHORT)
+ ( INT)
+ ( LONG)
+ ( CHAR)
+ ( FLOAT)
+ ( DOUBLE)
+ ) ; end primitive_type
+ (reference_type
+ ( array_type
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ( qualified_name
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ) ; end reference_type
+ (array_type
+ ( primitive_type dims
+ ,(semantic-lambda
+ (list ( concat ( car (nth 0 vals)) ( car (nth 1 vals))))))
+ ( qualified_name dims
+ ,(semantic-lambda
+ (list ( concat ( car (nth 0 vals)) ( car (nth 1 vals))))))
+ ) ; end array_type
+ (qualified_name
+ ( symbol punctuation "\\." qualified_name
+ ,(semantic-lambda
+ (list ( concat (nth 0 vals) (nth 1 vals) ( car (nth 2 vals))))))
+ ( symbol
+ ,(semantic-lambda
+ (list (nth 0 vals))))
+ ) ; end qualified_name
+ (package_declaration
+ ( PACKAGE qualified_name punctuation ";"
+ ,(semantic-lambda
+ (nth 1 vals) (list 'package nil nil)))
+ ) ; end package_declaration
+ (import_declaration
+ ( IMPORT qualified_name punctuation ";"
+ ,(semantic-lambda
+ (nth 1 vals) (list 'include nil nil)))
+ ( IMPORT qualified_name punctuation "\\." punctuation "*"
punctuation ";"
+ ,(semantic-lambda
+ (list ( concat ( car (nth 1 vals)) (nth 2 vals) (nth 3 vals)) 'include nil nil)))
+ ) ; end import_declaration
+ (type_declaration
+ ( punctuation ";")
+ ( class_declaration)
+ ( interface_declaration)
+ ) ; end type_declaration
+ (modifiers_opt
+ ( modifiers
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ()
+ ) ; end modifiers_opt
+ (modifiers
+ ( modifier modifiers
+ ,(semantic-lambda
+ ( cons ( car (nth 0 vals)) (nth 1 vals))))
+ ( modifier
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ) ; end modifiers
+ (modifier
+ ( PUBLIC)
+ ( PROTECTED)
+ ( PRIVATE)
+ ( STATIC)
+ ( ABSTRACT)
+ ( FINAL)
+ ( NATIVE)
+ ( SYNCHRONIZED)
+ ( TRANSIENT)
+ ( VOLATILE)
+ ( STRICTFP)
+ ) ; end modifier
+ (class_declaration
+ ( modifiers_opt CLASS qualified_name class_parents class_body
+ ,(semantic-lambda
+ (nth 2 vals) (list 'type "class" (nth 4 vals) (nth 3 vals) (
semantic-bovinate-make-assoc-list 'typemodifiers (nth 0 vals)) nil)))
+ ) ; end class_declaration
+ (class_parents
+ ( super interfaces
+ ,(semantic-lambda
+ ( append (nth 0 vals) (nth 1 vals))))
+ ( interfaces super
+ ,(semantic-lambda
+ ( append (nth 1 vals) (nth 0 vals))))
+ ( super
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ( interfaces
+ ,(semantic-lambda
+ ( cons nil (nth 0 vals))))
+ ()
+ ) ; end class_parents
+ (super
+ ( EXTENDS qualified_name
+ ,(semantic-lambda
+ (nth 1 vals)))
+ ) ; end super
+ (interfaces
+ ( IMPLEMENTS qualified_name_list
+ ,(semantic-lambda
+ (nth 1 vals)))
+ ) ; end interfaces
+ (qualified_name_list
+ ( qualified_name punctuation "," qualified_name_list
+ ,(semantic-lambda
+ ( cons ( car (nth 0 vals)) (nth 2 vals))))
+ ( qualified_name
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ) ; end qualified_name_list
+ (class_body
+ ( semantic-list
+ ,(semantic-lambda
+
+ (semantic-bovinate-from-nonterminal-full (car (nth 0 vals)) (cdr (nth 0 vals))
'class_body_declarations)
+ ))
+ ) ; end class_body
+ (class_body_declarations
+ ( class_declaration
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ( interface_declaration
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ( field_declaration
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ( method_declaration
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ( constructor_declaration
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ) ; end class_body_declarations
+ (field_declaration
+ ( modifiers_opt type variable_declarators punctuation ";"
+ ,(semantic-lambda
+ (nth 2 vals) (list 'variable) (nth 1 vals) (list nil (
semantic-bovinate-make-assoc-list 'typemodifiers (nth 0 vals)) nil)))
+ ) ; end field_declaration
+ (field_declaration_multi
+ ( modifiers_opt type variable_declarator punctuation ","
+ ,(semantic-lambda
+ (nth 2 vals)))
+ ( modifiers_opt type variable_declarator punctuation ";"
+ ,(semantic-lambda
+ (nth 2 vals)))
+ ( variable_declarator punctuation ","
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ( variable_declarator punctuation ";"
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ) ; end field_declaration_multi
+ (variable_declarators
+ ( variable_declarator variable_declarators_opt
+ ,(semantic-lambda
+ (list ( cons ( car (nth 0 vals)) ( car (nth 1 vals))))))
+ ) ; end variable_declarators
+ (variable_declarators_opt
+ ( punctuation "," variable_declarators
+ ,(semantic-lambda
+ (nth 1 vals)))
+ ()
+ ) ; end variable_declarators_opt
+ (variable_declarator
+ ( variable_declarator_id variable_assign_opt
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ) ; end variable_declarator
+ (variable_assign_opt
+ ( punctuation "=" variable_initializer)
+ ()
+ ) ; end variable_assign_opt
+ (variable_declarator_id
+ ( symbol dims
+ ,(semantic-lambda
+ (list ( concat (nth 0 vals) ( car (nth 1 vals))))))
+ ( symbol
+ ,(semantic-lambda
+ (list (nth 0 vals))))
+ ) ; end variable_declarator_id
+ (variable_initializer
+ ( array_initializer)
+ ( expression)
+ ) ; end variable_initializer
+ (method_declaration
+ ( method_header method_body
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ) ; end method_declaration
+ (method_header
+ ( modifiers_opt method_type symbol formal_parameter_list_opt throws_opt
+ ,(semantic-lambda
+ (list (nth 2 vals) 'function) (nth 1 vals) (list (nth 3 vals) (
semantic-bovinate-make-assoc-list 'typemodifiers (nth 0 vals) 'throws (nth 4
vals)) nil)))
+ ) ; end method_header
+ (method_type
+ ( VOID
+ ,(semantic-lambda
+ (list (nth 0 vals))))
+ ( type
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ) ; end method_type
+ (formal_parameter_list_opt
+ ( semantic-list
+ ,(semantic-lambda
+
+ (semantic-bovinate-from-nonterminal-full (car (nth 0 vals)) (cdr (nth 0 vals))
'formal_parameter_list)
+ ))
+ ()
+ ) ; end formal_parameter_list_opt
+ (formal_parameter_list
+ ( formal_parameter punctuation ","
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ( formal_parameter
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ) ; end formal_parameter_list
+ (formal_parameter-modifier
+ ( FINAL)
+ ()
+ ) ; end formal_parameter-modifier
+ (formal_parameter
+ ( formal_parameter-modifier type variable_declarator_id
+ ,(semantic-lambda
+ (nth 2 vals) (list 'variable) (nth 1 vals) (list nil (
semantic-bovinate-make-assoc-list 'typemodifiers (nth 0 vals)) nil)))
+ ) ; end formal_parameter
+ (throws_opt
+ ( throws
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ()
+ ) ; end throws_opt
+ (throws
+ ( THROWS qualified_name_list
+ ,(semantic-lambda
+ (nth 1 vals)))
+ ) ; end throws
+ (method_body
+ ( punctuation ";")
+ ( block)
+ ) ; end method_body
+ (constructor_declaration
+ ( modifiers_opt symbol formal_parameter_list_opt throws_opt constructor_body
+ ,(semantic-lambda
+ (list (nth 1 vals) 'function nil (nth 2 vals) ( semantic-bovinate-make-assoc-list
'typemodifiers (nth 0 vals) 'throws (nth 3 vals)) nil)))
+ ) ; end constructor_declaration
+ (constructor_body
+ ( block)
+ ) ; end constructor_body
+ (interface_declaration
+ ( modifiers_opt INTERFACE symbol interface_parents interface_body
+ ,(semantic-lambda
+ (list (nth 2 vals) 'type "interface" (nth 4 vals) (nth 3 vals) (
semantic-bovinate-make-assoc-list 'typemodifiers (nth 0 vals)) nil)))
+ ) ; end interface_declaration
+ (interface_parents
+ ( EXTENDS qualified_name_list
+ ,(semantic-lambda
+ (nth 1 vals)))
+ ()
+ ) ; end interface_parents
+ (interface_body
+ ( semantic-list
+ ,(semantic-lambda
+
+ (semantic-bovinate-from-nonterminal-full (car (nth 0 vals)) (cdr (nth 0 vals))
'interface_body_declarations)
+ ))
+ ) ; end interface_body
+ (interface_body_declarations
+ ( class_declaration
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ( interface_declaration
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ( method_header punctuation ";"
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ( field_declaration
+ ,(semantic-lambda
+ (nth 0 vals)))
+ ) ; end interface_body_declarations
+ (array_initializer
+ ( semantic-list "\\`{")
+ ) ; end array_initializer
+ (block
+ ( semantic-list "\\`{")
+ ) ; end block
+ (primary
+ ( array_creation_expression)
+ ( primary_no_new_array primary_dim_opt)
+ ) ; end primary
+ (primary_dim_opt
+ ( semantic-list "\\`\\[")
+ ()
+ ) ; end primary_dim_opt
+ (primary_no_new_array
+ ( qualified_name semantic-list "\\`(")
+ ( class_instance_creation_expression)
+ ( semantic-list "\\`(")
+ ( array_type punctuation "\\." CLASS)
+ ( literal)
+ ) ; end primary_no_new_array
+ (class_instance_creation_expression
+ ( NEW qualified_name semantic-list "\\`(" semantic-list "\\`{")
+ ( NEW qualified_name semantic-list "\\`(")
+ ) ; end class_instance_creation_expression
+ (array_creation_expression
+ ( NEW array_type array_initializer)
+ ( NEW array_type)
+ ) ; end array_creation_expression
+ (dims_opt
+ ( dims
+ ,(semantic-lambda
+ (nth 0 vals)))
+ (
+ ,(semantic-lambda
+ (list nil)))
+ ) ; end dims_opt
+ (dims
+ ( semantic-list "\\`\\[" dims_opt
+ ,(semantic-lambda
+ (list ( concat "[]" ( car (nth 1 vals))))))
+ ) ; end dims
+ (field_access
+ ( primary punctuation "\\." symbol)
+ ( qualified_name)
+ ) ; end field_access
+ (postfix_expression
+ ( primary postfix_operator_opt)
+ ) ; end postfix_expression
+ (postfix_operator_opt
+ ( punctuation "[-+]" punctuation "[-+]")
+ ()
+ ) ; end postfix_operator_opt
+ (unary_expression
+ ( punctuation "[-+^!]" unary_expression)
+ ( punctuation "[-+]" punctuation "[-+]" unary_expression)
+ ( semantic-list "\\`(" unary_expression)
+ ( postfix_expression)
+ ) ; end unary_expression
+ (operator
+ ( punctuation "[-+*/%=<>^~&|!?:.]")
+ ( INSTANCEOF)
+ ) ; end operator
+ (operators
+ ( operator operators)
+ ( operator)
+ ) ; end operators
+ (operators_expression_opt
+ ( operators expression)
+ ()
+ ) ; end operators_expression_opt
+ (expression
+ ( unary_expression operators_expression_opt)
+ ) ; end expression
+ )
+ "Java language specification.")
+
+;; Generated keyword table
+(defvar semantic-java-keyword-table
+ (semantic-flex-make-keyword-table
+ `( ("abstract" . ABSTRACT)
+ ("boolean" . BOOLEAN)
+ ("break" . BREAK)
+ ("byte" . BYTE)
+ ("case" . CASE)
+ ("catch" . CATCH)
+ ("char" . CHAR)
+ ("class" . CLASS)
+ ("const" . CONST)
+ ("continue" . CONTINUE)
+ ("default" . DEFAULT)
+ ("do" . DO)
+ ("double" . DOUBLE)
+ ("else" . ELSE)
+ ("extends" . EXTENDS)
+ ("final" . FINAL)
+ ("finally" . FINALLY)
+ ("float" . FLOAT)
+ ("for" . FOR)
+ ("goto" . GOTO)
+ ("if" . IF)
+ ("implements" . IMPLEMENTS)
+ ("import" . IMPORT)
+ ("instanceof" . INSTANCEOF)
+ ("int" . INT)
+ ("interface" . INTERFACE)
+ ("long" . LONG)
+ ("native" . NATIVE)
+ ("new" . NEW)
+ ("package" . PACKAGE)
+ ("private" . PRIVATE)
+ ("protected" . PROTECTED)
+ ("public" . PUBLIC)
+ ("return" . RETURN)
+ ("short" . SHORT)
+ ("static" . STATIC)
+ ("strictfp" . STRICTFP)
+ ("super" . SUPER)
+ ("switch" . SWITCH)
+ ("synchronized" . SYNCHRONIZED)
+ ("this" . THIS)
+ ("throw" . THROW)
+ ("throws" . THROWS)
+ ("transient" . TRANSIENT)
+ ("try" . TRY)
+ ("void" . VOID)
+ ("volatile" . VOLATILE)
+ ("while" . WHILE)
+ ("author" . AUTHOR)
+ ("version" . VERSION)
+ ("param" . PARAM)
+ ("exception" . EXCEPTION)
+ ("see" . SEE)
+ ("since" . SINCE)
+ ("serial" . SERIAL)
+ ("serialData" . SERIALDATA)
+ ("serialField" . SERIALFIELD)
+ ("deprecated" . DEPRECATED)
+ )
+ '(
+ ("abstract" summary "Class|Method declaration modifier: abstract
{class|<type>} <name> ...")
+ ("boolean" summary "Primitive logical quantity type (true or
false)")
+ ("break" summary "break [<label>] ;")
+ ("byte" summary "Integral primitive type (-128 to 127)")
+ ("case" summary "switch(<expr>) {case <const-expr>:
<stmts> ... }")
+ ("catch" summary "try {<stmts>} catch(<parm>)
{<stmts>} ... ")
+ ("char" summary "Integral primitive type ('\u0000' to
'\uffff') (0 to 65535)")
+ ("class" summary "Class declaration: class <name>")
+ ("const" summary "Unused reserved word")
+ ("continue" summary "continue [<label>] ;")
+ ("default" summary "switch(<expr>) { ... default:
<stmts>}")
+ ("do" summary "do <stmt> while (<expr>);")
+ ("double" summary "Primitive floating-point type (double-precision
64-bit IEEE 754)")
+ ("else" summary "if (<expr>) <stmt> else
<stmt>")
+ ("extends" summary "SuperClass|SuperInterfaces declaration: extends
<name> [, ...]")
+ ("final" summary "Class|Member declaration modifier: final
{class|<type>} <name> ...")
+ ("finally" summary "try {<stmts>} ... finally
{<stmts>}")
+ ("float" summary "Primitive floating-point type (single-precision
32-bit IEEE 754)")
+ ("for" summary "for ([<init-expr>]; [<expr>];
[<update-expr>]) <stmt>")
+ ("goto" summary "Unused reserved word")
+ ("if" summary "if (<expr>) <stmt> [else
<stmt>]")
+ ("implements" summary "Class SuperInterfaces declaration: implements
<name> [, ...]")
+ ("import" summary "Import package declarations: import
<package>")
+ ("int" summary "Integral primitive type (-2147483648 to
2147483647)")
+ ("interface" summary "Interface declaration: interface
<name>")
+ ("long" summary "Integral primitive type (-9223372036854775808 to
9223372036854775807)")
+ ("native" summary "Method declaration modifier: native <type>
<name> ...")
+ ("package" summary "Package declaration: package
<name>")
+ ("private" summary "Access level modifier: private
{class|interface|<type>} <name> ...")
+ ("protected" summary "Access level modifier: protected
{class|interface|<type>} <name> ...")
+ ("public" summary "Access level modifier: public
{class|interface|<type>} <name> ...")
+ ("return" summary "return [<expr>] ;")
+ ("short" summary "Integral primitive type (-32768 to 32767)")
+ ("static" summary "Declaration modifier: static
{class|interface|<type>} <name> ...")
+ ("strictfp" summary "Declaration modifier: strictfp
{class|interface|<type>} <name> ...")
+ ("switch" summary "switch(<expr>) {[case <const-expr>:
<stmts> ...] [default: <stmts>]}")
+ ("synchronized" summary "synchronized (<expr>) ... | Method
decl. modifier: synchronized <type> <name> ...")
+ ("throw" summary "throw <expr> ;")
+ ("throws" summary "Method|Constructor declaration: throws
<classType>, ...")
+ ("transient" summary "Field declaration modifier: transient
<type> <name> ...")
+ ("try" summary "try {<stmts>} [catch(<parm>)
{<stmts>} ...] [finally {<stmts>}]")
+ ("void" summary "Method return type: void <name> ...")
+ ("volatile" summary "Field declaration modifier: volatile
<type> <name> ...")
+ ("while" summary "while (<expr>) <stmt> | do <stmt>
while (<expr>);")
+ ("author" javadoc (seq 1 usage (type)))
+ ("version" javadoc (seq 2 usage (type)))
+ ("param" javadoc (seq 3 usage (function) with-name t))
+ ("return" javadoc (seq 4 usage (function)))
+ ("exception" javadoc (seq 5 usage (function) with-name t))
+ ("throws" javadoc (seq 6 usage (function) with-name t))
+ ("see" javadoc (seq 7 usage (type function variable) opt t with-ref t))
+ ("since" javadoc (seq 8 usage (type function variable) opt t))
+ ("serial" javadoc (seq 9 usage (variable) opt t))
+ ("serialData" javadoc (seq 10 usage (function) opt t))
+ ("serialField" javadoc (seq 11 usage (variable) opt t))
+ ("deprecated" javadoc (seq 12 usage (type function variable) opt t))
+ ))
+ "Java keywords.")
+
+;;;;
+;;;; Prototype handler
+;;;;
+
+(defun semantic-java-prototype-function (token &optional parent color)
+ "Return a function (method) prototype for TOKEN.
+Optional argument PARENT is a parent (containing) item.
+Optional argument COLOR indicates that color should be mixed in.
+See also `semantic-java-prototype-nonterminal'."
+ (let ((name (semantic-token-name token))
+ (type (semantic-token-type token))
+ (args (semantic-token-function-args token))
+ (argp "")
+ arg argt)
+ (while args
+ (setq arg (car args)
+ args (cdr args))
+ (if (semantic-token-p arg)
+ (setq argt (if color
+ (semantic-colorize-text
+ (semantic-token-type arg) 'type)
+ (semantic-token-type arg))
+ argp (concat argp argt (if args "," "")))))
+ (if color
+ (progn
+ (if type
+ (setq type (semantic-colorize-text type 'type)))
+ (setq name (semantic-colorize-text name 'function))))
+ (concat (or type "") (if type " " "") name
"(" argp ")")))
+
+(defun semantic-java-prototype-variable (token &optional parent color)
+ "Return a variable (field) prototype for TOKEN.
+Optional argument PARENT is a parent (containing) item.
+Optional argument COLOR indicates that color should be mixed in.
+See also `semantic-java-prototype-nonterminal'."
+ (concat (if color
+ (semantic-colorize-text
+ (semantic-token-type token) 'type)
+ (semantic-token-type token))
+ " "
+ (if color
+ (semantic-colorize-text
+ (semantic-token-name token) 'variable)
+ (semantic-token-name token))))
+
+(defun semantic-java-prototype-type (token &optional parent color)
+ "Return a type (class/interface) prototype for TOKEN.
+Optional argument PARENT is a parent (containing) item.
+Optional argument COLOR indicates that color should be mixed in.
+See also `semantic-java-prototype-nonterminal'."
+ (concat (semantic-token-type token)
+ " "
+ (if color
+ (semantic-colorize-text
+ (semantic-token-name token) 'type)
+ (semantic-token-name token))))
+
+(defun semantic-java-prototype-nonterminal (token &optional parent color)
+ "Return a prototype for TOKEN.
+Override `semantic-prototype-nonterminal'.
+Optional argument PARENT is a parent (containing) item.
+Optional argument COLOR indicates that color should be mixed in."
+ (let ((fprot (intern-soft
+ (format "semantic-java-prototype-%s"
+ (semantic-token-token token)))))
+ (if (fboundp fprot)
+ (funcall fprot token parent color)
+ (semantic-prototype-nonterminal-default token parent color))))
+
+;;;;
+;;;; Specific nonterminal handler
+;;;;
+
+(defun semantic-expand-java-nonterminal (token)
+ "Expand TOKEN into a list of equivalent nonterminals, or nil.
+Handle multiple variable declarations in the same statement."
+ (if (eq (semantic-token-token token) 'variable)
+ (let ((name (semantic-token-name token)))
+ (if (listp name)
+ (let ((multi (cdr name)))
+
+ ;; Always replace the list of variable names by the first
+ ;; name to get a valid token! There is nothing more to
+ ;; do if there is only one variable in the list.
+ (setcar token (car name))
+
+ (if multi
+ ;; There are multiple names in the same variable
+ ;; declaration.
+ (let ((ty (semantic-token-type token))
+ (dv (semantic-token-variable-default token))
+ (xs (semantic-token-variable-extra-specs token))
+ (ds (semantic-token-docstring token))
+ (pr (semantic-token-properties token))
+ ;; Reparse the declaration using the special
+ ;; nonterminal 'field_declaration_multi to get
+ ;; the START/END values of each variable.
+ (nl (semantic-bovinate-from-nonterminal-full
+ (semantic-token-start token)
+ (semantic-token-end token)
+ 'field_declaration_multi
+ 0))
+ tok vl)
+ ;; Merge in new 'variable tokens each reparsed
+ ;; token name and overlay with other values from
+ ;; the initial token.
+ (while nl
+ (setq tok (car nl)
+ nl (cdr nl)
+ vl (cons
+ (list
+ (semantic-token-name tok)
+ 'variable
+ ty ; type
+ dv ; default value
+ xs ; extra specs
+ ds ; docstring
+ pr ; properties
+ (semantic-token-overlay tok))
+ vl)))
+ (if vl
+ ;; Cleanup the no more needed initial token.
+ (semantic-deoverlay-token token))
+ vl)))))))
+
+;;;;
+;;;; Javadoc handler
+;;;;
+
+(defsubst semantic-java-skip-spaces-backward ()
+ "Move point backward, skipping Java whitespaces."
+ (skip-chars-backward " \n\r\t"))
+
+(defsubst semantic-java-skip-spaces-forward ()
+ "Move point forward, skipping Java whitespaces."
+ (skip-chars-forward " \n\r\t"))
+
+(defun semantic-java-find-documentation (&optional token nosnarf)
+ "Find documentation from TOKEN and return it as a clean string.
+Java have documentation set in a comment preceeding TOKEN's
+definition. Optional argument NOSNARF means to only return the flex
+token for it. If NOSNARF is 'flex, then only return the flex token.
+Override `semantic-find-documentation'."
+ (if (or token (setq token (semantic-current-nonterminal)))
+ (save-excursion
+ (set-buffer (semantic-token-buffer token))
+ ;; Move the point at token start
+ (goto-char (semantic-token-start token))
+ (semantic-java-skip-spaces-forward)
+ ;; If the point already at "/**" (this occurs after a doc fix)
+ (if (looking-at "/\\*\\*")
+ nil
+ ;; Skip previous spaces
+ (semantic-java-skip-spaces-backward)
+ ;; Ensure point is after "*/" (javadoc block comment end)
+ (condition-case nil
+ (backward-char 2)
+ (error nil))
+ (when (looking-at "\\*/")
+ ;; Move the point backward across the comment
+ (forward-char 2) ; return just after "*/"
+ (forward-comment -1) ; to skip the entire block
+ ))
+ ;; Verify the point is at "/**" (javadoc block comment start)
+ (if (looking-at "/\\*\\*")
+ (let ((p (point))
+ (c (semantic-find-doc-snarf-comment 'flex)))
+ (when c
+ ;; Verify that the token just following the doc
+ ;; comment is the current one!
+ (goto-char (semantic-flex-end c))
+ (semantic-java-skip-spaces-forward)
+ (when (eq token (semantic-current-nonterminal))
+ (goto-char p)
+ (semantic-find-doc-snarf-comment nosnarf))))))))
+
+;;;;
+;;;; Javadoc elements
+;;;;
+
+(defvar semantic-java-doc-line-tags nil
+ "Valid javadoc line tags.
+Ordered following Sun's Tag Convention at
+<http://java.sun.com/products/jdk/javadoc/writingdoccomments/index.html>")
+
+(defvar semantic-java-doc-with-name-tags nil
+ "Javadoc tags which have a name.")
+
+(defvar semantic-java-doc-with-ref-tags nil
+ "Javadoc tags which have a reference.")
+
+;; Optional javadoc tags by token category
+;;
+(defvar semantic-java-doc-extra-type-tags nil
+ "Optional tags used in class/interface documentation.
+Ordered following Sun's Tag Convention.")
+
+(defvar semantic-java-doc-extra-function-tags nil
+ "Optional tags used in method/constructor documentation.
+Ordered following Sun's Tag Convention.")
+
+(defvar semantic-java-doc-extra-variable-tags nil
+ "Optional tags used in field documentation.
+Ordered following Sun's Tag Convention.")
+
+;; All javadoc tags by token category
+;;
+(defvar semantic-java-doc-type-tags nil
+ "Tags allowed in class/interface documentation.
+Ordered following Sun's Tag Convention.")
+
+(defvar semantic-java-doc-function-tags nil
+ "Tags allowed in method/constructor documentation.
+Ordered following Sun's Tag Convention.")
+
+(defvar semantic-java-doc-variable-tags nil
+ "Tags allowed in field documentation.
+Ordered following Sun's Tag Convention.")
+
+(defun semantic-java-doc-keyword-before-p (k1 k2)
+ "Return non-nil if javadoc keyword K1 is before K2."
+ (let ((seq1 (and (semantic-flex-keyword-p k1)
+ (plist-get (semantic-flex-keyword-get k1 'javadoc)
+ 'seq)))
+ (seq2 (and (semantic-flex-keyword-p k2)
+ (plist-get (semantic-flex-keyword-get k2 'javadoc)
+ 'seq))))
+ (if (and (numberp seq1) (numberp seq2))
+ (<= seq1 seq2)
+ ;; Unknown tags (probably custom ones) are always after official
+ ;; ones and are not themselves ordered.
+ (or (numberp seq1)
+ (and (not seq1) (not seq2))))))
+
+(defun semantic-java-doc-keywords-map (fun &optional property)
+ "Run function FUN for each javadoc keyword.
+Return the list of FUN results. If optional PROPERTY is non nil only
+call FUN for javadoc keyword which have a value for PROPERTY. FUN
+receives two arguments: the javadoc keyword and its associated
+'javadoc property list. It can return any value. Nil values are
+removed from the result list."
+ (delq nil
+ (mapcar
+ #'(lambda (k)
+ (let ((plist (semantic-flex-keyword-get k 'javadoc)))
+ (if (or (not property) (plist-get plist property))
+ (funcall fun k plist))))
+ semantic-java-doc-line-tags)))
+
+(defun semantic-java-doc-setup ()
+ "Lazy initialization of javadoc elements."
+ (or semantic-java-doc-line-tags
+ (setq semantic-java-doc-line-tags
+ (sort (mapcar #'symbol-name
+ (semantic-flex-keywords 'javadoc))
+ #'semantic-java-doc-keyword-before-p)))
+
+ (or semantic-java-doc-with-name-tags
+ (setq semantic-java-doc-with-name-tags
+ (semantic-java-doc-keywords-map
+ #'(lambda (k p)
+ k)
+ 'with-name)))
+
+ (or semantic-java-doc-with-ref-tags
+ (setq semantic-java-doc-with-ref-tags
+ (semantic-java-doc-keywords-map
+ #'(lambda (k p)
+ k)
+ 'with-ref)))
+
+ (or semantic-java-doc-extra-type-tags
+ (setq semantic-java-doc-extra-type-tags
+ (semantic-java-doc-keywords-map
+ #'(lambda (k p)
+ (if (memq 'type (plist-get p 'usage))
+ k))
+ 'opt)))
+
+ (or semantic-java-doc-extra-function-tags
+ (setq semantic-java-doc-extra-function-tags
+ (semantic-java-doc-keywords-map
+ #'(lambda (k p)
+ (if (memq 'function (plist-get p 'usage))
+ k))
+ 'opt)))
+
+ (or semantic-java-doc-extra-variable-tags
+ (setq semantic-java-doc-extra-variable-tags
+ (semantic-java-doc-keywords-map
+ #'(lambda (k p)
+ (if (memq 'variable (plist-get p 'usage))
+ k))
+ 'opt)))
+
+ (or semantic-java-doc-type-tags
+ (setq semantic-java-doc-type-tags
+ (semantic-java-doc-keywords-map
+ #'(lambda (k p)
+ (if (memq 'type (plist-get p 'usage))
+ k)))))
+
+ (or semantic-java-doc-function-tags
+ (setq semantic-java-doc-function-tags
+ (semantic-java-doc-keywords-map
+ #'(lambda (k p)
+ (if (memq 'function (plist-get p 'usage))
+ k)))))
+
+ (or semantic-java-doc-variable-tags
+ (setq semantic-java-doc-variable-tags
+ (semantic-java-doc-keywords-map
+ #'(lambda (k p)
+ (if (memq 'variable (plist-get p 'usage))
+ k)))))
+
+ )
+
+;;;;
+;;;; Mode Hook
+;;;;
+
+(defun semantic-default-java-setup ()
+ "Set up a buffer for semantic parsing of the Java language."
+
+ ;; semantic overloaded functions
+ (semantic-install-function-overrides
+ '((prototype-nonterminal . semantic-java-prototype-nonterminal)
+ (find-documentation . semantic-java-find-documentation))
+ t ;; They can be changed in mode hook by more specific ones
+ )
+
+ ;; Code generated from java.bnf
+ (setq semantic-toplevel-bovine-table semantic-toplevel-java-bovine-table
+ semantic-toplevel-bovine-table-source "java.bnf")
+ (setq semantic-flex-keywords-obarray semantic-java-keyword-table)
+ (progn
+ (setq
+ ;; Java is case sensitive
+ semantic-case-fold nil
+ ;; special handling of multiple variable declarations/statement
+ semantic-expand-nonterminal 'semantic-expand-java-nonterminal
+ ;; function to use when creating items in imenu
+ semantic-imenu-summary-function 'semantic-prototype-nonterminal
+ ;; function to use for creating the imenu
+ imenu-create-index-function 'semantic-create-imenu-index
+ ;; Character used to separation a parent/child relationship
+ semantic-type-relation-separator-character '(".")
+ semantic-command-separation-character ";"
+ document-comment-start "/**"
+ document-comment-line-prefix " *"
+ document-comment-end " */"
+ ;; speedbar and imenu buckets name
+ semantic-symbol->name-assoc-list '((type . "Classes")
+ (variable . "Variables")
+ (function . "Methods")
+ (include . "Imports")
+ (package . "Package"))
+ ;; Semantic navigation inside 'type children
+ senator-step-at-token-ids '(function variable)
+ )
+ ;; Needed by `semantic-find-doc-snarf-comment'.
+ (set (make-local-variable 'block-comment-end) "\\s-*\\*/")
+ )
+
+ ;; End code generated from java.bnf
+
+ (semantic-java-doc-setup)
+ )
+
+(add-hook 'java-mode-hook 'semantic-default-java-setup)
+
+(provide 'semantic-java)
+
+;;; semantic-java.el ends here
Index: xemacs-packages/semantic/semantic-load.el
===================================================================
RCS file: semantic-load.el
diff -N semantic-load.el
--- /dev/null Tue Aug 14 14:29:33 2001
+++ semantic-load.el Tue Aug 14 22:28:18 2001
@@ -0,0 +1,84 @@
+;;; semantic-load.el --- Autoload definitions for Semantic
+
+;;; Copyright (C) 1999, 2000, 2001 Eric M. Ludlam
+
+;; Author: Eric M. Ludlam <zappo(a)gnu.org>
+;; X-RCS: $Id: semantic-load.el,v 1.5 2001/05/05 15:00:08 zappo Exp $
+
+;; Semantic is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This software is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+;;
+;; Initialize semantic for all supported conditions.
+
+;;; Code:
+
+(autoload 'semantic-bnf-mode "semantic-bnf" "Mode for Bovine Normal
Form." t)
+(add-to-list 'auto-mode-alist '("\\.bnf$" . semantic-bnf-mode))
+
+(autoload 'semantic-default-c-setup "semantic-c")
+(add-hook 'c-mode-hook 'semantic-default-c-setup)
+(add-hook 'c++-mode-hook 'semantic-default-c-setup)
+
+(autoload 'semantic-default-elisp-setup "semantic-el")
+(add-hook 'emacs-lisp-mode-hook 'semantic-default-elisp-setup)
+
+(autoload 'semantic-default-scheme-setup "semantic-scm")
+(add-hook 'scheme-mode-hook 'semantic-default-scheme-setup)
+
+(autoload 'semantic-default-make-setup "semantic-make")
+(add-hook 'makefile-mode-hook 'semantic-default-make-setup)
+
+(autoload 'semantic-default-texi-setup "semantic-texi")
+(add-hook 'texinfo-mode-hook 'semantic-default-texi-setup)
+
+(autoload 'semantic-default-java-setup "semantic-java")
+(add-hook 'java-mode-hook 'semantic-default-java-setup)
+
+(autoload 'senator-minor-mode "senator" nil t)
+
+(autoload 'global-semanticdb-minor-mode "semanticdb" nil t)
+(autoload 'semantic-show-dirty-mode "semantic-util" nil t)
+(autoload 'semantic-change-function-mark-dirty "semantic-util")
+
+;; This turns on semantic partial reparsing
+(add-hook 'semantic-change-hooks #'semantic-change-function-mark-dirty)
+
+(defvar semantic-load-turn-everything-on nil
+ "Non-nil means turn on all features in the semantic package.")
+
+(when semantic-load-turn-everything-on
+ (add-hook 'semantic-init-hooks (lambda ()
+ (senator-minor-mode 1)))
+ (add-hook 'semantic-init-hooks #'turn-on-eldoc-mode)
+ (if (fboundp #'which-func-mode)
+ (add-hook 'semantic-init-hooks (lambda ()
+ (which-func-mode 1))))
+
+ (when (and (eq window-system 'x)
+ (locate-library "imenu"))
+ (add-hook 'semantic-init-hooks (lambda ()
+ (imenu-add-to-menubar "TOKENS"))))
+
+ (semantic-show-dirty-mode 1)
+ (global-semanticdb-minor-mode 1)
+
+ (add-hook 'speedbar-load-hook (lambda () (require 'semantic-sb)))
+ )
+
+(provide 'semantic-load)
+
+;;; semantic-load.el ends here
Index: xemacs-packages/semantic/semantic-make.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/semantic/semantic-make.el,v
retrieving revision 1.4
diff -u -r1.4 semantic-make.el
--- xemacs-packages/semantic/semantic-make.el 2001/02/20 03:23:43 1.4
+++ xemacs-packages/semantic/semantic-make.el 2001/08/15 05:28:18
@@ -1,9 +1,9 @@
;;; semantic-make.el --- Makefile parsing rules.
-;; Copyright (C) 2000 Eric M. Ludlam
+;; Copyright (C) 2000, 2001 Eric M. Ludlam
;; Author: Eric M. Ludlam <zappo(a)gnu.org>
-;; X-RCS: $Id: semantic-make.el,v 1.4 2001/02/20 03:23:43 youngs Exp $
+;; X-RCS: $Id: semantic-make.el,v 1.8 2001/04/13 02:02:21 zappo Exp $
;; This file is not part of GNU Emacs.
@@ -32,72 +32,93 @@
;;; Code:
(defvar semantic-toplevel-make-bovine-table
- `((bovine-toplevel
- ( variable)
- ( rule)
- ( conditional)
- ) ; end Makefile
- (variable
- ( symbol equals elements
- ,(semantic-lambda
- (list (nth 0 vals) 'variable nil nil (nth 2 vals) nil nil)))
- ) ; end variable
- (rule
- ( symbol colons elements commands
- ,(semantic-lambda
- (list (nth 0 vals) 'function nil (nth 2 vals) nil nil)))
- ) ; end rule
- (conditional
- ( symbol "if" symbol newline
- ,(semantic-lambda
- (list nil)))
- ( symbol "else" newline
- ,(semantic-lambda
- (list nil)))
- ( symbol "endif" newline
- ,(semantic-lambda
- (list nil)))
- ) ; end conditional
- (equals
- ( punctuation ":" punctuation "="
- ,(semantic-lambda
- ))
- ( punctuation "+" punctuation "="
- ,(semantic-lambda
- ))
- ( punctuation "="
- ,(semantic-lambda
- ))
- ) ; end equals
- (colons
- ( punctuation ":" punctuation ":"
- ,(semantic-lambda
- ))
- ( punctuation ":"
- ,(semantic-lambda
- ))
- ) ; end colons
- (elements
- ( symbol elements
- ,(semantic-lambda
- (list (nth 0 vals)) (nth 1 vals)))
- ( symbol newline
- ,(semantic-lambda
- (list (nth 0 vals))))
- ( newline
- ,(semantic-lambda
- ))
- ) ; end elements
- (commands
- ( shell-command newline commands
- ,(semantic-lambda
- (list (nth 0 vals)) (nth 1 vals)))
- (
- ,(semantic-lambda
- ))
- ) ; end commands
- )
- "Table for parsing Makefiles.")
+`((bovine-toplevel
+ ( variable)
+ ( rule)
+ ( conditional)
+ ( include)
+ ) ; end Makefile
+ (variable
+ ( symbol equals elements
+ ,(semantic-lambda
+ (list (nth 0 vals) 'variable nil (nth 2 vals) nil nil)))
+ ) ; end variable
+ (rule
+ ( symbol colons elements commands
+ ,(semantic-lambda
+ (list (nth 0 vals) 'function nil (nth 2 vals) nil nil)))
+ ) ; end rule
+ (conditional
+ ( IF symbol newline
+ ,(semantic-lambda
+ ))
+ ( ELSE newline
+ ,(semantic-lambda
+ ))
+ ( ENDIF newline
+ ,(semantic-lambda
+ ))
+ ) ; end conditional
+ (include
+ ( INCLUDE symbol elements
+ ,(semantic-lambda
+ (list (nth 1 vals) 'include nil)))
+ ) ; end include
+ (equals
+ ( punctuation "\\b:\\b" punctuation "\\b=\\b"
+ ,(semantic-lambda
+ ))
+ ( punctuation "\\b\\+\\b" punctuation "\\b=\\b"
+ ,(semantic-lambda
+ ))
+ ( punctuation "\\b=\\b"
+ ,(semantic-lambda
+ ))
+ ) ; end equals
+ (colons
+ ( punctuation "\\b:\\b" punctuation "\\b:\\b"
+ ,(semantic-lambda
+ ))
+ ( punctuation "\\b:\\b"
+ ,(semantic-lambda
+ ))
+ ) ; end colons
+ (elements
+ ( symbol elements
+ ,(semantic-lambda
+ (list (nth 0 vals)) (nth 1 vals)))
+ ( symbol newline
+ ,(semantic-lambda
+ (list (nth 0 vals))))
+ ( newline
+ ,(semantic-lambda
+ ))
+ ) ; end elements
+ (commands
+ ( shell-command newline commands
+ ,(semantic-lambda
+ (list (nth 0 vals)) (nth 1 vals)))
+ (
+ ,(semantic-lambda
+ ))
+ ) ; end commands
+ )
+ "Table for parsing Makefiles.")
+
+(defvar semantic-make-keyword-table
+ (semantic-flex-make-keyword-table
+ `( ("if" . IF)
+ ("else" . ELSE)
+ ("endif" . ENDIF)
+ ("include" . INCLUDE)
+ )
+ '(
+ ("if" summary "Conditional: if (expression) ... else ...
endif")
+ ("else" summary "Conditional: if (expression) ... else ...
endif")
+ ("endif" summary "Conditional: if (expression) ... else ...
endif")
+ ("include" summary "Macro: include filename1 filename2 ...")
+ ))
+ "Keyword table for Makefiles.")
(defvar semantic-flex-make-extensions
'(("^\\(\t\\)" . semantic-flex-make-command)
@@ -122,7 +143,9 @@
"Set up a Makefile buffer for parsing with semantic."
(setq semantic-flex-extensions semantic-flex-make-extensions)
;; Code generated from make.bnf
- (setq semantic-toplevel-bovine-table semantic-toplevel-make-bovine-table)
+ (setq semantic-toplevel-bovine-table semantic-toplevel-make-bovine-table
+ semantic-toplevel-bovine-table-source "make.bnf")
+ (setq semantic-flex-keywords-obarray semantic-make-keyword-table)
(setq semantic-flex-enable-newlines t
semantic-symbol->name-assoc-list '((variable . "Variables")
(function . "Rules")
@@ -141,7 +164,7 @@
semantic-flex-enable-newlines t
imenu-create-index-function 'semantic-create-imenu-index
)
-
+
;; End code generated from make.bnf
)
Index: xemacs-packages/semantic/semantic-mode.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/semantic/semantic-mode.el,v
retrieving revision 1.3
diff -u -r1.3 semantic-mode.el
--- xemacs-packages/semantic/semantic-mode.el 2001/02/20 03:23:43 1.3
+++ xemacs-packages/semantic/semantic-mode.el 2001/08/15 05:28:18
@@ -1,264 +0,0 @@
-;;; semantic-mode.el --- Semantic minor mode
-
-;;; Copyright (C) 2000 Eric M. Ludlam
-
-;; Author: Eric M. Ludlam <zappo(a)gnu.org>
-;; Keywords: syntax
-;; X-RCS: $Id: semantic-mode.el,v 1.3 2001/02/20 03:23:43 youngs Exp $
-
-;; Semantic is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-
-;; This software is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
-
-;;; Commentary:
-;;
-;; Semantic-mode is a minor mode which provides services assuming that
-;; the current buffer is parsable by the bovinator.
-;;
-;; General features are:
-;; 1) Apply settings on the overlays that define the boundary of the tokens.
-;; 2) Provide some simple querying utilities via commands.
-;; 3) Semantic/Imenu configuration menu.
-;;
-
-(require 'semantic)
-(require 'imenu)
-(require 'facemenu)
-
-;;; Code:
-(defcustom semantic-minor-mode-hooks nil
- "*Hooks run when function `semantic-minor-mode' is run."
- :group 'semantic
- :type 'hook)
-
-(defface semantic-intangible-face '((((class color) (background light))
- (:foreground "gray25"))
- (((class color) (background light))
- (:foreground "gray75")))
- "Face placed on intangible text."
- :group 'semantic-faces)
-
-(defface semantic-read-only-face '((((class color) (background light))
- (:background "gray25"))
- (((class color) (background light))
- (:background "gray75")))
- "Face placed on read-only text."
- :group 'semantic-faces)
-
-(defvar semantic-minor-mode nil
- "Non-nil when a buffer is controlled by Semantic Minor Mode.")
-(make-variable-buffer-local 'semantic-minor-mode)
-
-(defvar semantic-mode-map
- (let ((km (make-sparse-keymap)))
- km)
- "Keymap used in semantic minor mode.")
-
-(if semantic-mode-map
- (easy-menu-define
- semantic-minor-menu semantic-mode-map "Semantic Minor Mode Menu"
- '("Parse"
- [ "Reparse If Needed" semantic-mode-parse t ]
- [ "Force Reparse" semantic-mode-reparse t ]
- "-" ;; Do stuff
- ("Token Properties"
- [ "Hide Token" semantic-mode-make-invisible t ]
- [ "Show Token" semantic-mode-make-visible t ]
- [ "Read Only Token" semantic-mode-toggle-read-only t ]
- [ "Intangible Token" semantic-mode-toggle-intangible t ]
- [ "Set Token Face" semantic-mode-set-face t ]
- [ "Set Token Foreground" semantic-mode-set-foreground t ]
- [ "Set Token Background" semantic-mode-set-background t ]
- [ "Remove all properties" semantic-mode-clear-token t ] )
- ("Imenu Config"
- ( "Token Sorting Function"
- [ "identity" semantic-imenu-set-sort-function
- :active t :style radio
- :selected (eq semantic-imenu-sort-bucket-function nil)]
- [ "semantic-sort-tokens-by-name-increasing"
- semantic-imenu-set-sort-function
- :active t :style radio
- :selected (eq semantic-imenu-sort-bucket-function
- 'semantic-sort-tokens-by-name-increasing)]
- [ "semantic-sort-tokens-by-name-decreasing"
- semantic-imenu-set-sort-function
- :active t :style radio
- :selected (eq semantic-imenu-sort-bucket-function
- 'semantic-sort-tokens-by-name-decreasing)]
- [ "semantic-sort-tokens-by-name-increasing-ci"
- semantic-imenu-set-sort-function
- :active t :style radio
- :selected (eq semantic-imenu-sort-bucket-function
- 'semantic-sort-tokens-by-name-increasing-ci)]
- [ "semantic-sort-tokens-by-name-decreasing-ci"
- semantic-imenu-set-sort-function
- :active t :style radio
- :selected (eq semantic-imenu-sort-bucket-function
- 'semantic-sort-tokens-by-name-decreasing-ci)]
- )
- [ "Bin tokens by type" semantic-imenu-toggle-bucketize-file
- :active t
- :style toggle :selected semantic-imenu-bucketize-file ]
- [ "Bins are submenus" semantic-imenu-toggle-buckets-to-submenu
- :active t
- :style toggle :selected semantic-imenu-buckets-to-submenu ]
- [ "Bin tokens in type" semantic-imenu-toggle-bucketize-type-parts
- :active t
- :style toggle :selected semantic-imenu-bucketize-type-parts ]
- )
- "-" ;; Token menu
- [ "Tokens" imenu t ]
- )))
-
-;; Allow re-insertion of a new keymap
-(let ((a (assoc 'semantic-minor-mode minor-mode-map-alist)))
- (if a
- (setcdr a semantic-mode-map)
- (add-to-list 'minor-mode-map-alist (cons 'semantic-minor-mode
- semantic-mode-map))))
-
-;;;###autoload
-(defun semantic-minor-mode (&optional arg)
- "Toggle semantic minor mode, a mode for tracking buffer parsing.
-With prefix ARG, turn semantic minor mode on iff ARG is positive.
-
-When in Semantic minor mode, the buffer will be parsed, and reparsed
-during editing in small chunks, during idle time.
-
-Semantic minor mode also allows modification of text properties on
-tokens, highlighting them, or making functions read only.
-
-\\<semantic-mode-map>
-\\{semantic-mode-map}"
- (interactive "P")
- (setq semantic-minor-mode
- (not (or (and (null arg) semantic-minor-mode)
- (<= (prefix-numeric-value arg) 0))))
- (if semantic-minor-mode
- ;; If turned on, do this:
- (progn
- (semantic-mode-parse)
-
- )
- ;; If turned off, do this:
-
- )
- (run-hooks 'semantic-minor-mode-hooks))
-
-
-;;; User Commands
-(defun semantic-mode-parse ()
- "Parse the current buffer only if it needs it."
- (interactive)
- (semantic-bovinate-toplevel t))
-
-(defun semantic-mode-reparse ()
- "Force a reparse of the current buffer."
- (interactive)
- (semantic-clear-toplevel-cache)
- (semantic-bovinate-toplevel t))
-
-(defun semantic-mode-make-visible (token)
- "Select an invisible TOKEN to be made visible."
- (interactive (list
- ;; Query for an invisible token to revisiblize
- "foo"))
- (error "Not implemented yet.")
- )
-
-;;; Property setting functions
-(defun semantic-mode-make-invisible (&optional token)
- "Make the current TOKEN invisible."
- (interactive)
- (error "This segvs Emacs 21, investigate")
- (semantic-set-token-invisible (or token (semantic-smallest-token))))
-
-(defun semantic-mode-toggle-read-only (&optional token)
- "Toggle the read-only status of the current TOKEN."
- (interactive)
- (let* ((tok (or token (semantic-smallest-token)))
- (o (semantic-token-overlay tok))
- (read (member 'semantic-overlay-signal-read-only
- (semantic-overlay-get o 'modification-hooks))))
- (semantic-set-token-read-only tok read)
- (semantic-mode-set-face
- (if read nil 'semantic-read-only-face))))
-
-(defun semantic-mode-toggle-intangible (&optional token)
- "Toggle the tangibility of the current TOKEN."
- (interactive)
- (let* ((tok (or token (semantic-smallest-token)))
- (tang (semantic-overlay-get (semantic-token-overlay tok) 'intangible)))
- (semantic-set-token-intangible tok tang)
- (semantic-mode-set-face
- (if tang nil 'semantic-intangible-face))))
-
-(defun semantic-mode-set-face (face &optional token)
- "Set the foreground FACE of the current TOKEN."
- (interactive (list (read-face-name "Face")))
- (semantic-set-token-face (or token (semantic-smallest-token)) face))
-
-(defun semantic-mode-set-foreground (color &optional token)
- "Set the foreground COLOR of the current TOKEN."
- ;; This was copied from facemenu
- (interactive (list (facemenu-read-color "Foreground color: ")))
- (let ((face (intern (concat "fg:" color))))
- (or (facemenu-get-face face)
- (error "Unknown color: %s" color))
- (semantic-mode-set-face face)))
-
-(defun semantic-mode-set-background (color &optional token)
- "Set the background COLOR of the current TOKEN."
- ;; This was copied from facemenu
- (interactive (list (facemenu-read-color "Background color: ")))
- (let ((face (intern (concat "bg:" color))))
- (or (facemenu-get-face face)
- (error "Unknown color: %s" color))
- (semantic-mode-set-face face)))
-
-(defun semantic-mode-clear-token (&optional token)
- "Clear all properties from TOKEN."
- (interactive)
- (semantic-set-token-face (or token (semantic-smallest-token)) nil))
-
-;;; Imenu menu function
-;;
-(defun semantic-imenu-set-sort-function ()
- "Set the sort bucket function."
- (interactive)
- ;; This is a hack for Emacs.
- (setq semantic-imenu-sort-bucket-function
- (cond ((eq last-input-event 'identity)
- nil)
- (t last-input-event))))
-
-;;; Utility functions
-;;
-(defun semantic-invisible-tokens ()
- "Return a list of tokens that are invisible."
- )
-
-(defun semantic-smallest-token (&optional point)
- "Return the smallest token part at POINT."
- (let ((ol (semantic-find-nonterminal-by-overlay (or point (point)))))
- (car ol)))
-
-(defun semantic-mode-toggle-token-property (token prop)
- "For TOKEN, return the opposite boolean value for PROP."
-)
-
-
-(provide 'semantic-mode)
-
-;;; semantic-mode.el ends here
Index: xemacs-packages/semantic/semantic-sb.el
===================================================================
RCS file: semantic-sb.el
diff -N semantic-sb.el
--- /dev/null Tue Aug 14 14:29:33 2001
+++ semantic-sb.el Tue Aug 14 22:28:18 2001
@@ -0,0 +1,357 @@
+;;; semantic-sb.el --- Semantic tag display for speedbar
+
+;;; Copyright (C) 1999, 2000, 2001 Eric M. Ludlam
+
+;; Author: Eric M. Ludlam <zappo(a)gnu.org>
+;; Version: 0.1
+;; Keywords: syntax
+;; X-RCS: $Id: semantic-sb.el,v 1.27 2001/01/31 15:59:06 zappo Exp $
+
+;; This file is not part of GNU Emacs.
+
+;; Semantic-sb is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This software is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+;;
+;; Convert a bovinated token list into speedbar buttons.
+
+;;; History:
+;;
+
+(require 'semantic)
+(require 'speedbar)
+
+(defcustom semantic-sb-autoexpand-length 1
+ "*Length of a semantic bucket to autoexpand in place.
+This will replace the named bucket that would have usually occured here."
+ :group 'speedbar
+ :type 'integer)
+
+;;; Code:
+
+;;; Button Generation
+;;
+;; Here are some button groups:
+;;
+;; +> Function ()
+;; @ return_type
+;; +( arg1
+;; +| arg2
+;; +) arg3
+;;
+;; +> Variable[1] =
+;; @ type
+;; = default value
+;;
+;; +> keywrd Type
+;; +> type part
+;;
+;; +> -> click to see additional information
+
+(defun semantic-sb-one-button (token depth &optional prefix)
+ "Insert TOKEN as a speedbar button at DEPTH.
+Optional PREFIX is used to specify special marker characters."
+ (let* ((type (semantic-token-token token))
+ (ttype (if (member type '(function variable type))
+ (semantic-token-type token)
+ nil))
+ (edata (cond ((eq type 'type)
+ (semantic-token-type-parts token))
+ ((eq type 'variable)
+ (semantic-token-variable-default token))
+ ((eq type 'function)
+ (semantic-token-function-args token))
+ ))
+ (start (point))
+ (end (progn
+ (insert (int-to-string depth) ":")
+ (point))))
+ (insert-char ? (1- depth) nil)
+ (put-text-property end (point) 'invisible nil)
+ ;; take care of edata = (nil) -- a yucky but hard to clean case
+ (if (and edata (listp edata) (and (<= (length edata) 1) (not (car edata))))
+ (setq edata nil))
+ ;; types are a bit unique. Variable types can have special meaning.
+ (cond ((eq type 'type)
+ (let ((name (semantic-token-name token)))
+ (if ttype
+ (setq name (concat ttype " " name)))
+ (if edata
+ (speedbar-insert-button (if prefix (concat " +" prefix) "
+>")
+ 'speedbar-button-face
+ 'speedbar-highlight-face
+ 'semantic-sb-show-extra
+ token t)
+ (speedbar-insert-button (if prefix (concat " " prefix) "
=>")
+ nil nil nil nil t))
+ (speedbar-insert-button name
+ 'speedbar-tag-face
+ 'speedbar-highlight-face
+ 'semantic-sb-token-jump
+ token t)))
+ (t
+ (if (or (and ttype (or (not (listp ttype)) (car ttype))) edata)
+ (speedbar-insert-button (if prefix (concat " +" prefix) "
+>")
+ 'speedbar-button-face
+ 'speedbar-highlight-face
+ 'semantic-sb-show-extra
+ token t)
+ (speedbar-insert-button (if prefix (concat " " prefix) "
=>")
+ nil nil nil nil t))
+ (speedbar-insert-button (semantic-token-name token)
+ 'speedbar-tag-face
+ 'speedbar-highlight-face
+ 'semantic-sb-token-jump
+ token t)
+ (cond ((eq type 'variable)
+ ;; Place array dims here if apropriate.
+ (if (semantic-token-variable-default token)
+ (speedbar-insert-button "=" nil nil nil nil t)))
+ ((eq type 'function)
+ (speedbar-insert-button "()" nil nil nil nil t))
+ ((and (eq type 'include)
+ (semantic-token-include-system token))
+ (speedbar-insert-button "<>" nil nil nil nil t))
+ )))
+ ;; This is very bizarre. When this was just after the insertion
+ ;; of the depth: text, the : would get erased, but only for the
+ ;; auto-expanded short- buckets. Move back for a later version
+ ;; version of Emacs 21 CVS
+ (put-text-property start end 'invisible t)
+ ))
+
+(defun semantic-sb-speedbar-data-line (depth button text &optional
+ text-fun text-data)
+ "Insert a semantic token data element.
+DEPTH is the current depth. BUTTON is the text for the button.
+TEXT is the actual info with TEXT-FUN to occur when it happens.
+Argument TEXT-DATA is the token data to pass to TEXT-FUN."
+ (let ((start (point))
+ (end (progn
+ (insert (int-to-string depth) ":")
+ (point))))
+ (put-text-property start end 'invisible t)
+ (insert-char ? depth nil)
+ (put-text-property end (point) 'invisible nil)
+ (speedbar-insert-button button nil nil nil nil t)
+ (speedbar-insert-button text
+ 'speedbar-tag-face
+ (if text-fun 'speedbar-highlight-face)
+ text-fun text-data t)
+ ))
+
+(defun semantic-sb-maybe-token-to-button (obj indent &optional
+ prefix modifiers)
+ "Convert OBJ, which was returned from the bovinator, into a button.
+This OBJ might be a plain string (simple type or untyped variable)
+or a complete bovinator type.
+Argument INDENT is the indentation used when making the button.
+Optional PREFIX is the character to use when marking the line.
+Optional MODIFIERS is additional text needed for variables."
+ (let ((myprefix (or prefix ">")))
+ (if (stringp obj)
+ (semantic-sb-speedbar-data-line indent myprefix obj)
+ (if (listp obj)
+ (progn
+ (if (and (stringp (car obj))
+ (= (length obj) 1))
+ (semantic-sb-speedbar-data-line indent myprefix
+ (concat
+ (car obj)
+ (or modifiers "")))
+ (semantic-sb-one-button obj indent prefix)))))))
+
+(defun semantic-sb-insert-details (token indent)
+ "Insert details about TOKEN at level INDENT."
+ (let ((tt (semantic-token-token token))
+ (type (semantic-token-type token)))
+ (cond ((eq tt 'type)
+ (let ((parts (semantic-token-type-parts token)))
+ ;; Lets expect PARTS to be a list of either strings,
+ ;; or variable tokens.
+ (while parts
+ (semantic-sb-maybe-token-to-button (car parts) indent)
+ (setq parts (cdr parts)))))
+ ((eq tt 'variable)
+ (if type
+ (let ((mods (semantic-token-variable-extra-spec token 'typemodifiers)))
+ (semantic-sb-maybe-token-to-button type indent "@" mods)))
+ ;; default value here
+ )
+ ((eq tt 'function)
+ (if type
+ (semantic-sb-speedbar-data-line
+ indent "@"
+ (if (stringp type) type
+ (semantic-token-name type))))
+ ;; Arguments to the function
+ (let ((args (semantic-token-function-args token)))
+ (if (and args (car args))
+ (progn
+ (semantic-sb-maybe-token-to-button (car args) indent "(")
+ (setq args (cdr args))
+ (while (> (length args) 1)
+ (semantic-sb-maybe-token-to-button (car args)
+ indent
+ "|")
+ (setq args (cdr args)))
+ (if args
+ (semantic-sb-maybe-token-to-button
+ (car args) indent ")"))
+ )))))
+ ))
+
+(defun semantic-sb-detail-parent ()
+ "Return the first parent token of the current like that includes a
location."
+ (save-excursion
+ (beginning-of-line)
+ (let ((dep (if (looking-at "[0-9]+:")
+ (1- (string-to-int (match-string 0)))
+ 0)))
+ (re-search-backward (concat "^"
+ (int-to-string dep)
+ ":")
+ nil t))
+ (beginning-of-line)
+ (if (looking-at "[0-9]+: +[-+][>()@|] \\([^\n]+\\)$")
+ (let ((prop nil))
+ (goto-char (match-beginning 1))
+ (setq prop (get-text-property (point) 'speedbar-token))
+ (if (numberp (semantic-token-start prop))
+ prop
+ (semantic-sb-detail-parent)))
+ nil)))
+
+(defun semantic-sb-show-extra (text token indent)
+ "Display additional information about the token as an expansion.
+TEXT TOKEN and INDENT are the details."
+ (cond ((string-match "+" text) ;we have to expand this file
+ (speedbar-change-expand-button-char ?-)
+ (speedbar-with-writable
+ (save-excursion
+ (end-of-line) (forward-char 1)
+ (save-restriction
+ (narrow-to-region (point) (point))
+ ;; Add in stuff specific to this type of token.
+ (semantic-sb-insert-details token (1+ indent))))))
+ ((string-match "-" text) ;we have to contract this node
+ (speedbar-change-expand-button-char ?+)
+ (speedbar-delete-subblock indent))
+ (t (error "Ooops... not sure what to do")))
+ (speedbar-center-buffer-smartly))
+
+(defun semantic-sb-token-jump (text token indent)
+ "Jump to the location specified in token.
+TEXT TOKEN and INDENT are the details."
+ (let ((file (speedbar-line-path indent))
+ (parent (semantic-sb-detail-parent)))
+ (speedbar-find-file-in-frame file)
+ (save-excursion (speedbar-stealthy-updates))
+ (semantic-find-nonterminal token parent)
+ ;; Reset the timer with a new timeout when cliking a file
+ ;; in case the user was navigating directories, we can cancel
+ ;; that other timer.
+ ;; (speedbar-set-timer dframe-update-speed)
+ ;;(recenter)
+ (speedbar-maybee-jump-to-attached-frame)
+ (run-hooks 'speedbar-visiting-tag-hook)))
+
+(defun semantic-sb-expand-group (text token indent)
+ "Expand a group which has semantic tokens.
+TEXT TOKEN and INDENT are the details."
+ (cond ((string-match "+" text) ;we have to expand this file
+ (speedbar-change-expand-button-char ?-)
+ (speedbar-with-writable
+ (save-excursion
+ (end-of-line) (forward-char 1)
+ (save-restriction
+ (narrow-to-region (point-min) (point))
+ (semantic-sb-buttons-plain (1+ indent) token)))))
+ ((string-match "-" text) ;we have to contract this node
+ (speedbar-change-expand-button-char ?+)
+ (speedbar-delete-subblock indent))
+ (t (error "Ooops... not sure what to do")))
+ (speedbar-center-buffer-smartly))
+
+(defun semantic-sb-buttons-plain (level tokens)
+ "Create buttons at LEVEL using TOKENS."
+ (let ((sordid (speedbar-create-tag-hierarchy tokens)))
+ (while sordid
+ (cond ((null (car-safe sordid)) nil)
+ ((consp (car-safe (cdr-safe (car-safe sordid))))
+ ;; A group!
+ (speedbar-make-tag-line 'curly ?+ 'semantic-sb-expand-group
+ (cdr (car sordid))
+ (car (car sordid))
+ nil nil 'speedbar-tag-face
+ level))
+ (t ;; Assume that this is a token.
+ (semantic-sb-one-button (car sordid) level)))
+ (setq sordid (cdr sordid)))))
+
+(defun semantic-insert-bovine-list (level lst)
+ "At LEVEL, insert the bovine parsed list LST.
+Use arcane knowledge about the semantic tokens in the tagged elements
+to create much wiser decisions about how to sort and group these items."
+ (semantic-sb-buttons level lst))
+
+(defun semantic-sb-buttons (level lst)
+ "Create buttons at LEVEL using LST sorting into type buckets."
+ (save-restriction
+ (narrow-to-region (point-min) (point))
+ (let (tmp)
+ (while lst
+ (setq tmp (car lst))
+ (if (cdr tmp)
+ (if (<= (length (cdr tmp)) semantic-sb-autoexpand-length)
+ (semantic-sb-buttons-plain (1+ level) (cdr tmp))
+ (speedbar-make-tag-line 'curly ?+ 'semantic-sb-expand-group
+ (cdr tmp)
+ (car (car lst))
+ nil nil 'speedbar-tag-face
+ (1+ level))))
+ (setq lst (cdr lst))))))
+
+(defun semantic-fetch-dynamic-bovine (file)
+ "Load FILE into a buffer, and generate tags using the Semantic Bovinator.
+Returns the tag list, or t for an error."
+ (let ((out (if (and (featurep 'semanticdb) (semanticdb-minor-mode-p)
+ (not speedbar-power-click))
+ ;; If the database is loaded and running, try to get
+ ;; tokens from it.
+ (or (semanticdb-file-stream file)
+ t)
+ ;; No database, do it the old way.
+ (save-excursion
+ (set-buffer (find-file-noselect file))
+ (if (or (not (featurep 'semantic))
+ (not semantic-toplevel-bovine-table))
+ t
+ (if speedbar-power-click (semantic-clear-toplevel-cache))
+ (semantic-bovinate-toplevel))))))
+ (if (listp out)
+ (condition-case nil
+ (semantic-bucketize out)
+ (error t))
+ t)))
+
+;; Link ourselves into the tagging process.
+(add-to-list 'speedbar-dynamic-tags-function-list
+ '(semantic-fetch-dynamic-bovine . semantic-insert-bovine-list))
+
+(provide 'semantic-sb)
+
+;;; semantic-sb.el ends here
Index: xemacs-packages/semantic/semantic-scm.el
===================================================================
RCS file: semantic-scm.el
diff -N semantic-scm.el
--- /dev/null Tue Aug 14 14:29:33 2001
+++ semantic-scm.el Tue Aug 14 22:28:18 2001
@@ -0,0 +1,169 @@
+;;; semantic-scm.el --- Semantic details for Scheme (guile)
+
+;;; Copyright (C) 2001 Eric M. Ludlam
+
+;; Author: Eric M. Ludlam <zappo(a)gnu.org>
+;; X-RCS: $Id: semantic-scm.el,v 1.5 2001/05/23 23:09:26 zappo Exp $
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This software is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+;;
+;; Use the Semantic Bovinator for Scheme (guile)
+
+(require 'semantic)
+(require 'backquote)
+
+(eval-when-compile
+ (require 'document))
+
+;;; Code:
+(defvar semantic-toplevel-scheme-bovine-table
+`((bovine-toplevel
+ ( semantic-list
+ ,(lambda (vals start end)
+
+ (semantic-bovinate-from-nonterminal (car (nth 0 vals)) (cdr (nth 0 vals))
'scheme-list)
+ ))
+ ) ; end scheme
+ (scheme-list
+ ( open-paren "(" scheme-in-list
+ ,(semantic-lambda
+ (nth 1 vals)))
+ ) ; end scheme-list
+ (scheme-in-list
+ ( DEFINE symbol expression
+ ,(semantic-lambda
+ (list (nth 1 vals) 'variable nil (nth 2 vals) nil)))
+ ( DEFINE name-args opt-doc
+ ,(semantic-lambda
+ (list ( car (nth 1 vals)) 'function ( cdr (nth 1 vals)) nil) (nth 2 vals)))
+ ( DEFINE-MODULE name-args
+ ,(semantic-lambda
+ (list ( nth ( length (nth 1 vals)) (nth 1 vals)) 'provide nil)))
+ ( LOAD string
+ ,(semantic-lambda
+ (list ( file-name-nondirectory ( read (nth 1 vals))) 'require ( read (nth 1
vals)))))
+ ( symbol
+ ,(semantic-lambda
+ (list (nth 0 vals) 'code)))
+ ) ; end scheme-in-list
+ (name-args
+ ( semantic-list
+ ,(lambda (vals start end)
+
+ (semantic-bovinate-from-nonterminal (car (nth 0 vals)) (cdr (nth 0 vals))
'name-arg-expand)
+ ))
+ ) ; end name-args
+ (name-arg-expand
+ ( open-paren name-arg-expand
+ ,(semantic-lambda
+ (nth 1 vals)))
+ ( symbol name-arg-expand
+ ,(semantic-lambda
+ ( cons (nth 0 vals) (nth 1 vals))))
+ (
+ ,(semantic-lambda
+ ))
+ ) ; end name-arg-expand
+ (opt-doc
+ ( string)
+ ()
+ ) ; end opt-doc
+ (expression
+ ( symbol)
+ ( semantic-list)
+ ( string)
+ ) ; end expression
+ )
+ "Top level bovination table for scheme.")
+
+(defvar semantic-scheme-keyword-table
+ (semantic-flex-make-keyword-table
+ `( ("define" . DEFINE)
+ ("define-module" . DEFINE-MODULE)
+ ("load" . LOAD)
+ )
+ '(
+ ("define" summary "Function: (define symbol expression)")
+ ("define-module" summary "Function: (define-module (name arg1 ...))
")
+ ("load" summary "Function: (load \"filename\")")
+ ))
+ "Some keywords used in scheme.")
+
+(defcustom semantic-default-scheme-path '("/usr/share/guile/")
+ "Default set of include paths for scheme (guile) code.
+Used by `semantic-inc' to define an include path. This should
+probably do some sort of search to see what is actually on the local
+machine."
+ :group 'scheme
+ :type '(repeat (string :tag "Path")))
+
+(defun semantic-scheme-prototype-nonterminal (token)
+ "Return a prototype for the Emacs Lisp nonterminal TOKEN."
+ (let* ((tok (semantic-token-token token))
+ (args (semantic-nonterminal-children token))
+ )
+ (if (eq tok 'function)
+ (concat (semantic-token-name token) " ("
+ (mapconcat (lambda (a) a) args " ")
+ ")")
+ (semantic-prototype-nonterminal-default token))))
+
+(defun semantic-scheme-find-documentation (token &optional nosnarf)
+ "Return the documentation string for TOKEN.
+Optional argument NOSNARF is ignored."
+ (let ((d (semantic-token-docstring token)))
+ (if (and d (> (length d) 0) (= (aref d 0) ?*))
+ (substring d 1)
+ d)))
+
+(defun semantic-scheme-insert-foreign-token (token tokenfile)
+ "Insert TOKEN from TOKENFILE at point.
+Attempts a simple prototype for calling or using TOKEN."
+ (cond ((eq (semantic-token-token token) 'function)
+ (insert "(" (semantic-token-name token) " )")
+ (forward-char -1))
+ (t
+ (insert (semantic-token-name token)))))
+
+(defun semantic-default-scheme-setup ()
+ "Setup hook function for Emacs Lisp files and Semantic."
+ ;; Code generated from scheme.bnf
+ (setq semantic-toplevel-bovine-table semantic-toplevel-scheme-bovine-table
+ semantic-toplevel-bovine-table-source "scheme.bnf")
+ (setq semantic-flex-keywords-obarray semantic-scheme-keyword-table)
+ (setq semantic-symbol->name-assoc-list '( (variable . "Variables")
+ ;;(type . "Types")
+ (function . "Functions")
+ (include . "Loads")
+ (package . "DefinModule"))
+ imenu-create-index-function 'semantic-create-imenu-index
+ semantic-dependency-include-path semantic-default-scheme-path
+ imenu-create-index-function 'semantic-create-imenu-index
+ document-comment-start ";;"
+ document-comment-line-prefix ";;"
+ document-comment-end "\n"
+ )
+
+ ;; End code generated from scheme.bnf
+ )
+
+(add-hook 'scheme-mode-hook 'semantic-default-scheme-setup)
+
+(provide 'semantic-scm)
+
+;;; semantic-scm.el ends here
Index: xemacs-packages/semantic/semantic-texi.el
===================================================================
RCS file: semantic-texi.el
diff -N semantic-texi.el
--- /dev/null Tue Aug 14 14:29:33 2001
+++ semantic-texi.el Tue Aug 14 22:28:19 2001
@@ -0,0 +1,380 @@
+;;; semantic-texi.el --- Semantic details for Texinfo files
+
+;;; Copyright (C) 2001 Eric M. Ludlam
+
+;; Author: Eric M. Ludlam <zappo(a)gnu.org>
+;; X-RCS: $Id: semantic-texi.el,v 1.5 2001/04/12 01:13:10 zappo Exp $
+
+;; This file is not part of GNU Emacs.
+
+;; This is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This software is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+;;
+;; Example using semantic's `semantic-toplevel-bovinate-override'
+;; using texinfo files.
+;;
+
+(require 'semantic)
+(require 'texinfo)
+
+(eval-when-compile
+ (require 'semanticdb)
+ (require 'semantic-ctxt)
+ (require 'semantic-imenu)
+ (require 'document)
+ (require 'senator))
+
+(defvar semantic-texi-super-regex
+ "^@\\(chapter\\|\\(sub\\)*section\\|unnumbered\\(\\(sub\\)*sec\\)?\\|\
+\\(chap\\|\\(sub\\)+\\|major\\)?heading\\|appendix\\(\\(sub\\)*sec\\)?\\|\
+centerchap\\|def\\(var\\|un\\|fn\\)x?\\)"
+ "Regular expression used to find special sections in a Texinfo file.")
+
+(defvar semantic-texi-name-field-list
+ '( ("defvar" . 1)
+ ("defvarx" . 1)
+ ("defun" . 1)
+ ("defunx" . 1)
+ ("deffn" . 2)
+ ("deffnx" . 2)
+ )
+ "List of definition commands, and the field position.
+The field position is the field number (based at 1) where the
+name of this section is.")
+
+;;; Code:
+(defun semantic-texi-bovinate-toplevel (checkcache)
+ "Parse the current texinfo buffer for bovine tokens.
+If CHECKCACHE is non-nil, then check to see if the cache needs
+to be flushed. (ignored)
+Each token returned is of the form:
+ (\"NAME\" section children DOC OVERLAY)
+or
+ (\"NAME\" def DOC OVERLAY)"
+ ;;(semantic-texi-bovinate-headings)
+ (mapcar 'semantic-texi-raw-to-cooked-token (semantic-texi-bovinate-headings))
+ )
+
+(defun semantic-texi-raw-to-cooked-token (token)
+ "Cook the texinfo token TOKEN."
+ (let ((chil (semantic-texi-nonterminal-children token)))
+ (if chil
+ (setcar (nthcdr 2 token)
+ (mapcar 'semantic-texi-raw-to-cooked-token chil)))
+ (car (semantic-raw-to-cooked-token token))))
+
+(defun semantic-texi-bovinate-headings ()
+ "Parse the current texinfo buffer for all bovine tokens now."
+ (let ((pass1 nil))
+ ;; First search and snarf.
+ (save-excursion
+ (goto-char (point-min))
+ (working-status-forms (file-name-nondirectory buffer-file-name) "done"
+ (while (re-search-forward semantic-texi-super-regex nil t)
+ (setq pass1 (cons (match-beginning 0) pass1))
+ (working-status)
+ )
+ (working-status t)))
+ (setq pass1 (nreverse pass1))
+ ;; Now, make some tokens while creating a set of children.
+ (car (semantic-texi-recursive-combobulate-list pass1 0))
+ ))
+
+(defun semantic-texi-recursive-combobulate-list (sectionlist level)
+ "Re-arrange SECTIONLIST to be a hierarchical token list starting at LEVEL.
+Return the re-arranged new list, with all remaining tokens from
+SECTIOLIST starting at ELT 2. Sections not are not dealt with as soon as a
+token with greater section value than LEVEL is found."
+ (let ((newl nil)
+ (oldl sectionlist)
+ tmp)
+ (save-excursion
+ (catch 'level-jump
+ (while oldl
+ (goto-char (car oldl))
+ (if (looking-at "@\\(\\w+\\)")
+ (let* ((word (match-string 1))
+ (levelmatch (assoc word texinfo-section-list))
+ text begin end tmp
+ )
+ ;; Get out of here if there if we made it that far.
+ (if (and levelmatch (<= (car (cdr levelmatch)) level))
+ (throw 'level-jump t))
+ (setq begin (point))
+ ;; Recombobulate
+ (if levelmatch
+ (progn
+ ;; When there is a match, the descriptive text
+ ;; consists of the rest of the line.
+ (goto-char (match-end 1))
+ (skip-chars-forward " \t")
+ (setq text (buffer-substring-no-properties
+ (point)
+ (progn (end-of-line) (point))))
+ ;; Next, recurse into the body to find the end.
+ (setq tmp (semantic-texi-recursive-combobulate-list
+ (cdr oldl) (car (cdr levelmatch))))
+ ;; Build a token
+ (setq newl (cons
+ (list text 'section (car tmp) nil begin (point))
+ newl))
+ ;; continue
+ (setq oldl (cdr tmp))
+ )
+ ;; No match means we have a def*, so get the name from
+ ;; it based on the type of thingy we found.
+ (setq levelmatch (assoc word semantic-texi-name-field-list)
+ tmp (or (cdr levelmatch) 1))
+ (forward-sexp tmp)
+ (skip-chars-forward " \t")
+ (setq text (buffer-substring-no-properties
+ (point)
+ (progn (forward-sexp 1) (point))))
+ ;; Seek the end of this definition
+ (goto-char begin)
+ (semantic-texi-forward-deffn)
+ (setq newl (cons
+ (list text 'def nil begin (point))
+ newl))
+ ;; continue
+ (setq oldl (cdr oldl)))
+ )
+ (error "Problem finding section in semantic/texi parser"))
+ ;; (setq oldl (cdr oldl))
+ )))
+ (cons (nreverse newl) oldl)))
+
+(defun semantic-texi-forward-deffn ()
+ "Move forward over one deffn type definition.
+The cursor should be on the @ sign."
+ (when (looking-at "@\\(\\w+\\)")
+ (let* ((type (match-string 1))
+ (seek (concat "^@end\\s-+" (regexp-quote type))))
+ (re-search-forward seek nil t))))
+
+(defun semantic-texi-nonterminal-children (nonterm)
+ "Return children belonging to NONTERM."
+ (if (eq (semantic-token-token nonterm) 'section)
+ (nth 2 nonterm)
+ nil))
+
+(defun semantic-texi-insert-foreign-token (token tokenfile)
+ "Insert TOKEN from a foreign buffer in TOKENFILE.
+Assume TOKENFILE is a source buffer, and create a documentation
+thingy from it using the `document' tool."
+ ;; This makes sure that TOKEN will be in an active buffer.
+ (let ((b (find-file-noselect tokenfile)))
+ ;; Now call the document insert thingy.
+ (require 'document)
+ (document-insert-texinfo token b)))
+
+(defun semantic-default-texi-setup ()
+ "Set up a buffer for parsing of Texinfo files."
+ ;; This will use our parser.
+ (setq semantic-bovinate-toplevel-override #'semantic-texi-bovinate-toplevel
+ imenu-create-index-function 'semantic-create-imenu-index
+ semantic-command-separation-character "@"
+ semantic-type-relation-separator-character '(":")
+ semantic-symbol->name-assoc-list '((section . "Section")
+ (def . "Definition")
+ )
+ semantic-imenu-expandable-token 'section
+ semantic-imenu-bucketize-file nil
+ semantic-imenu-bucketize-type-parts nil
+ senator-step-at-start-end-token-ids '(section)
+ )
+ (semantic-install-function-overrides
+ '((nonterminal-children . semantic-texi-nonterminal-children)
+ (insert-foreign-token . semantic-texi-insert-foreign-token)
+ )
+ t)
+ )
+
+(add-hook 'texinfo-mode-hook 'semantic-default-texi-setup)
+
+
+;;; Special features of Texinfo token streams
+;;
+;; This section provides specialized access into texinfo files.
+;; Because texinfo files often directly refer to functions and programs
+;; it is useful to access the texinfo file from the C code for document
+;; maintainance.
+(defun semantic-texi-associated-files (&optional buffer)
+ "Find texinfo files associated with BUFFER."
+ (save-excursion
+ (if buffer (set-buffer buffer))
+ (cond ((and (fboundp 'ede-documentation-files) ede-minor-mode
(ede-current-project))
+ ;; When EDE is active, ask it.
+ (ede-documentation-files)
+ )
+ ((and (featurep 'semanticdb) (semanticdb-minor-mode-p))
+ ;; See what texinfo files we have loaded in the database
+ (let ((tabs (oref semanticdb-current-database tables))
+ (r nil))
+ (while tabs
+ (if (eq (oref (car tabs) major-mode) 'texinfo-mode)
+ (setq r (cons (oref (car tabs) file) r)))
+ (setq tabs (cdr tabs)))
+ r))
+ (t
+ (directory-files default-directory nil "\\.texi$"))
+ )))
+
+;; Turns out this might not be useful.
+;; Delete later if that is true.
+(defun semantic-texi-find-documentation (name &optional type)
+ "Find the function or variable NAME of TYPE in the texinfo source.
+NAME is a string representing some functional symbol.
+TYPE is a string, such as \"variable\" or \"Command\" used to find
+the correct definition in case NAME qualifies as several things.
+When this function exists, POINT is at the definition.
+If the doc was not found, an error is thrown.
+Note: TYPE not yet implemented."
+ (let ((f (semantic-texi-associated-files))
+ stream
+ match)
+ (while (and f (not match))
+ (when (not stream)
+ (save-excursion
+ (set-buffer (find-file-noselect (car f)))
+ (setq stream (semantic-bovinate-toplevel t))))
+ (setq match (semantic-find-nonterminal-by-name name stream t nil))
+ (when match
+ (set-buffer (semantic-token-buffer match))
+ (goto-char (semantic-token-start match)))
+ (setq f (cdr f)))))
+
+(defun semantic-texi-update-doc-from-texi (&optional token)
+ "Update the documentation in the texinfo deffn class token TOKEN.
+The current buffer must be a texinfo file containing TOKEN.
+If TOKEN is nil, determine a token based on the current position."
+ (interactive)
+ (if (not (or (featurep 'semanticdb) (semanticdb-minor-mode-p)))
+ (error "Texinfo updating only works when `semanticdb' is being
used"))
+ (semantic-bovinate-toplevel t)
+ (when (not token)
+ (beginning-of-line)
+ (setq token (semantic-current-nonterminal)))
+ (if (not (eq (semantic-token-token token) 'def))
+ (error "Only deffns (or defun or defvar) can be updated"))
+ (let* ((name (semantic-token-name token))
+ (toks (mapcar
+ #'cdr
+ ;; `semanticdb-find-nonterminal-by-name' returns a
+ ;; list ((DB-TABLE . TOKEN) ...)
+ (semanticdb-find-nonterminal-by-name name nil t nil t t)))
+ (docstring nil)
+ (doctok nil))
+ (save-excursion
+ (while (and toks (not docstring))
+ (set-buffer (semantic-token-buffer (car toks)))
+ (when (not (eq major-mode 'texinfo-mode))
+ (setq docstring (semantic-find-documentation (car toks))
+ doctok (if docstring (car toks) nil)))
+ (setq toks (cdr toks))))
+ (if (not docstring)
+ (error "Could not find documentation for %s" (semantic-token-name token)))
+ ;; If we have a string, do the replacement.
+ (delete-region (semantic-token-start token)
+ (semantic-token-end token))
+ ;; Use useful functions from the document library.
+ (require 'document)
+ (document-insert-texinfo doctok (semantic-token-buffer doctok))
+ ))
+
+(defun semantic-texi-update-doc-from-source (&optional token)
+ "Update the documentation for the source TOKEN.
+The current buffer must be a non-texinfo source file containing TOKEN.
+If TOKEN is nil, determine the token based on the current position.
+The current buffer must include TOKEN."
+ (interactive)
+ (if (eq major-mode 'texinfo-mode)
+ (error "Not a source file"))
+ (semantic-bovinate-toplevel t)
+ (when (not token)
+ (setq token (semantic-current-nonterminal)))
+ (when (not (semantic-find-documentation token))
+ (error "Cannot find interesting documentation to use for %s"
+ (semantic-token-name token)))
+ (let* ((name (semantic-token-name token))
+ (texi (semantic-texi-associated-files))
+ (doctok nil)
+ (docbuff nil))
+ (while (and texi (not doctok))
+ (set-buffer (find-file-noselect (car texi)))
+ (setq doctok (semantic-find-nonterminal-by-name
+ name (semantic-bovinate-toplevel t) t nil)
+ docbuff (if doctok (current-buffer) nil))
+ (setq texi (cdr texi)))
+ (if (not doctok)
+ (error "Token %s is not yet documented. Use the `document' command"))
+ ;; Ok, we should have everything we need. Do the deed.
+ (if (get-buffer-window docbuff)
+ (set-buffer docbuff)
+ (switch-to-buffer docbuff))
+ (goto-char (semantic-token-start doctok))
+ (delete-region (semantic-token-start doctok)
+ (semantic-token-end doctok))
+ ;; Use useful functions from the document library.
+ (require 'document)
+ (document-insert-texinfo token (semantic-token-buffer token))
+ ))
+
+(defun semantic-texi-update-doc (&optional token)
+ "Update the documentation for TOKEN.
+If the current buffer is a texinfo file, then find the source doc, and
+update it. If the current buffer is a source file, then get the
+documentation for this item, find the existing doc in the associated
+manual, and update that."
+ (interactive)
+ (cond ((eq major-mode 'texinfo-mode)
+ (semantic-texi-update-doc-from-texi token))
+ (t
+ (semantic-texi-update-doc-from-source token))))
+
+(defun semantic-texi-goto-source (&optional token)
+ "Jump to the source for the definition in the texinfo file TOKEN.
+If TOKEN is nil, it is derived from the deffn under POINT."
+ (interactive)
+ (if (not (or (featurep 'semanticdb) (semanticdb-minor-mode-p)))
+ (error "Texinfo updating only works when `semanticdb' is being
used"))
+ (semantic-bovinate-toplevel t)
+ (when (not token)
+ (beginning-of-line)
+ (setq token (semantic-current-nonterminal)))
+ (if (not (eq (semantic-token-token token) 'def))
+ (error "Only deffns (or defun or defvar) can be updated"))
+ (let* ((name (semantic-token-name token))
+ (toks (mapcar
+ #'cdr
+ ;; `semanticdb-find-nonterminal-by-name' returns a
+ ;; list ((DB-TABLE . TOKEN) ...)
+ (semanticdb-find-nonterminal-by-name name nil t nil t t)))
+ (done nil)
+ )
+ (save-excursion
+ (while (and toks (not done))
+ (set-buffer (semantic-token-buffer (car toks)))
+ (when (not (eq major-mode 'texinfo-mode))
+ (switch-to-buffer (semantic-token-buffer (car toks)))
+ (goto-char (semantic-token-start (car toks)))
+ (setq done t))
+ (setq toks (cdr toks))))))
+
+(provide 'semantic-texi)
+
+;;; semantic-texi.el ends here
Index: xemacs-packages/semantic/semantic-util.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/semantic/semantic-util.el,v
retrieving revision 1.6
diff -u -r1.6 semantic-util.el
--- xemacs-packages/semantic/semantic-util.el 2001/02/20 03:23:44 1.6
+++ xemacs-packages/semantic/semantic-util.el 2001/08/15 05:28:20
@@ -4,7 +4,7 @@
;; Author: Eric M. Ludlam <zappo(a)gnu.org>
;; Keywords: syntax
-;; X-RCS: $Id: semantic-util.el,v 1.6 2001/02/20 03:23:44 youngs Exp $
+;; X-RCS: $Id: semantic-util.el,v 1.68 2001/07/13 16:12:41 zappo Exp $
;; This file is not part of GNU Emacs.
@@ -29,57 +29,32 @@
;; Semantic Bovinator.
;;
+(require 'assoc)
+(require 'semantic)
;;; Code:
-;;; Simple APIs
-;;
-;; These macros extract parts from the default token types as
-;; described by `semantic-toplevel-bovine-table'
-
-;; Check semantic.el for the other token information extraction functions.
-
-(defmacro semantic-token-token (token)
- "Retrieve from TOKEN the token identifier.
-ie, the symbol 'variable, 'function, 'type, or other."
- `(nth 1 ,token))
-
-(defun semantic-token-name (token)
- "Retrieve the name of TOKEN."
- (car token))
-
-(defun semantic-token-docstring (token &optional buffer)
- "Retrieve the documentation of TOKEN.
-Optional argument BUFFER indicates where to get the text from.
-If not provided, then only the POSITION can be provided."
- (let ((p (nth (- (length token) 2) token)))
- (if (and p buffer)
- (save-excursion
- (set-buffer buffer)
- (semantic-flex-text (car (semantic-flex p (1+ p)))))
- p)))
+(defvar semantic-type-relation-separator-character '(".")
+ "Character strings used to separation a parent/child relationship.
+This list of strings are used for displaying or finding separators
+in variable field dereferencing. The first character will be used for
+display. In C, a type field is separated like this: \"type.field\"
+thus, the character is a \".\". In C, and additional value of
\"->\"
+would be in the list, so that \"type->field\" could be found.")
+(make-variable-buffer-local 'semantic-type-relation-separator-character)
+
+(defvar semantic-equivalent-major-modes nil
+ "List of major modes which are considered equivalent.
+Equivalent modes share a parser, and a set of override methods.
+Setup from the BNF code generator. A value of nil means that
+the current major mode is the only one.")
+(make-variable-buffer-local 'semantic-equivalent-major-modes)
-(defmacro semantic-token-overlay (token)
- "Retrieve the OVERLAY part of TOKEN."
- `(nth (- (length ,token) 1) ,token))
-
-(defmacro semantic-token-extent (token)
- "Retrieve the extent (START END) of TOKEN."
- `(let ((over (semantic-token-overlay ,token)))
- (list (semantic-overlay-start over) (semantic-overlay-end over))))
-
-(defmacro semantic-token-start (token)
- "Retrieve the start location of TOKEN."
- `(semantic-overlay-start (semantic-token-overlay ,token)))
-
-(defmacro semantic-token-end (token)
- "Retrieve the end location of TOKEN."
- `(semantic-overlay-end (semantic-token-overlay ,token)))
-
-(defmacro semantic-token-buffer (token)
- "Retrieve the buffer TOKEN resides in."
- `(semantic-overlay-buffer (semantic-token-overlay ,token)))
-
+;;; Utility API functions
+;;
+;; These functions use the flex and bovination engines to perform some
+;; simple tasks useful to other programs. These are just the most
+;; critical entries.
(defun semantic-token-type (token)
"Retrieve the type of TOKEN."
(if (member (semantic-token-token token)
@@ -91,77 +66,163 @@
`(nth 3 ,token))
(defmacro semantic-token-type-parent (token)
- "Retrieve the parent of the type TOKEN."
+ "Retrieve the parent of the type TOKEN.
+The return value is a list. A value of nil means no parents.
+The `car' of the list is either the parent class, or a list
+of parent classes. The `cdr' of the list is the list of
+interfaces, or abstract classes which are parents of TOKEN."
`(nth 4 ,token))
-(defmacro semantic-token-type-modifiers (token)
- "Retrieve the non-type modifiers of the type TOKEN."
+(defun semantic-token-type-parent-superclass (token)
+ "Retrieve the parent superclasses of type type TOKEN."
+ (let ((p (semantic-token-type-parent token)))
+ (cond ((stringp (car p))
+ (list (car p)))
+ ((listp (car p))
+ (car p)))))
+
+(defun semantic-token-type-parent-implement (token)
+ "Retrieve the parent interfaces of type type TOKEN."
+ (cdr (semantic-token-type-parent token)))
+
+(defmacro semantic-token-type-extra-specs (token)
+ "Retrieve extra specifications for the type TOKEN."
`(nth 5 ,token))
+(defmacro semantic-token-type-extra-spec (token spec)
+ "Retrieve an extra specification for the type TOKEN.
+SPEC is the symbol whose specification value to get."
+ `(cdr (assoc ,spec (semantic-token-type-extra-specs ,token))))
+
+(defmacro semantic-token-type-modifiers (token)
+ "Retrieve modifiers for the type TOKEN."
+ `(semantic-token-type-extra-spec ,token 'typemodifiers))
+
(defmacro semantic-token-function-args (token)
"Retrieve the arguments of the function TOKEN."
`(nth 3 ,token))
-(defmacro semantic-token-function-modifiers (token)
- "Retrieve non-type modifiers for the function TOKEN."
+(defmacro semantic-token-function-extra-specs (token)
+ "Retrieve extra specifications for the function TOKEN."
`(nth 4 ,token))
+(defmacro semantic-token-function-extra-spec (token spec)
+ "Retrieve an extra specification for the function TOKEN.
+SPEC is the symbol whose specification value to get."
+ `(cdr (assoc ,spec (semantic-token-function-extra-specs ,token))))
+
+(defmacro semantic-token-function-modifiers (token)
+ "Retrieve modifiers for the function TOKEN."
+ `(semantic-token-function-extra-spec ,token 'typemodifiers))
+
(defmacro semantic-token-function-throws (token)
- "Optional details if this function has a THROWS type.
+ "The symbol string that a function can throws.
Determines if it is available based on the length of TOKEN."
- `(if (>= (length ,token) (+ 6 2))
- (nth 5 ,token)
- nil))
+ `(semantic-token-function-extra-spec ,token 'throws))
-(defmacro semantic-token-variable-const (token)
- "Retrieve the status of constantness from the variable TOKEN."
- `(nth 3 ,token))
+(defmacro semantic-token-function-parent (token)
+ "The parent of the function TOKEN.
+A function has a parent if it is a method of a class, and if the
+function does not appear in body of it's parent class."
+ `(semantic-token-function-extra-spec ,token 'parent))
(defmacro semantic-token-variable-default (token)
"Retrieve the default value of the variable TOKEN."
+ `(nth 3 ,token))
+
+(defmacro semantic-token-variable-extra-specs (token)
+ "Retrieve extra specifications for the variable TOKEN."
`(nth 4 ,token))
+(defmacro semantic-token-variable-extra-spec (token spec)
+ "Retrieve an extra specification for the variable TOKEN.
+SPEC is the symbol whose specification value to get."
+ `(cdr (assoc ,spec (semantic-token-variable-extra-specs ,token))))
+
(defmacro semantic-token-variable-modifiers (token)
- "Retrieve non-type modifiers for the variable TOKEN."
- `(nth 5 ,token))
+ "Retrieve modifiers for the variable TOKEN."
+ `(semantic-token-variable-extra-spec ,token 'typemodifiers))
+(defmacro semantic-token-variable-const (token)
+ "Retrieve the status of constantness from the variable TOKEN."
+ `(semantic-token-variable-extra-spec ,token 'const))
+
(defmacro semantic-token-variable-optsuffix (token)
"Optional details if this variable has bit fields, or array dimentions.
Determines if it is available based on the length of TOKEN."
- `(if (>= (length ,token) (+ 7 2))
- (nth 6 ,token)
- nil))
+ `(semantic-token-variable-extra-spec ,token 'suffix))
(defmacro semantic-token-include-system (token)
- "Retrieve the flag indicating if the include TOKEN is a sysmtem include."
+ "Retrieve the flag indicating if the include TOKEN is a system include."
`(nth 2 ,token))
-;;; Searching APIs
+(defun semantic-token-extra-spec (token spec)
+ "Retrieve an extra specification for TOKEN.
+SPEC is a symbol whose specification value to get.
+This function can get extra specifications from any type of token.
+Do not use the function if you know what type of token you are dereferencing.
+Instead, use `semantic-token-variable-extra-spec',
+`semantic-token-function-extra-spec', or
`semantic-token-type-extra-spec'."
+ (let ((tt (semantic-token-token token)))
+ (cond ((eq tt 'variable)
+ (semantic-token-variable-extra-spec token spec))
+ ((eq tt 'function)
+ (semantic-token-function-extra-spec token spec))
+ ((eq tt 'type)
+ (semantic-token-type-extra-spec token spec))
+ (t nil))))
+
+(defmacro semantic-token-modifiers (token)
+ "Retrieve modifiers for TOKEN.
+If TOKEN is of an unknown type, then nil is returned."
+ `(semantic-token-extra-spec ,token 'typemodifiers))
+
+;;; Misc. utilities
;;
-;; These functions search through lists of nonterminals which are in
-;; standard form.
-(defun semantic-find-nonterminal-by-name (name streamorbuffer)
- "Find a nonterminal NAME within STREAMORBUFFER. NAME is a string."
- (let* ((stream (if (bufferp streamorbuffer)
- (save-excursion
- (set-buffer streamorbuffer)
- (semantic-bovinate-toplevel))
- streamorbuffer))
- (m (assoc name stream)))
- (if m
- m
- (let ((toklst (semantic-find-nonterminal-by-token 'type stream)))
- (while (and (not m) toklst)
- (let ((parts (semantic-token-type-parts (car toklst))))
- (setq m (if (listp (car parts))
- (semantic-find-nonterminal-by-name name parts)
- (car-safe (member name parts)))
- toklst (cdr toklst))))
- (if (not m)
- ;; Go to dependencies, and search there.
- nil)
- m))))
+(defun semantic-map-buffers (fun)
+ "Run function FUN for each Semantic enabled buffer found.
+FUN does not have arguments. When FUN is entered `current-buffer' is
+the current Semantic enabled buffer found."
+ (let ((bl (buffer-list))
+ b)
+ (while bl
+ (setq b (car bl)
+ bl (cdr bl))
+ (if (and (buffer-live-p b)
+ (buffer-file-name b))
+ (with-current-buffer b
+ (if (semantic-active-p)
+ (funcall fun)))))))
+
+;; These semanticdb calls will throw warnings in the byte compiler.
+;; Doing the right thing to make them available at compile time
+;; really messes up the compilation sequence.
+(defun semantic-file-token-stream (file &optional checkcache)
+ "Return a token stream for FILE.
+If it is loaded, return the stream after making sure it's ok.
+If FILE is not loaded, check to see if `semanticdb' feature exists,
+ and use it to get tokens from files not in memory.
+If FILE is not loaded, and semanticdb is not available, find the file
+ and parse it.
+Optional argument CHECKCACHE is the same as that for
+`semantic-bovinate-toplevel'."
+ (if (get-file-buffer file)
+ (save-excursion
+ (set-buffer (get-file-buffer file))
+ (semantic-bovinate-toplevel checkcache))
+ ;; File not loaded
+ (if (and (fboundp 'semanticdb-minor-mode-p)
+ (semanticdb-minor-mode-p))
+ ;; semanticdb is around, use it.
+ (semanticdb-file-stream file)
+ ;; Get the stream ourselves.
+ (save-excursion
+ (set-buffer (find-file-noselect file))
+ (semantic-bovinate-toplevel checkcache)))))
+;;; Searching by Position APIs
+;;
+;; These functions will find nonterminals based on a position.
(defun semantic-find-nonterminal-by-position (position streamorbuffer
&optional nomedian)
"Find a nonterminal covering POSITION within STREAMORBUFFER.
@@ -263,13 +324,12 @@
(defun semantic-find-nonterminal-by-overlay-next (&optional start buffer)
"Find the next nonterminal after START in BUFFER.
If START is in an overlay, find the token which starts next,
-not the current token.
-UNTRUSTED"
+not the current token."
(save-excursion
(if buffer (set-buffer buffer))
(if (not start) (setq start (point)))
(let ((os start) (ol nil))
- (while (and os (not ol))
+ (while (and os (< os (point-max)) (not ol))
(setq os (semantic-overlay-next-change os))
(when os
;; Get overlays at position
@@ -288,13 +348,12 @@
(defun semantic-find-nonterminal-by-overlay-prev (&optional start buffer)
"Find the next nonterminal after START in BUFFER.
If START is in an overlay, find the token which starts next,
-not the current token.
-UNTRUSTED"
+not the current token."
(save-excursion
(if buffer (set-buffer buffer))
(if (not start) (setq start (point)))
(let ((os start) (ol nil))
- (while (and os (not ol))
+ (while (and os (> os (point-min)) (not ol))
(setq os (semantic-overlay-previous-change os))
(when os
;; Get overlays at position
@@ -315,88 +374,305 @@
If there are more than one in the same location, return the
smallest token."
(car (nreverse (semantic-find-nonterminal-by-overlay))))
+
+;;; Nonterminal regions and splicing
+;;
+;; This functionality is needed to take some set of dirty code,
+;; and splice in new tokens after a partial reparse.
-(defun semantic-find-nonterminal-by-token (token streamorbuffer)
- "Find all nonterminals with a token TOKEN within STREAMORBUFFER.
-TOKEN is a symbol."
- (let ((stream (if (bufferp streamorbuffer)
- (save-excursion
- (set-buffer streamorbuffer)
- (semantic-bovinate-toplevel))
- streamorbuffer))
- (nl nil))
- (while stream
- (if (eq token (semantic-token-token (car stream)))
- (setq nl (cons (car stream) nl)))
- (setq stream (cdr stream)))
- (nreverse nl)))
+(defun semantic-change-function-mark-dirty (start end length)
+ "Run whenever a buffer controlled by `semantic-mode' changes.
+Tracks when and how the buffer is re-parsed.
+Argument START, END, and LENGTH specify the bounds of the change."
+ (when (and (not semantic-toplevel-bovine-cache-check)
+ (not semantic-edits-are-safe))
+ (let ((tl (condition-case nil
+ (nreverse (semantic-find-nonterminal-by-overlay-in-region
+ (1- start) (1+ end)))
+ (error nil))))
+ (if tl
+ (catch 'alldone
+ ;; Loop over the token list
+ (while tl
+ (cond
+ ;; If we are completely enclosed in this overlay.
+ ((and (> start (semantic-token-start (car tl)))
+ (< end (semantic-token-end (car tl))))
+ (if (semantic-token-get (car tl) 'dirty)
+ nil
+ (add-to-list 'semantic-dirty-tokens (car tl))
+ (semantic-token-put (car tl) 'dirty t)
+ (condition-case nil
+ (run-hook-with-args 'semantic-dirty-token-hooks
+ (car tl) start end)
+ (error (if debug-on-error (debug)))))
+ (throw 'alldone t))
+ ;; If we cover the beginning or end of this item, we must
+ ;; reparse this object. If there are more items coming, then postpone
+ ;; this till later.
+ ((not (cdr tl))
+ (setq semantic-toplevel-bovine-cache-check t)
+ (run-hooks 'semantic-reparse-needed-change-hook))
+ (t nil))
+ ;; next
+ (setq tl (cdr tl))))
+ ;; There was no hit, perhaps we need to reparse this intermediate area.
+ (setq semantic-toplevel-bovine-cache-check t)
+ )
+ )))
+;;
+;; Properties set on the tokens are:
+;; dirty - This token is dirty
+;; dirty-after - This token, and the white space after it is dirty
+;; dirty-before - This token, and the white space before it is dirty
+;; dirty-children - This token has children that are dirty.
+;;
+;; EXPERIMENTAL
+(defsubst semantic-find-nearby-dirty-tokens (beg end)
+ "Make a special kind of token for dirty whitespace.
+Argument BEG and END is the region to find nearby tokens.
+EXPERIMENTAL"
+ (let ((prev (semantic-find-nonterminal-by-overlay-prev beg))
+ (next (semantic-find-nonterminal-by-overlay-next end)))
+ (if prev (semantic-token-put prev 'dirty-after t))
+ (if next (semantic-token-put next 'dirty-before t))
+ (list prev next)))
+
+(defun semantic-set-tokens-dirty-in-region (beg end)
+ "Mark the region between BEG and END as dirty.
+This is done by finding tokens overlapping the region, and marking
+them dirty. Regions not covered by a token are then marked as
+dirty-after, meaning the space after that area is dirty.
+This function will be called in an after change hook, and must
+be very fast.
+EXPERIMENTAL"
+ (let ((tromp (semantic-find-nonterminal-by-overlay-in-region beg end))
+ (ttmp nil)
+ )
+ (if (not tromp)
+ ;; No tokens hit, setup a dirty region on the screen.
+ (setq tromp nil) ;(semantic-get-dirty-token beg end))
+ ;; First, mark all fully dirty tokens.
+ (setq ttmp tromp)
+ (while ttmp
+ (and (> beg (semantic-token-start (car tromp)))
+ (< end (semantic-token-end (car tromp))))
-(defun semantic-find-nonterminal-standard (streamorbuffer)
- "Find all nonterminals in STREAMORBUFFER which define simple token types."
- (let ((stream (if (bufferp streamorbuffer)
+ )
+ )))
+
+
+;;; Generalized nonterminal searching
+;;
+;; These functions will search through nonterminal lists explicity for
+;; desired information.
+
+;; The -by-name nonterminal search can use the built in fcn
+;; `assoc', which is faster than looping ourselves, so we will
+;; not use `semantic-find-nonterminal-by-function' to do this,
+;; instead erroring on the side of speed.
+(defun semantic-find-nonterminal-by-name
+ (name streamorbuffer &optional search-parts search-include)
+ "Find a nonterminal NAME within STREAMORBUFFER. NAME is a string.
+If SEARCH-PARTS is non-nil, search children of tokens.
+If SEARCH-INCLUDE is non-nil, search include files."
+ (let* ((stream (if (bufferp streamorbuffer)
(save-excursion
(set-buffer streamorbuffer)
(semantic-bovinate-toplevel))
streamorbuffer))
- (nl nil))
- (while stream
- (if (member (semantic-token-token (car stream))
- '(function variable type))
- (setq nl (cons (car stream) nl)))
- (setq stream (cdr stream)))
- (nreverse nl)))
+ (assoc-fun (if semantic-case-fold
+ #'assoc-ignore-case
+ #'assoc))
+ (m (funcall assoc-fun name stream)))
+ (if m
+ m
+ (let ((toklst stream)
+ (children nil))
+ (while (and (not m) toklst)
+ (if search-parts
+ (progn
+ (setq children (semantic-nonterminal-children (car toklst) t))
+ (if children
+ (setq m (semantic-find-nonterminal-by-name
+ name children search-parts search-include)))))
+ (setq toklst (cdr toklst)))
+ (if (not m)
+ ;; Go to dependencies, and search there.
+ nil)
+ m))))
+
+(defmacro semantic-find-nonterminal-by-token
+ (token streamorbuffer &optional search-parts search-includes)
+ "Find all nonterminals with a token TOKEN within STREAMORBUFFER.
+TOKEN is a symbol representing the type of the tokens to find.
+Optional argument SEARCH-PARTS and SEARCH-INCLUDE are passed to
+`semantic-find-nonterminal-by-function'."
+ `(semantic-find-nonterminal-by-function
+ (lambda (tok) (eq ,token (semantic-token-token tok)))
+ ,streamorbuffer ,search-parts ,search-includes))
+
+(defmacro semantic-find-nonterminal-standard
+ (streamorbuffer &optional search-parts search-includes)
+ "Find all nonterminals in STREAMORBUFFER which define simple token types.
+Optional argument SEARCH-PARTS and SEARCH-INCLUDE are passed to
+`semantic-find-nonterminal-by-function'."
+ `(semantic-find-nonterminal-by-function
+ (lambda (tok) (member tok '(function variable type)))
+ ,streamorbuffer ,search-parts ,search-includes))
(defvar semantic-default-built-in-types nil
"For a given language, a set of built-in types.")
(make-variable-buffer-local 'semantic-default-built-in-types)
-(defun semantic-find-nonterminal-by-type (type streamorbuffer)
+(defun semantic-find-nonterminal-by-type
+ (type streamorbuffer &optional search-parts search-includes)
"Find all nonterminals with type TYPE within STREAMORBUFFER.
-TYPE is a string."
- (let ((stream (if (bufferp streamorbuffer)
- (save-excursion
- (set-buffer streamorbuffer)
- (semantic-bovinate-toplevel))
- streamorbuffer))
- (nl nil) (ts nil))
- (if (member type semantic-default-built-in-types)
- (setq nl (list (list type 'type "built in")))
+TYPE is a string which is the name of the type of the token returned.
+Optional argument SEARCH-PARTS and SEARCH-INCLUDES are passed to
+`semantic-find-nonterminal-by-function'."
+ (if (member type semantic-default-built-in-types)
+ (list (list type 'type "built in"))
+ (semantic-find-nonterminal-by-function
+ (lambda (tok)
+ (let ((ts (semantic-token-type tok)))
+ (if (and (listp ts) (eq (semantic-token-token ts) 'type))
+ (setq ts (semantic-token-name ts)))
+ (equal type ts)))
+ streamorbuffer search-parts search-includes)))
+
+(defun semantic-find-nonterminal-by-type-regexp
+ (regexp streamorbuffer &optional search-parts search-includes)
+ "Find all nonterminals with type matching REGEXP within STREAMORBUFFER.
+REGEXP is a regular expression which matches the name of the type of the
+tokens returned.
+Optional argument SEARCH-PARTS and SEARCH-INCLUDES are passed to
+`semantic-find-nonterminal-by-function'."
+ (semantic-find-nonterminal-by-function
+ (lambda (tok)
+ (let ((ts (semantic-token-type tok)))
+ (if (listp ts)
+ (setq ts
+ (if (eq (semantic-token-token ts) 'type)
+ (semantic-token-name ts)
+ (car ts))))
+ (and ts (string-match regexp ts))))
+ streamorbuffer search-parts search-includes))
+
+(defmacro semantic-find-nonterminal-by-name-regexp
+ (regex streamorbuffer &optional search-parts search-includes)
+ "Find all nonterminals whose name match REGEX in STREAMORBUFFER.
+Optional argument SEARCH-PARTS and SEARCH-INCLUDES are passed to
+`semantic-find-nonterminal-by-function'."
+ `(semantic-find-nonterminal-by-function
+ (lambda (tok) (string-match ,regex (semantic-token-name tok)))
+ ,streamorbuffer ,search-parts ,search-includes)
+ )
+
+(defmacro semantic-find-nonterminal-by-property
+ (property value streamorbuffer &optional search-parts search-includes)
+ "Find all nonterminals with PROPERTY equal to VALUE in STREAMORBUFFER.
+Properties can be added with `semantic-token-put'.
+Optional argument SEARCH-PARTS and SEARCH-INCLUDES are passed to
+`semantic-find-nonterminal-by-function'."
+ `(semantic-find-nonterminal-by-function
+ (lambda (tok) (equal (semantic-token-get tok ,property) ,value))
+ ,streamorbuffer ,search-parts ,search-includes)
+ )
+
+(defmacro semantic-find-nonterminal-by-extra-spec
+ (spec streamorbuffer &optional search-parts search-includes)
+ "Find all nonterminals with a given SPEC in STREAMORBUFFER.
+SPEC is a symbol key into the modifiers association list.
+Optional argument SEARCH-PARTS and SEARCH-INCLUDES are passed to
+`semantic-find-nonterminal-by-function'."
+ `(semantic-find-nonterminal-by-function
+ (lambda (tok) (semantic-token-extra-spec tok ,spec))
+ ,streamorbuffer ,search-parts ,search-includes)
+ )
+
+(defmacro semantic-find-nonterminal-by-extra-spec-value
+ (spec value streamorbuffer &optional search-parts search-includes)
+ "Find all nonterminals with a given SPEC equal to VALUE in STREAMORBUFFER.
+SPEC is a symbol key into the modifiers association list.
+VALUE is the value that SPEC should match.
+Optional argument SEARCH-PARTS and SEARCH-INCLUDES are passed to
+`semantic-find-nonterminal-by-function'."
+ `(semantic-find-nonterminal-by-function
+ (lambda (tok) (equal (semantic-token-extra-spec tok ,spec) ,value))
+ ,streamorbuffer ,search-parts ,search-includes)
+ )
+
+(defun semantic-find-nonterminal-by-function
+ (function streamorbuffer &optional search-parts search-includes)
+ "Find all nonterminals in which FUNCTION match within STREAMORBUFFER.
+FUNCTION must return non-nil if an element of STREAM will be included
+in the new list.
+
+If optional argument SEARCH-PARTS is non-nil, all sub-parts of tokens
+are searched. The overloadable function `semantic-nonterminal-children' is
+used for the searching child lists. If SEARCH-PARTS is the symbol
+'positiononly, then only children that have positional information are
+searched.
+
+If SEARCH-INCLUDES is non-nil, then all include files are also
+searched for matches."
+ (let ((streamlist (list
+ (if (bufferp streamorbuffer)
+ (save-excursion
+ (set-buffer streamorbuffer)
+ (semantic-bovinate-toplevel))
+ streamorbuffer)))
+ (includes nil) ;list of includes
+ (stream nil) ;current stream
+ (sl nil) ;list of token children
+ (nl nil) ;new list
+ (case-fold-search semantic-case-fold))
+ (if search-includes
+ (setq includes (semantic-find-nonterminal-by-token
+ 'include (car streamlist))))
+ (while streamlist
+ (setq stream (car streamlist))
(while stream
- (setq ts (semantic-token-type (car stream)))
- (if (and (listp ts) (eq (semantic-token-token ts) 'type))
- (setq ts (semantic-token-name ts)))
- (if (equal type ts)
+ (if (funcall function (car stream))
(setq nl (cons (car stream) nl)))
- (setq stream (cdr stream))))
- (nreverse nl)))
-
-(defun semantic-find-nonterminal-by-function (function streamorbuffer)
- "Find all nonterminals which FUNCTION match within STREAMORBUFFER.
-FUNCTION must return non-nil if an element of STREAM will be included
-in the new list."
- (let ((stream (if (bufferp streamorbuffer)
- (save-excursion
- (set-buffer streamorbuffer)
- (semantic-bovinate-toplevel))
- streamorbuffer))
- (nl nil))
- (while stream
- (if (funcall function (car stream))
- (setq nl (cons (car stream) nl)))
- (setq stream (cdr stream)))
- (nreverse nl)))
+ (if search-parts
+ (progn
+ (setq sl (semantic-nonterminal-children
+ (car stream)
+ t
+ ))
+ (if sl
+ (setq nl (append nl (semantic-find-nonterminal-by-function
+ function sl
+ search-parts search-includes))))))
+ ;; next token
+ (setq stream (cdr stream)))
+ (setq streamlist (cdr streamlist)))
+ (setq nl (nreverse nl))
+; (while includes
+; (setq nl (append nl (semantic-find-nonterminal-by-function
+;
+; ))))
+ nl))
-(defun semantic-find-nonterminal-by-function-first-match (function
- streamorbuffer)
+(defun semantic-find-nonterminal-by-function-first-match
+ (function streamorbuffer &optional search-parts search-includes)
"Find the first nonterminal which FUNCTION match within STREAMORBUFFER.
FUNCTION must return non-nil if an element of STREAM will be included
-in the new list."
+in the new list.
+If optional argument SEARCH-PARTS, all sub-parts of tokens are searched.
+The overloadable function `semantic-nonterminal-children' is used for
+searching.
+If SEARCH-INCLUDES is non-nil, then all include files are also
+searched for matches."
(let ((stream (if (bufferp streamorbuffer)
(save-excursion
(set-buffer streamorbuffer)
(semantic-bovinate-toplevel))
streamorbuffer))
- (found nil))
+ (found nil)
+ (case-fold-search semantic-case-fold))
(while (and (not found) stream)
(if (funcall function (car stream))
(setq found (car stream)))
@@ -576,8 +852,13 @@
(if filter
(semantic-find-nonterminal-by-function filter stream)
(semantic-find-nonterminal-standard stream)))
+ (if (and default (string-match ":" prompt))
+ (setq prompt
+ (concat (substring prompt 0 (match-end 0))
+ " (default: " default ") ")))
(completing-read prompt stream nil t ""
- 'semantic-read-symbol-history default))
+ 'semantic-read-symbol-history
+ default))
(defun semantic-read-variable (prompt &optional default stream)
"Read a variable name from the user for the current buffer.
@@ -617,24 +898,52 @@
;; for tasks of that nature, and also provides reasonable defaults.
(defvar semantic-override-table nil
- "Buffer local semantic function overrides alist.
+ "Buffer local semantic function overrides obarray.
These overrides provide a hook for a `major-mode' to override specific
behaviors with respect to generated semantic toplevel nonterminals and
-things that these non-terminals are useful for.
-Each element must be of the form: (SYM . FUN)
-where SYM is the symbol to override, and FUN is the function to
-override it with.
+things that these non-terminals are useful for. Use the function
+`semantic-install-function-overrides' to install overrides.
+
Available override symbols:
SYBMOL PARAMETERS DESCRIPTION
+ `abbreviate-nonterminal' (tok & parent color) Return summary string.
+ `summarize-nonterminal' (tok & parent color) Return summary string.
+ `prototype-nonterminal' (tok & parent color) Return a prototype
string.
+ `concise-prototype-nonterminal' (tok & parent color) Return a concise prototype
string.
+ `uml-abbreviate-nonterminal' (tok & parent color) Return a UML standard
abbreviation string.
+
`find-dependency' (token) Find the dependency file
`find-nonterminal' (token & parent) Find token in buffer.
`find-documentation' (token & nosnarf) Find doc comments.
- `abbreviate-nonterminal' (token & parent) Return summery string.
- `summerize-nonterminal' (token & parent) Return summery string.
- `prototype-nonterminal' (token) Return a prototype string.
`prototype-file' (buffer) Return a file in which
prototypes are placed
+ `nonterminal-children' (token) Return first rate children.
+ These are children which may
+ contain overlays.
+ `nonterminal-protection' (token & parent) Protection (as a symbol)
+
+ CONTEXT FUNCTIONS:
+ `beginning-of-context' (& point) Move to the beginning of the
+ current context.
+ `end-of-context' (& point) Move to the end of the
+ current context.
+ `up-context' (& point) Move up one context level.
+ `get-local-variables' (& point) Get local variables.
+ `get-all-local-variables'(& point) Get all local variables.
+ `get-local-arguments' (& point) Get arguments to this function.
+
+ `end-of-command' Move to the end of the current
+ command
+ `beginning-of-command' Move to the beginning of the
+ current command
+ `ctxt-current-symbol' (& point) List of related symbols.
+ `ctxt-current-assignment'(& point) Variable being assigned to.
+ `ctxt-current-function' (& point) Function being called at point.
+ `ctxt-current-argument' (& point) The index to the argument of
+ the current function the cursor
+ is in.
+
Parameters mean:
& - Following parameters are optional
@@ -645,11 +954,448 @@
information in it.")
(make-variable-buffer-local 'semantic-override-table)
+(defun semantic-install-function-overrides (overrides &optional transient)
+ "Install function OVERRIDES in `semantic-override-table'.
+If optional TRANSIENT is non-nil installed overrides can in turn be
+overridden by next installation. OVERRIDES must be an alist. Each
+element must be of the form: (SYM . FUN) where SYM is the symbol to
+override, and FUN is the function to override it with."
+ (if (not (arrayp semantic-override-table))
+ (setq semantic-override-table (make-vector 13 nil)))
+ (let (sym sym-name fun override)
+ (while overrides
+ (setq override (car overrides)
+ overrides (cdr overrides)
+ sym-name (symbol-name (car override))
+ fun (cdr override))
+ (if (setq sym (intern-soft sym-name semantic-override-table))
+ (if (get sym 'override)
+ (set sym fun)
+ (or (equal (symbol-value sym) fun)
+ (message "Current `%s' function #'%s not overrode by
#'%s"
+ sym (symbol-value sym) fun)))
+ (setq sym (intern sym-name semantic-override-table))
+ (set sym fun))
+ (put sym 'override transient))))
+
(defun semantic-fetch-overload (sym)
- "Find and return the overload function for SYM."
- (let ((a (assq sym semantic-override-table)))
- (cdr a)))
+ "Find and return the overload function for SYM.
+Return nil if not found."
+ (symbol-value
+ (and (arrayp semantic-override-table)
+ (intern-soft (symbol-name sym) semantic-override-table))))
+
+;;; Token to text overload functions
+;;
+;; Abbreviations, prototypes, and coloring support.
+(eval-when-compile (require 'font-lock))
+(defvar semantic-token->text-functions
+ '(semantic-name-nonterminal
+ semantic-abbreviate-nonterminal
+ semantic-summarize-nonterminal
+ semantic-prototype-nonterminal
+ semantic-concise-prototype-nonterminal
+ semantic-uml-abbreviate-nonterminal
+ semantic-uml-prototype-nonterminal
+ )
+ "List of functions which convert a token to text.
+Each function must take the parameters TOKEN &optional PARENT COLOR.
+TOKEN is the token to convert.
+PARENT is a parent token or name which refers to the structure
+or class which contains TOKEN. PARENT is NOT a class which a TOKEN
+would claim as a parent.
+COLOR indicates that the generated text should be colored using
+`font-lock'.")
+
+(defvar semantic-token->text-custom-list
+ (append '(radio)
+ (mapcar (lambda (f) (list 'const f))
+ semantic-token->text-functions)
+ '(function))
+ "A List used by customizeable variables to choose a token to text function.
+Use this variable in the :type field of a customizable variable.")
+
+
+(defvar semantic-face-alist
+ `( (function . font-lock-function-name-face)
+ (variable . font-lock-variable-name-face)
+ (type . font-lock-type-face)
+ ;; These are different between Emacsen.
+ (include . ,(if (featurep 'xemacs)
+ 'font-lock-preprocessor-face
+ 'font-lock-constant-face))
+ (package . ,(if (featurep 'xemacs)
+ 'font-lock-preprocessor-face
+ 'font-lock-constant-face))
+ ;; Not a token, but instead a feature of output
+ (label . font-lock-string-face)
+ (comment . font-lock-comment-face)
+ (keyword . font-lock-keyword-face)
+ )
+ "Face used to colorize tokens of different types.
+Override the value locally if a language supports other token types.
+When adding new elements, try to use symbols also returned by the parser.
+The form of an entry in this list is of the form:
+ ( SYMBOL . FACE )
+where SYMBOL is a token type symbol used with semantic. FACE
+is a symbol representing a face.
+Faces used are generated in `font-lock' for consistency, and will not
+be used unless font lock is a feature.")
+
+;;; Coloring Functions
+(defun semantic-colorize-text (text face-class)
+ "Apply onto TEXT a color associated with FACE-CLASS.
+FACE-CLASS is a token type found in `semantic-face-alist'. See this variable
+for details on adding new types."
+ (let ((face (cdr-safe (assoc face-class semantic-face-alist)))
+ (newtext (concat text)))
+ (put-text-property 0 (length text) 'face face newtext)
+ newtext)
+ )
+
+;;; The token->text functions
+(defun semantic-name-nonterminal (token &optional parent color)
+ "Return the name string describing TOKEN.
+The name is the shortest possible representation.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let ((s (semantic-fetch-overload 'name-nonterminal))
+ tt)
+ ;; No colors without font lock
+ (if (not (featurep 'font-lock)) (setq color nil))
+ (if s
+ (funcall s token parent color)
+ (semantic-name-nonterminal-default token parent color))))
+
+(defun semantic-name-nonterminal-default (token &optional parent color)
+ "Return an abbreviated string describing TOKEN.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let ((name (semantic-token-name token)))
+ (if color
+ (setq name (semantic-colorize-text name (semantic-token-token token))))
+ name))
+
+(defun semantic-abbreviate-nonterminal (token &optional parent color)
+ "Return an abbreviated string describing TOKEN.
+The abbreviation is to be short, with possible symbols indicating
+the type of token, or other information.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let ((s (semantic-fetch-overload 'abbreviate-nonterminal)))
+ ;; No colors without font lock
+ (if (not (featurep 'font-lock)) (setq color nil))
+ (if s
+ (funcall s token parent color)
+ (semantic-abbreviate-nonterminal-default token parent color))))
+
+(defun semantic-abbreviate-nonterminal-default (token &optional parent color)
+ "Return an abbreviated string describing TOKEN.
+Optional argument PARENT is a parent token in the token hierarchy.
+In this case PARENT refers to containment, not inheritance.
+Optional argument COLOR means highlight the prototype with font-lock colors.
+This is a simple C like default."
+ ;; Do lots of complex stuff here.
+ (let ((tok (semantic-token-token token))
+ (name (semantic-name-nonterminal token parent color))
+ (suffix "")
+ str)
+ (cond ((eq tok 'function)
+ (setq suffix "()"))
+ ((eq tok 'include)
+ (setq suffix "<>"))
+ ((eq tok 'variable)
+ (setq suffix (if (semantic-token-variable-default token)
+ "=" "")))
+ )
+ (setq str (concat name suffix))
+ (if parent
+ (setq str
+ (concat (semantic-name-nonterminal parent color)
+ (car semantic-type-relation-separator-character)
+ str)))
+ str))
+
+;; Semantic 1.2.x had this misspelling. Keep it for backwards compatibiity.
+(defalias 'semantic-summerize-nonterminal 'semantic-summarize-nonterminal)
+
+(defun semantic-summarize-nonterminal (token &optional parent color)
+ "Summarize TOKEN in a reasonable way.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let ((s (semantic-fetch-overload 'summarize-nonterminal)))
+ ;; No colors without font lock
+ (if (not (featurep 'font-lock)) (setq color nil))
+ (if s
+ (funcall s token parent color)
+ (semantic-summarize-nonterminal-default token parent color)
+ )))
+
+(defun semantic-summarize-nonterminal-default (token &optional parent color)
+ "Summarize TOKEN in a reasonable way.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let ((proto (semantic-prototype-nonterminal token nil color))
+ (label (capitalize
+ (or (cdr-safe (assoc (semantic-token-token token)
+ semantic-symbol->name-assoc-list))
+ (symbol-name (semantic-token-token token))))))
+ (if color
+ (setq label (semantic-colorize-text label 'label)))
+ (concat label ": " proto))
+ )
+
+(defun semantic-prototype-nonterminal (token &optional parent color)
+ "Return a prototype for TOKEN.
+This function should be overloaded, though it need not be used.
+This is because it can be used to create code by language independent
+tools.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let ((s (semantic-fetch-overload 'prototype-nonterminal)))
+ ;; No colors without font lock
+ (if (not (featurep 'font-lock)) (setq color nil))
+ (if s
+ ;; Prototype is non-local
+ (funcall s token parent color)
+ (semantic-prototype-nonterminal-default token parent color))))
+
+(defun semantic-prototype-nonterminal-default-args (args color)
+ "Create a list of of strings for prototypes of ARGS.
+ARGS can be a list of terminals, or a list of strings.
+COLOR specifies if these arguments should be colored or not."
+ (let ((out nil))
+ (while args
+ (cond ((stringp (car args))
+ (let ((a (car args)))
+ (if color
+ (setq a (semantic-colorize-text a 'variable)))
+ (setq out (cons a out))
+ ))
+ ((semantic-token-p (car args))
+ (setq out
+ (cons (semantic-prototype-nonterminal (car args) nil t)
+ out))))
+ (setq args (cdr args)))
+ (nreverse out)))
+
+(defun semantic-prototype-nonterminal-default (token &optional parent color)
+ "Default method for returning a prototype for TOKEN.
+This will work for C like languages.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let* ((tok (semantic-token-token token))
+ (name (semantic-name-nonterminal token parent color))
+ (type (if (member tok '(function variable type))
+ (semantic-token-type token)))
+ (args (semantic-prototype-nonterminal-default-args
+ (cond ((eq tok 'function)
+ (semantic-token-function-args token))
+ ((eq tok 'type)
+ (semantic-token-type-parts token))
+ (t nil))
+ color))
+ (const (semantic-token-extra-spec token 'const))
+ (mods (append
+ (if const '("const") nil)
+ (semantic-token-extra-spec token 'typemodifiers)))
+ (array (if (eq tok 'variable)
+ (let ((deref
+ (semantic-token-variable-extra-spec
+ token 'dereference))
+ (r ""))
+ (while (and deref (/= deref 0))
+ (setq r (concat r "[]")
+ deref (1- deref)))
+ r)))
+ (suffix (if (eq tok 'variable)
+ (semantic-token-variable-extra-spec token 'suffix)))
+ )
+ (if (and (listp mods) mods)
+ (setq mods (concat (mapconcat (lambda (a) a) mods " ") " ")))
+ (if (and mods color)
+ (setq mods (semantic-colorize-text mods 'type)))
+ (if args
+ (setq args
+ (concat " "
+ (if (eq tok 'type) "{" "(")
+ (mapconcat (lambda (a) a) args ",")
+ (if (eq tok 'type) "}" ")"))))
+ (if type
+ (if (semantic-token-p type)
+ (setq type (semantic-prototype-nonterminal type nil color))
+ (if (listp type)
+ (setq type (car type)))
+ (if color
+ (setq type (semantic-colorize-text type 'type)))))
+ (concat (or mods "")
+ (if type (concat type " "))
+ name
+ (or args "")
+ (or array ""))))
+
+(defun semantic-concise-prototype-nonterminal (token &optional parent color)
+ "Return a concise prototype for TOKEN.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let ((s (semantic-fetch-overload 'concise-prototype-nonterminal)))
+ (if s
+ (funcall s token parent color)
+ (semantic-concise-prototype-nonterminal-default token parent color))))
+
+(defun semantic-concise-prototype-nonterminal-default (token &optional parent
color)
+ "Return a concise prototype for TOKEN.
+This default function will make a cheap concise prototype using C like syntax.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let ((tok (semantic-token-token token)))
+ (cond
+ ((eq tok 'type)
+ (concat (semantic-name-nonterminal token parent color) "{}"))
+ ((eq tok 'function)
+ (let ((args (semantic-token-function-args token)))
+ (concat (semantic-name-nonterminal token parent color)
+ "("
+ (if args
+ (cond ((stringp (car args))
+ (mapconcat
+ (if color
+ (lambda (a) (semantic-colorize-text
+ a 'variable))
+ 'identity)
+ args ","))
+ ((semantic-token-p (car args))
+ (mapconcat
+ (lambda (a)
+ (let ((ty (semantic-token-type a)))
+ (cond ((and (stringp ty) color)
+ (semantic-colorize-text ty 'type))
+ ((stringp ty)
+ ty)
+ ((semantic-token-p ty)
+ (semantic-prototype-nonterminal
+ ty parent nil))
+ ((and (consp ty) color)
+ (semantic-colorize-text (car ty) 'type))
+ ((consp ty)
+ (car ty))
+ (t (error "Concice-prototype")))))
+ args ", "))
+ ((consp (car args))
+ (mapconcat
+ (if color
+ (lambda (a)
+ (semantic-colorize-text (car a) 'type))
+ 'car)
+ args ","))
+ (t (error "Concice-prototype")))
+ "")
+ ")")))
+ ((eq tok 'variable)
+ (let* ((deref (semantic-token-variable-extra-spec
+ token 'dereference))
+ (array "")
+ (suffix (semantic-token-variable-extra-spec
+ token 'suffix)))
+ (while (and deref (/= deref 0))
+ (setq array (concat array "[]")
+ deref (1- deref)))
+ (concat (semantic-name-nonterminal token parent nil)
+ array)))
+ (t
+ (semantic-abbreviate-nonterminal token parent nil)))))
+
+(defun semantic-uml-protection-to-string (protection-symbol)
+ "Convert PROTECTION-SYMBOL to a string for UML."
+ (cond ((eq protection-symbol 'public)
+ "+")
+ ((eq protection-symbol 'private)
+ "-")
+ ((eq protection-symbol 'protected)
+ "#")
+ (t " ")))
+
+(defun semantic-uml-abbreviate-nonterminal (token &optional parent color)
+ "Return a UML style abbreviation for TOKEN.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let ((s (semantic-fetch-overload 'uml-abbreviate-nonterminal)))
+ (if s
+ (funcall s token parent color)
+ (semantic-uml-abbreviate-nonterminal-default token parent color))))
+
+(defun semantic-uml-abbreviate-nonterminal-default (token &optional parent color)
+ "Return a UML style abbreviation for TOKEN.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let* ((tok (semantic-token-token token))
+ (name (semantic-name-nonterminal token parent color))
+ (type (or (semantic-token-type token) ""))
+ (prot (semantic-nonterminal-protection token parent))
+ )
+ (setq type
+ (cond ((semantic-token-p type)
+ (semantic-prototype-nonterminal type nil color))
+ ((listp type)
+ (car type))
+ ((stringp type)
+ type)
+ (t nil)))
+ (if (and type color)
+ (setq type (semantic-colorize-text type 'type)))
+ (setq prot (semantic-uml-protection-to-string prot))
+ (if type
+ (concat prot name ":" type)
+ name)
+ ))
+
+(defun semantic-uml-prototype-nonterminal (token &optional parent color)
+ "Return a UML style prototype for TOKEN.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let ((s (semantic-fetch-overload 'uml-prototype-nonterminal)))
+ (if s
+ (funcall s token parent color)
+ (semantic-uml-prototype-nonterminal-default token parent color))))
+
+(defun semantic-uml-prototype-nonterminal-default (token &optional parent color)
+ "Return a UML style abbreviation for TOKEN.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let* ((tok (semantic-token-token token))
+ (name (semantic-name-nonterminal token parent color))
+ (type (or (semantic-token-type token) ""))
+ (args (semantic-prototype-nonterminal-default-args
+ (cond ((eq tok 'function)
+ (semantic-token-function-args token))
+ (t nil))
+ color))
+ (prot (semantic-nonterminal-protection token parent))
+ )
+ (if type
+ (if (semantic-token-p type)
+ (setq type (semantic-prototype-nonterminal type nil color))
+ (if (listp type)
+ (setq type (car type)))
+ (if color
+ (setq type (semantic-colorize-text type 'type)))))
+ (setq prot (semantic-uml-protection-to-string prot))
+ (if args
+ (setq args
+ (concat " "
+ (if (eq tok 'type) "{" "(")
+ (mapconcat (lambda (a) a) args ",")
+ (if (eq tok 'type) "}" ")"))))
+ (if type
+ (concat prot name (or args "") ":" type)
+ name)
+ ))
+
+
+
+;;; Multi-file Token information
+;;
(defvar semantic-dependency-include-path nil
"Defines the include path used when searching for files.
This should be a list of directories to search which is specific to
@@ -668,6 +1414,9 @@
(if (not token)
(setq token (car (semantic-find-nonterminal-by-overlay nil))))
+ (if (not (eq (semantic-token-token token) 'include))
+ (signal 'wrong-type-argument (list token 'include)))
+
;; First, see if this file exists in the current EDE projecy
(if (and (fboundp 'ede-expand-filename) ede-minor-mode
(ede-expand-filename (ede-toplevel)
@@ -709,20 +1458,29 @@
nil
(let ((s (semantic-fetch-overload 'find-nonterminal)))
(if s (funcall s token parent)
- (set-buffer (semantic-token-buffer token))
- (let ((start (semantic-token-start token)))
- (if (numberp start)
- ;; If it's a number, go there
- (goto-char start)
- ;; Otherwise, it's a trimmed vector, such as a parameter,
- ;; or a structure part.
- (if (not parent)
- nil
- (goto-char (semantic-token-start parent))
- ;; Here we make an assumtion that the text returned by
- ;; the bovinator and concocted by us actually exists
- ;; in the buffer.
- (re-search-forward (semantic-token-name token) nil t))))))))
+ (if (semantic-token-buffer token)
+ ;; If the token has no buffer, it may be deoverlayed.
+ ;; Assume the tool doing the finding knows that we came
+ ;; in from a database, and use the current buffer.
+ (set-buffer (semantic-token-buffer token)))
+ (if (semantic-token-with-position-p token)
+ ;; If it's a number, go there
+ (goto-char (semantic-token-start token))
+ ;; Otherwise, it's a trimmed vector, such as a parameter,
+ ;; or a structure part.
+ (if (not parent)
+ nil
+ (if (semantic-token-with-position-p parent)
+ (progn
+ (if (semantic-token-buffer parent)
+ ;; If this parent token has no buffer, then it
+ ;; may be deoverlayed.
+ (set-buffer (semantic-token-buffer parent)))
+ (goto-char (semantic-token-start parent))
+ ;; Here we make an assumtion that the text returned by
+ ;; the bovinator and concocted by us actually exists
+ ;; in the buffer.
+ (re-search-forward (semantic-token-name token) nil t)))))))))
(defun semantic-find-documentation (&optional token nosnarf)
"Find documentation from TOKEN and return it as a clean string.
@@ -743,8 +1501,10 @@
(or
;; Is there doc in the token???
(if (semantic-token-docstring token)
- (progn (goto-char (semantic-token-docstring token))
- (semantic-find-doc-snarf-comment nosnarf)))
+ (if (stringp (semantic-token-docstring token))
+ (semantic-token-docstring token)
+ (goto-char (semantic-token-docstring token))
+ (semantic-find-doc-snarf-comment nosnarf)))
;; Check just before the definition.
(save-excursion
(re-search-backward comment-start-skip nil t)
@@ -790,84 +1550,6 @@
;; Now return the text.
ct))))
-(defun semantic-abbreviate-nonterminal (token &optional parent)
- "Return an abbreviated string describing TOKEN.
-The abbreviation is to be short, with possible symbols indicating
-the type of token, or other information.
-Optional argument PARENT is the parent type if TOKEN is a detail."
- (let ((s (semantic-fetch-overload 'abbreviate-nonterminal))
- tt)
- (if s
- (funcall s token parent)
- ;; Do lots of complex stuff here.
- (let ((tok (semantic-token-token token))
- (name (semantic-token-name token)))
- (concat name
- (cond ((eq tok 'function) "()")
- ((eq tok 'include) "<>")
- ((and (eq tok 'variable)
- (semantic-token-variable-default token))
- "=")))
- ))))
-
-(defun semantic-summerize-nonterminal (token &optional parent)
- "Summerize TOKEN in a reasonable way.
-Optional argument PARENT is the parent type if TOKEN is a detail."
- (let ((s (semantic-fetch-overload 'summerize-nonterminal)))
- (if s
- (funcall s token parent)
- ;; FLESH THIS OUT MORE
- (concat (or (capitalize
- (cdr-safe (assoc (semantic-token-token token)
- semantic-symbol->name-assoc-list)))
- (capitalize (symbol-name (semantic-token-token token))))
- ": "
- (semantic-prototype-nonterminal token)))))
-
-(defun semantic-prototype-nonterminal (token)
- "Return a prototype for TOKEN.
-This functin must be overloaded, though it need not be used."
- (let ((tt (semantic-token-token token))
- (s (semantic-fetch-overload 'prototype-nonterminal)))
- (if s
- ;; Prototype is non-local
- (funcall s token)
- ;; Cococt a cheap prototype
- (let* ((tok (semantic-token-token token))
- (type (if (member tok '(function variable type))
- (semantic-token-type token) ""))
- (args (cond ((eq tok 'function)
- (semantic-token-function-args token))
- ((eq tok 'type)
- (semantic-token-type-parts token))
- (t nil)))
- (mods (cond ((eq tok 'variable)
- (semantic-token-variable-modifiers token))
- ((eq tok 'function)
- (semantic-token-function-modifiers token))
- ((eq tok 'type)
- (semantic-token-type-modifiers token))
- (t nil)))
- (array (if (eq tok 'variable)
- (semantic-token-variable-optsuffix token)))
- )
- (if (and (listp mods) mods)
- (setq mods (concat (mapconcat (lambda (a) a) mods " ") " ")))
- (if args
- (setq args
- (concat " " (if (eq tok 'type) "{" "(")
- (if (stringp (car args))
- (mapconcat (lambda (a) a) args ",")
- (mapconcat 'car args ","))
- (if (eq tok 'type) "}" ")"))))
- (if (and type (listp type))
- (setq type (car type)))
- (concat (or mods "")
- (if type (concat type " "))
- (semantic-token-name token)
- (or args "")
- (or array ""))))))
-
(defun semantic-prototype-file (buffer)
"Return a file in which prototypes belonging to BUFFER should be placed.
Default behavior (if not overriden) looks for a token specifying the
@@ -887,6 +1569,83 @@
(if (re-search-forward "::Header:: \\([a-zA-Z0-9.]+\\)" nil t)
(match-string 1)))))))
+
+;;;; Mode-specific Token information
+;;
+(defun semantic-nonterminal-children (token &optional positionalonly)
+ "Return the list of top level children belonging to TOKEN.
+Children are any sub-tokens which may contain overlays.
+The default behavior (if not overriden with `nonterminal-children'
+is to return type parts for a type, and arguments for a function.
+
+If optional argument POSITIONALONLY is non-nil, then only return valid
+children if they contain positions. Some languages may choose to create
+lists of children without position/overlay information.
+
+If this function is overriden, use `semantic-nonterminal-children-default'
+to also include the default behavior, and merely extend your own.
+
+Note for language authors:
+ If a mode defines a language that has tokens in it with overlays that
+should not be considered children, you should still return them with
+this function."
+ (let* ((s (semantic-fetch-overload 'nonterminal-children))
+ (chil (if s (funcall s token)
+ (semantic-nonterminal-children-default token))))
+ (if (or (not positionalonly)
+ (semantic-token-with-position-p (car chil)))
+ chil
+ nil)))
+
+(defun semantic-nonterminal-children-default (token)
+ "Return the children of TOKEN.
+For types, return the type parts.
+For functions return the argument list."
+ (cond ((eq (semantic-token-token token) 'type)
+ (semantic-token-type-parts token))
+ ((eq (semantic-token-token token) 'function)
+ (semantic-token-function-args token))
+ (t nil)))
+
+(defun semantic-nonterminal-protection (token &optional parent)
+ "Return protection information about TOKEN with optional PARENT.
+This function returns on of the following symbols:
+ nil - No special protection. Language dependent.
+ 'public - Anyone can access this TOKEN.
+ 'private - Only methods in the local scope can access TOKEN.
+ 'protected - Like private for outside scopes, like public for child
+ classes.
+Some languages may choose to provide additional return symbols specific
+to themselves. Use of this function should allow for this.
+
+The default behavior (if not overriden with `nonterminal-children'
+is to return a symbol based on type modifiers."
+ (let* ((s (semantic-fetch-overload 'nonterminal-protection)))
+ (if s (funcall s token parent)
+ (semantic-nonterminal-protection-default token parent))))
+
+(defun semantic-nonterminal-protection-default (token &optional parent)
+ "Return the protection of TOKEN as a child of PARENT default action.
+See `semantic-nonterminal-protection'."
+ (let ((mods (semantic-token-modifiers token))
+ (prot nil))
+ (while (and (not prot) mods)
+ (if (stringp (car mods))
+ (let ((s (car mods)))
+ ;; A few silly defaults to get things started.
+ (cond ((or (string= s "public")
+ (string= s "extern")
+ (string= s "export"))
+ 'public)
+ ((or (string= s "private")
+ (string= s "static"))
+ 'private)
+ ((string= s "protected")
+ 'protected))))
+ (setq mods (cdr mods)))
+ prot))
+
+
;;; Do some fancy stuff with overlays
;;
(defun semantic-highlight-token (token &optional face)
@@ -930,15 +1689,27 @@
(semantic-overlay-put (semantic-token-overlay token) 'invisible
(not visible)))
+(defun semantic-token-invisible-p (token)
+ "Return non-nil if TOKEN is invisible."
+ (semantic-overlay-get (semantic-token-overlay token) 'invisible))
+
(defun semantic-set-token-intangible (token &optional tangible)
"Enable the text in TOKEN to be made intangible.
-If TANGIBLE is non-nil, make the text visible."
+If TANGIBLE is non-nil, make the text visible.
+This function does not have meaning in XEmacs because it seems that
+the extent 'intangible' property does not exist."
(semantic-overlay-put (semantic-token-overlay token) 'intangible
(not tangible)))
+(defun semantic-token-intangible-p (token)
+ "Return non-nil if TOKEN is intangible.
+This function does not have meaning in XEmacs because it seems that
+the extent 'intangible' property does not exist."
+ (semantic-overlay-get (semantic-token-overlay token) 'intangible))
+
(defun semantic-overlay-signal-read-only
(overlay after start end &optional len)
- "Hook used in modification hooks to preventi modification.
+ "Hook used in modification hooks to prevent modification.
Allows deletion of the entire text.
Argument OVERLAY, AFTER, START, END, and LEN are passed in by the system."
;; Stolen blithly from cpp.el in Emacs 21.1
@@ -953,36 +1724,114 @@
instead of read-only."
(let ((o (semantic-token-overlay token))
(hook (if writable nil '(semantic-overlay-signal-read-only))))
- (semantic-overlay-put o 'modification-hooks hook)
- (semantic-overlay-put o 'insert-in-front-hooks hook)
- (semantic-overlay-put o 'insert-behind-hooks hook)))
+ (if (featurep 'xemacs)
+ ;; XEmacs extents have a 'read-only' property.
+ (semantic-overlay-put o 'read-only (not writable))
+ (semantic-overlay-put o 'modification-hooks hook)
+ (semantic-overlay-put o 'insert-in-front-hooks hook)
+ (semantic-overlay-put o 'insert-behind-hooks hook))))
+(defun semantic-token-read-only-p (token)
+ "Return non-nil if the current TOKEN is marked read only."
+ (let ((o (semantic-token-overlay token)))
+ (if (featurep 'xemacs)
+ ;; XEmacs extents have a 'read-only' property.
+ (semantic-overlay-get o 'read-only)
+ (member 'semantic-overlay-signal-read-only
+ (semantic-overlay-get o 'modification-hooks)))))
+
+(defun semantic-narrow-to-token (token)
+ "Narrow to the region specified by TOKEN."
+ (narrow-to-region (semantic-token-start token)
+ (semantic-token-end token)))
+
;;; Interactive Functions for bovination
;;
-(eval-when-compile
- (condition-case nil (require 'pp) (error nil)))
+(defun semantic-describe-token (&optional token)
+ "Describe TOKEN in the minibuffer.
+If TOKEN is nil, describe the token under the cursor."
+ (interactive)
+ (if (not token) (setq token (semantic-current-nonterminal)))
+ (semantic-bovinate-toplevel t)
+ (if token (message (semantic-summarize-nonterminal token))))
-(defun bovinate (&optional clear)
- "Bovinate the current buffer. Show output in a temp buffer.
-Optional argument CLEAR will clear the cache before bovinating."
- (interactive "P")
- (if clear (semantic-clear-toplevel-cache))
- (let ((out (semantic-bovinate-toplevel)))
- (pop-to-buffer "*BOVINATE*")
- (require 'pp)
- (erase-buffer)
- (insert (pp-to-string out))
- (goto-char (point-min))))
+
+;;; Putting keys on tokens.
+;;
+(defun semantic-add-label (label value &optional token)
+ "Add a LABEL with VALUE on TOKEN.
+If TOKEN is not specified, use the token at point."
+ (interactive "sLabel: \nXValue (eval): ")
+ (if (not token)
+ (progn
+ (semantic-bovinate-toplevel t)
+ (setq token (semantic-current-nonterminal))))
+ (semantic-token-put token (intern label) value)
+ (message "Added label %s with value %S" label value))
+
+(defun semantic-show-label (label &optional token)
+ "Show the value of LABEL on TOKEN.
+If TOKEN is not specified, use the token at point."
+ (interactive "sLabel: ")
+ (if (not token)
+ (progn
+ (semantic-bovinate-toplevel t)
+ (setq token (semantic-current-nonterminal))))
+ (message "%s: %S" label (semantic-token-get token (intern label))))
-(defun bovinate-debug ()
- "Bovinate the current buffer and run in debug mode."
- (interactive)
- (let ((semantic-edebug t)
- (out (semantic-bovinate-debug-buffer)))
- (pop-to-buffer "*BOVINATE*")
- (require 'pp)
- (erase-buffer)
- (insert (pp-to-string out))))
+
+;;; Show dirty mode
+;;
+;;;###autoload
+(defcustom semantic-show-dirty-mode nil
+ "*If non-nil enable the use of `semantic-show-dirty-mode'."
+ :group 'semantic
+ :type 'boolean
+ :require 'semantic-util
+ :initialize 'custom-initialize-default
+ :set (lambda (sym val)
+ (semantic-show-dirty-mode (if val 1 -1))
+ (custom-set-default sym val)))
+
+(defface semantic-dirty-token-face '((((class color) (background dark))
+ (:background "gray10"))
+ (((class color) (background light))
+ (:background "gray90")))
+ "Face used to show dirty tokens in `semantic-show-dirty-token-mode'."
+ :group 'semantic)
+
+(defun semantic-show-dirty-token-hook-fcn (token start end)
+ "Function set into `semantic-dirty-token-hooks'.
+This will highlight TOKEN as dirty.
+START and END define the region changed, but are not used."
+ (semantic-highlight-token token 'semantic-dirty-token-face))
+
+(defun semantic-show-clean-token-hook-fcn (token)
+ "Function set into `semantic-clean-token-hooks'.
+This will unhighlight TOKEN from being dirty."
+ (semantic-unhighlight-token token))
+
+(defun semantic-show-dirty-mode (&optional arg)
+ "Enable the display of dirty tokens.
+If ARG is positive, enable, if it is negative, disable.
+If ARG is nil, then toggle."
+ (interactive "P")
+ (if (not arg)
+ (if (member #'semantic-show-dirty-token-hook-fcn
+ semantic-dirty-token-hooks)
+ (setq arg -1)
+ (setq arg 1)))
+ (if (< arg 0)
+ (progn
+ ;; Remove hooks
+ (remove-hook 'semantic-dirty-token-hooks 'semantic-show-dirty-token-hook-fcn)
+ (remove-hook 'semantic-clean-token-hooks 'semantic-show-clean-token-hook-fcn)
+ (remove-hook 'after-save-hook 'semantic-rebovinate-quickly-hook)
+ )
+ (add-hook 'semantic-dirty-token-hooks 'semantic-show-dirty-token-hook-fcn)
+ (add-hook 'semantic-clean-token-hooks 'semantic-show-clean-token-hook-fcn)
+ (add-hook 'after-save-hook 'semantic-rebovinate-quickly-hook)
+ ))
;;; Hacks
;;
@@ -991,11 +1840,11 @@
"Display the curent token.
Argument P is the point to search from in the current buffer."
(interactive "d")
- (message
- (mapconcat
- 'semantic-abbreviate-nonterminal
- (semantic-find-innermost-nonterminal-by-position p (current-buffer))
- ",")))
+ (let ((tok (semantic-find-innermost-nonterminal-by-position
+ p (current-buffer))))
+ (message (mapconcat 'semantic-abbreviate-nonterminal tok ","))
+ (car tok))
+ )
(defun semantic-hack-search ()
"Disply info about something under the cursor using generic methods."
Index: xemacs-packages/semantic/semantic-util.el.upstream
===================================================================
RCS file:
/usr/CVSroot/XEmacs/packages/xemacs-packages/semantic/semantic-util.el.upstream,v
retrieving revision 1.1
diff -u -r1.1 semantic-util.el.upstream
--- xemacs-packages/semantic/semantic-util.el.upstream 2001/02/20 03:23:45 1.1
+++ xemacs-packages/semantic/semantic-util.el.upstream 2001/08/15 05:28:21
@@ -4,7 +4,7 @@
;; Author: Eric M. Ludlam <zappo(a)gnu.org>
;; Keywords: syntax
-;; X-RCS: $Id: semantic-util.el.upstream,v 1.1 2001/02/20 03:23:45 youngs Exp $
+;; X-RCS: $Id: semantic-util.el,v 1.68 2001/07/13 16:12:41 zappo Exp $
;; This file is not part of GNU Emacs.
@@ -29,16 +29,32 @@
;; Semantic Bovinator.
;;
+(require 'assoc)
+(require 'semantic)
;;; Code:
-;;; Simple APIs
-;;
-;; These macros extract parts from the default token types as
-;; described by `semantic-toplevel-bovine-table'
-
-;; Check semantic.el for the other token information extraction functions.
+(defvar semantic-type-relation-separator-character '(".")
+ "Character strings used to separation a parent/child relationship.
+This list of strings are used for displaying or finding separators
+in variable field dereferencing. The first character will be used for
+display. In C, a type field is separated like this: \"type.field\"
+thus, the character is a \".\". In C, and additional value of
\"->\"
+would be in the list, so that \"type->field\" could be found.")
+(make-variable-buffer-local 'semantic-type-relation-separator-character)
+
+(defvar semantic-equivalent-major-modes nil
+ "List of major modes which are considered equivalent.
+Equivalent modes share a parser, and a set of override methods.
+Setup from the BNF code generator. A value of nil means that
+the current major mode is the only one.")
+(make-variable-buffer-local 'semantic-equivalent-major-modes)
+;;; Utility API functions
+;;
+;; These functions use the flex and bovination engines to perform some
+;; simple tasks useful to other programs. These are just the most
+;; critical entries.
(defun semantic-token-type (token)
"Retrieve the type of TOKEN."
(if (member (semantic-token-token token)
@@ -50,77 +66,163 @@
`(nth 3 ,token))
(defmacro semantic-token-type-parent (token)
- "Retrieve the parent of the type TOKEN."
+ "Retrieve the parent of the type TOKEN.
+The return value is a list. A value of nil means no parents.
+The `car' of the list is either the parent class, or a list
+of parent classes. The `cdr' of the list is the list of
+interfaces, or abstract classes which are parents of TOKEN."
`(nth 4 ,token))
-(defmacro semantic-token-type-modifiers (token)
- "Retrieve the non-type modifiers of the type TOKEN."
+(defun semantic-token-type-parent-superclass (token)
+ "Retrieve the parent superclasses of type type TOKEN."
+ (let ((p (semantic-token-type-parent token)))
+ (cond ((stringp (car p))
+ (list (car p)))
+ ((listp (car p))
+ (car p)))))
+
+(defun semantic-token-type-parent-implement (token)
+ "Retrieve the parent interfaces of type type TOKEN."
+ (cdr (semantic-token-type-parent token)))
+
+(defmacro semantic-token-type-extra-specs (token)
+ "Retrieve extra specifications for the type TOKEN."
`(nth 5 ,token))
+(defmacro semantic-token-type-extra-spec (token spec)
+ "Retrieve an extra specification for the type TOKEN.
+SPEC is the symbol whose specification value to get."
+ `(cdr (assoc ,spec (semantic-token-type-extra-specs ,token))))
+
+(defmacro semantic-token-type-modifiers (token)
+ "Retrieve modifiers for the type TOKEN."
+ `(semantic-token-type-extra-spec ,token 'typemodifiers))
+
(defmacro semantic-token-function-args (token)
"Retrieve the arguments of the function TOKEN."
`(nth 3 ,token))
-(defmacro semantic-token-function-modifiers (token)
- "Retrieve non-type modifiers for the function TOKEN."
+(defmacro semantic-token-function-extra-specs (token)
+ "Retrieve extra specifications for the function TOKEN."
`(nth 4 ,token))
+(defmacro semantic-token-function-extra-spec (token spec)
+ "Retrieve an extra specification for the function TOKEN.
+SPEC is the symbol whose specification value to get."
+ `(cdr (assoc ,spec (semantic-token-function-extra-specs ,token))))
+
+(defmacro semantic-token-function-modifiers (token)
+ "Retrieve modifiers for the function TOKEN."
+ `(semantic-token-function-extra-spec ,token 'typemodifiers))
+
(defmacro semantic-token-function-throws (token)
- "Optional details if this function has a THROWS type.
+ "The symbol string that a function can throws.
Determines if it is available based on the length of TOKEN."
- `(if (>= (length ,token) (+ 6 2))
- (nth 5 ,token)
- nil))
+ `(semantic-token-function-extra-spec ,token 'throws))
-(defmacro semantic-token-variable-const (token)
- "Retrieve the status of constantness from the variable TOKEN."
- `(nth 3 ,token))
+(defmacro semantic-token-function-parent (token)
+ "The parent of the function TOKEN.
+A function has a parent if it is a method of a class, and if the
+function does not appear in body of it's parent class."
+ `(semantic-token-function-extra-spec ,token 'parent))
(defmacro semantic-token-variable-default (token)
"Retrieve the default value of the variable TOKEN."
+ `(nth 3 ,token))
+
+(defmacro semantic-token-variable-extra-specs (token)
+ "Retrieve extra specifications for the variable TOKEN."
`(nth 4 ,token))
+(defmacro semantic-token-variable-extra-spec (token spec)
+ "Retrieve an extra specification for the variable TOKEN.
+SPEC is the symbol whose specification value to get."
+ `(cdr (assoc ,spec (semantic-token-variable-extra-specs ,token))))
+
(defmacro semantic-token-variable-modifiers (token)
- "Retrieve non-type modifiers for the variable TOKEN."
- `(nth 5 ,token))
+ "Retrieve modifiers for the variable TOKEN."
+ `(semantic-token-variable-extra-spec ,token 'typemodifiers))
+(defmacro semantic-token-variable-const (token)
+ "Retrieve the status of constantness from the variable TOKEN."
+ `(semantic-token-variable-extra-spec ,token 'const))
+
(defmacro semantic-token-variable-optsuffix (token)
"Optional details if this variable has bit fields, or array dimentions.
Determines if it is available based on the length of TOKEN."
- `(if (>= (length ,token) (+ 7 2))
- (nth 6 ,token)
- nil))
+ `(semantic-token-variable-extra-spec ,token 'suffix))
(defmacro semantic-token-include-system (token)
- "Retrieve the flag indicating if the include TOKEN is a sysmtem include."
+ "Retrieve the flag indicating if the include TOKEN is a system include."
`(nth 2 ,token))
+
+(defun semantic-token-extra-spec (token spec)
+ "Retrieve an extra specification for TOKEN.
+SPEC is a symbol whose specification value to get.
+This function can get extra specifications from any type of token.
+Do not use the function if you know what type of token you are dereferencing.
+Instead, use `semantic-token-variable-extra-spec',
+`semantic-token-function-extra-spec', or
`semantic-token-type-extra-spec'."
+ (let ((tt (semantic-token-token token)))
+ (cond ((eq tt 'variable)
+ (semantic-token-variable-extra-spec token spec))
+ ((eq tt 'function)
+ (semantic-token-function-extra-spec token spec))
+ ((eq tt 'type)
+ (semantic-token-type-extra-spec token spec))
+ (t nil))))
+
+(defmacro semantic-token-modifiers (token)
+ "Retrieve modifiers for TOKEN.
+If TOKEN is of an unknown type, then nil is returned."
+ `(semantic-token-extra-spec ,token 'typemodifiers))
-;;; Searching APIs
+;;; Misc. utilities
;;
-;; These functions search through lists of nonterminals which are in
-;; standard form.
-(defun semantic-find-nonterminal-by-name (name streamorbuffer)
- "Find a nonterminal NAME within STREAMORBUFFER. NAME is a string."
- (let* ((stream (if (bufferp streamorbuffer)
- (save-excursion
- (set-buffer streamorbuffer)
- (semantic-bovinate-toplevel))
- streamorbuffer))
- (m (assoc name stream)))
- (if m
- m
- (let ((toklst (semantic-find-nonterminal-by-token 'type stream)))
- (while (and (not m) toklst)
- (let ((parts (semantic-token-type-parts (car toklst))))
- (setq m (if (listp (car parts))
- (semantic-find-nonterminal-by-name name parts)
- (car-safe (member name parts)))
- toklst (cdr toklst))))
- (if (not m)
- ;; Go to dependencies, and search there.
- nil)
- m))))
+(defun semantic-map-buffers (fun)
+ "Run function FUN for each Semantic enabled buffer found.
+FUN does not have arguments. When FUN is entered `current-buffer' is
+the current Semantic enabled buffer found."
+ (let ((bl (buffer-list))
+ b)
+ (while bl
+ (setq b (car bl)
+ bl (cdr bl))
+ (if (and (buffer-live-p b)
+ (buffer-file-name b))
+ (with-current-buffer b
+ (if (semantic-active-p)
+ (funcall fun)))))))
+
+;; These semanticdb calls will throw warnings in the byte compiler.
+;; Doing the right thing to make them available at compile time
+;; really messes up the compilation sequence.
+(defun semantic-file-token-stream (file &optional checkcache)
+ "Return a token stream for FILE.
+If it is loaded, return the stream after making sure it's ok.
+If FILE is not loaded, check to see if `semanticdb' feature exists,
+ and use it to get tokens from files not in memory.
+If FILE is not loaded, and semanticdb is not available, find the file
+ and parse it.
+Optional argument CHECKCACHE is the same as that for
+`semantic-bovinate-toplevel'."
+ (if (get-file-buffer file)
+ (save-excursion
+ (set-buffer (get-file-buffer file))
+ (semantic-bovinate-toplevel checkcache))
+ ;; File not loaded
+ (if (and (fboundp 'semanticdb-minor-mode-p)
+ (semanticdb-minor-mode-p))
+ ;; semanticdb is around, use it.
+ (semanticdb-file-stream file)
+ ;; Get the stream ourselves.
+ (save-excursion
+ (set-buffer (find-file-noselect file))
+ (semantic-bovinate-toplevel checkcache)))))
+;;; Searching by Position APIs
+;;
+;; These functions will find nonterminals based on a position.
(defun semantic-find-nonterminal-by-position (position streamorbuffer
&optional nomedian)
"Find a nonterminal covering POSITION within STREAMORBUFFER.
@@ -222,13 +324,12 @@
(defun semantic-find-nonterminal-by-overlay-next (&optional start buffer)
"Find the next nonterminal after START in BUFFER.
If START is in an overlay, find the token which starts next,
-not the current token.
-UNTRUSTED"
+not the current token."
(save-excursion
(if buffer (set-buffer buffer))
(if (not start) (setq start (point)))
(let ((os start) (ol nil))
- (while (and os (not ol))
+ (while (and os (< os (point-max)) (not ol))
(setq os (semantic-overlay-next-change os))
(when os
;; Get overlays at position
@@ -247,13 +348,12 @@
(defun semantic-find-nonterminal-by-overlay-prev (&optional start buffer)
"Find the next nonterminal after START in BUFFER.
If START is in an overlay, find the token which starts next,
-not the current token.
-UNTRUSTED"
+not the current token."
(save-excursion
(if buffer (set-buffer buffer))
(if (not start) (setq start (point)))
(let ((os start) (ol nil))
- (while (and os (not ol))
+ (while (and os (> os (point-min)) (not ol))
(setq os (semantic-overlay-previous-change os))
(when os
;; Get overlays at position
@@ -274,88 +374,305 @@
If there are more than one in the same location, return the
smallest token."
(car (nreverse (semantic-find-nonterminal-by-overlay))))
+
+;;; Nonterminal regions and splicing
+;;
+;; This functionality is needed to take some set of dirty code,
+;; and splice in new tokens after a partial reparse.
-(defun semantic-find-nonterminal-by-token (token streamorbuffer)
- "Find all nonterminals with a token TOKEN within STREAMORBUFFER.
-TOKEN is a symbol."
- (let ((stream (if (bufferp streamorbuffer)
- (save-excursion
- (set-buffer streamorbuffer)
- (semantic-bovinate-toplevel))
- streamorbuffer))
- (nl nil))
- (while stream
- (if (eq token (semantic-token-token (car stream)))
- (setq nl (cons (car stream) nl)))
- (setq stream (cdr stream)))
- (nreverse nl)))
+(defun semantic-change-function-mark-dirty (start end length)
+ "Run whenever a buffer controlled by `semantic-mode' changes.
+Tracks when and how the buffer is re-parsed.
+Argument START, END, and LENGTH specify the bounds of the change."
+ (when (and (not semantic-toplevel-bovine-cache-check)
+ (not semantic-edits-are-safe))
+ (let ((tl (condition-case nil
+ (nreverse (semantic-find-nonterminal-by-overlay-in-region
+ (1- start) (1+ end)))
+ (error nil))))
+ (if tl
+ (catch 'alldone
+ ;; Loop over the token list
+ (while tl
+ (cond
+ ;; If we are completely enclosed in this overlay.
+ ((and (> start (semantic-token-start (car tl)))
+ (< end (semantic-token-end (car tl))))
+ (if (semantic-token-get (car tl) 'dirty)
+ nil
+ (add-to-list 'semantic-dirty-tokens (car tl))
+ (semantic-token-put (car tl) 'dirty t)
+ (condition-case nil
+ (run-hook-with-args 'semantic-dirty-token-hooks
+ (car tl) start end)
+ (error (if debug-on-error (debug)))))
+ (throw 'alldone t))
+ ;; If we cover the beginning or end of this item, we must
+ ;; reparse this object. If there are more items coming, then postpone
+ ;; this till later.
+ ((not (cdr tl))
+ (setq semantic-toplevel-bovine-cache-check t)
+ (run-hooks 'semantic-reparse-needed-change-hook))
+ (t nil))
+ ;; next
+ (setq tl (cdr tl))))
+ ;; There was no hit, perhaps we need to reparse this intermediate area.
+ (setq semantic-toplevel-bovine-cache-check t)
+ )
+ )))
+;;
+;; Properties set on the tokens are:
+;; dirty - This token is dirty
+;; dirty-after - This token, and the white space after it is dirty
+;; dirty-before - This token, and the white space before it is dirty
+;; dirty-children - This token has children that are dirty.
+;;
+;; EXPERIMENTAL
+(defsubst semantic-find-nearby-dirty-tokens (beg end)
+ "Make a special kind of token for dirty whitespace.
+Argument BEG and END is the region to find nearby tokens.
+EXPERIMENTAL"
+ (let ((prev (semantic-find-nonterminal-by-overlay-prev beg))
+ (next (semantic-find-nonterminal-by-overlay-next end)))
+ (if prev (semantic-token-put prev 'dirty-after t))
+ (if next (semantic-token-put next 'dirty-before t))
+ (list prev next)))
+
+(defun semantic-set-tokens-dirty-in-region (beg end)
+ "Mark the region between BEG and END as dirty.
+This is done by finding tokens overlapping the region, and marking
+them dirty. Regions not covered by a token are then marked as
+dirty-after, meaning the space after that area is dirty.
+This function will be called in an after change hook, and must
+be very fast.
+EXPERIMENTAL"
+ (let ((tromp (semantic-find-nonterminal-by-overlay-in-region beg end))
+ (ttmp nil)
+ )
+ (if (not tromp)
+ ;; No tokens hit, setup a dirty region on the screen.
+ (setq tromp nil) ;(semantic-get-dirty-token beg end))
+ ;; First, mark all fully dirty tokens.
+ (setq ttmp tromp)
+ (while ttmp
+ (and (> beg (semantic-token-start (car tromp)))
+ (< end (semantic-token-end (car tromp))))
-(defun semantic-find-nonterminal-standard (streamorbuffer)
- "Find all nonterminals in STREAMORBUFFER which define simple token types."
- (let ((stream (if (bufferp streamorbuffer)
+ )
+ )))
+
+
+;;; Generalized nonterminal searching
+;;
+;; These functions will search through nonterminal lists explicity for
+;; desired information.
+
+;; The -by-name nonterminal search can use the built in fcn
+;; `assoc', which is faster than looping ourselves, so we will
+;; not use `semantic-find-nonterminal-by-function' to do this,
+;; instead erroring on the side of speed.
+(defun semantic-find-nonterminal-by-name
+ (name streamorbuffer &optional search-parts search-include)
+ "Find a nonterminal NAME within STREAMORBUFFER. NAME is a string.
+If SEARCH-PARTS is non-nil, search children of tokens.
+If SEARCH-INCLUDE is non-nil, search include files."
+ (let* ((stream (if (bufferp streamorbuffer)
(save-excursion
(set-buffer streamorbuffer)
(semantic-bovinate-toplevel))
streamorbuffer))
- (nl nil))
- (while stream
- (if (member (semantic-token-token (car stream))
- '(function variable type))
- (setq nl (cons (car stream) nl)))
- (setq stream (cdr stream)))
- (nreverse nl)))
+ (assoc-fun (if semantic-case-fold
+ #'assoc-ignore-case
+ #'assoc))
+ (m (funcall assoc-fun name stream)))
+ (if m
+ m
+ (let ((toklst stream)
+ (children nil))
+ (while (and (not m) toklst)
+ (if search-parts
+ (progn
+ (setq children (semantic-nonterminal-children (car toklst) t))
+ (if children
+ (setq m (semantic-find-nonterminal-by-name
+ name children search-parts search-include)))))
+ (setq toklst (cdr toklst)))
+ (if (not m)
+ ;; Go to dependencies, and search there.
+ nil)
+ m))))
+
+(defmacro semantic-find-nonterminal-by-token
+ (token streamorbuffer &optional search-parts search-includes)
+ "Find all nonterminals with a token TOKEN within STREAMORBUFFER.
+TOKEN is a symbol representing the type of the tokens to find.
+Optional argument SEARCH-PARTS and SEARCH-INCLUDE are passed to
+`semantic-find-nonterminal-by-function'."
+ `(semantic-find-nonterminal-by-function
+ (lambda (tok) (eq ,token (semantic-token-token tok)))
+ ,streamorbuffer ,search-parts ,search-includes))
+
+(defmacro semantic-find-nonterminal-standard
+ (streamorbuffer &optional search-parts search-includes)
+ "Find all nonterminals in STREAMORBUFFER which define simple token types.
+Optional argument SEARCH-PARTS and SEARCH-INCLUDE are passed to
+`semantic-find-nonterminal-by-function'."
+ `(semantic-find-nonterminal-by-function
+ (lambda (tok) (member tok '(function variable type)))
+ ,streamorbuffer ,search-parts ,search-includes))
(defvar semantic-default-built-in-types nil
"For a given language, a set of built-in types.")
(make-variable-buffer-local 'semantic-default-built-in-types)
-(defun semantic-find-nonterminal-by-type (type streamorbuffer)
+(defun semantic-find-nonterminal-by-type
+ (type streamorbuffer &optional search-parts search-includes)
"Find all nonterminals with type TYPE within STREAMORBUFFER.
-TYPE is a string."
- (let ((stream (if (bufferp streamorbuffer)
- (save-excursion
- (set-buffer streamorbuffer)
- (semantic-bovinate-toplevel))
- streamorbuffer))
- (nl nil) (ts nil))
- (if (member type semantic-default-built-in-types)
- (setq nl (list (list type 'type "built in")))
+TYPE is a string which is the name of the type of the token returned.
+Optional argument SEARCH-PARTS and SEARCH-INCLUDES are passed to
+`semantic-find-nonterminal-by-function'."
+ (if (member type semantic-default-built-in-types)
+ (list (list type 'type "built in"))
+ (semantic-find-nonterminal-by-function
+ (lambda (tok)
+ (let ((ts (semantic-token-type tok)))
+ (if (and (listp ts) (eq (semantic-token-token ts) 'type))
+ (setq ts (semantic-token-name ts)))
+ (equal type ts)))
+ streamorbuffer search-parts search-includes)))
+
+(defun semantic-find-nonterminal-by-type-regexp
+ (regexp streamorbuffer &optional search-parts search-includes)
+ "Find all nonterminals with type matching REGEXP within STREAMORBUFFER.
+REGEXP is a regular expression which matches the name of the type of the
+tokens returned.
+Optional argument SEARCH-PARTS and SEARCH-INCLUDES are passed to
+`semantic-find-nonterminal-by-function'."
+ (semantic-find-nonterminal-by-function
+ (lambda (tok)
+ (let ((ts (semantic-token-type tok)))
+ (if (listp ts)
+ (setq ts
+ (if (eq (semantic-token-token ts) 'type)
+ (semantic-token-name ts)
+ (car ts))))
+ (and ts (string-match regexp ts))))
+ streamorbuffer search-parts search-includes))
+
+(defmacro semantic-find-nonterminal-by-name-regexp
+ (regex streamorbuffer &optional search-parts search-includes)
+ "Find all nonterminals whose name match REGEX in STREAMORBUFFER.
+Optional argument SEARCH-PARTS and SEARCH-INCLUDES are passed to
+`semantic-find-nonterminal-by-function'."
+ `(semantic-find-nonterminal-by-function
+ (lambda (tok) (string-match ,regex (semantic-token-name tok)))
+ ,streamorbuffer ,search-parts ,search-includes)
+ )
+
+(defmacro semantic-find-nonterminal-by-property
+ (property value streamorbuffer &optional search-parts search-includes)
+ "Find all nonterminals with PROPERTY equal to VALUE in STREAMORBUFFER.
+Properties can be added with `semantic-token-put'.
+Optional argument SEARCH-PARTS and SEARCH-INCLUDES are passed to
+`semantic-find-nonterminal-by-function'."
+ `(semantic-find-nonterminal-by-function
+ (lambda (tok) (equal (semantic-token-get tok ,property) ,value))
+ ,streamorbuffer ,search-parts ,search-includes)
+ )
+
+(defmacro semantic-find-nonterminal-by-extra-spec
+ (spec streamorbuffer &optional search-parts search-includes)
+ "Find all nonterminals with a given SPEC in STREAMORBUFFER.
+SPEC is a symbol key into the modifiers association list.
+Optional argument SEARCH-PARTS and SEARCH-INCLUDES are passed to
+`semantic-find-nonterminal-by-function'."
+ `(semantic-find-nonterminal-by-function
+ (lambda (tok) (semantic-token-extra-spec tok ,spec))
+ ,streamorbuffer ,search-parts ,search-includes)
+ )
+
+(defmacro semantic-find-nonterminal-by-extra-spec-value
+ (spec value streamorbuffer &optional search-parts search-includes)
+ "Find all nonterminals with a given SPEC equal to VALUE in STREAMORBUFFER.
+SPEC is a symbol key into the modifiers association list.
+VALUE is the value that SPEC should match.
+Optional argument SEARCH-PARTS and SEARCH-INCLUDES are passed to
+`semantic-find-nonterminal-by-function'."
+ `(semantic-find-nonterminal-by-function
+ (lambda (tok) (equal (semantic-token-extra-spec tok ,spec) ,value))
+ ,streamorbuffer ,search-parts ,search-includes)
+ )
+
+(defun semantic-find-nonterminal-by-function
+ (function streamorbuffer &optional search-parts search-includes)
+ "Find all nonterminals in which FUNCTION match within STREAMORBUFFER.
+FUNCTION must return non-nil if an element of STREAM will be included
+in the new list.
+
+If optional argument SEARCH-PARTS is non-nil, all sub-parts of tokens
+are searched. The overloadable function `semantic-nonterminal-children' is
+used for the searching child lists. If SEARCH-PARTS is the symbol
+'positiononly, then only children that have positional information are
+searched.
+
+If SEARCH-INCLUDES is non-nil, then all include files are also
+searched for matches."
+ (let ((streamlist (list
+ (if (bufferp streamorbuffer)
+ (save-excursion
+ (set-buffer streamorbuffer)
+ (semantic-bovinate-toplevel))
+ streamorbuffer)))
+ (includes nil) ;list of includes
+ (stream nil) ;current stream
+ (sl nil) ;list of token children
+ (nl nil) ;new list
+ (case-fold-search semantic-case-fold))
+ (if search-includes
+ (setq includes (semantic-find-nonterminal-by-token
+ 'include (car streamlist))))
+ (while streamlist
+ (setq stream (car streamlist))
(while stream
- (setq ts (semantic-token-type (car stream)))
- (if (and (listp ts) (eq (semantic-token-token ts) 'type))
- (setq ts (semantic-token-name ts)))
- (if (equal type ts)
+ (if (funcall function (car stream))
(setq nl (cons (car stream) nl)))
- (setq stream (cdr stream))))
- (nreverse nl)))
-
-(defun semantic-find-nonterminal-by-function (function streamorbuffer)
- "Find all nonterminals which FUNCTION match within STREAMORBUFFER.
-FUNCTION must return non-nil if an element of STREAM will be included
-in the new list."
- (let ((stream (if (bufferp streamorbuffer)
- (save-excursion
- (set-buffer streamorbuffer)
- (semantic-bovinate-toplevel))
- streamorbuffer))
- (nl nil))
- (while stream
- (if (funcall function (car stream))
- (setq nl (cons (car stream) nl)))
- (setq stream (cdr stream)))
- (nreverse nl)))
+ (if search-parts
+ (progn
+ (setq sl (semantic-nonterminal-children
+ (car stream)
+ t
+ ))
+ (if sl
+ (setq nl (append nl (semantic-find-nonterminal-by-function
+ function sl
+ search-parts search-includes))))))
+ ;; next token
+ (setq stream (cdr stream)))
+ (setq streamlist (cdr streamlist)))
+ (setq nl (nreverse nl))
+; (while includes
+; (setq nl (append nl (semantic-find-nonterminal-by-function
+;
+; ))))
+ nl))
-(defun semantic-find-nonterminal-by-function-first-match (function
- streamorbuffer)
+(defun semantic-find-nonterminal-by-function-first-match
+ (function streamorbuffer &optional search-parts search-includes)
"Find the first nonterminal which FUNCTION match within STREAMORBUFFER.
FUNCTION must return non-nil if an element of STREAM will be included
-in the new list."
+in the new list.
+If optional argument SEARCH-PARTS, all sub-parts of tokens are searched.
+The overloadable function `semantic-nonterminal-children' is used for
+searching.
+If SEARCH-INCLUDES is non-nil, then all include files are also
+searched for matches."
(let ((stream (if (bufferp streamorbuffer)
(save-excursion
(set-buffer streamorbuffer)
(semantic-bovinate-toplevel))
streamorbuffer))
- (found nil))
+ (found nil)
+ (case-fold-search semantic-case-fold))
(while (and (not found) stream)
(if (funcall function (car stream))
(setq found (car stream)))
@@ -535,8 +852,13 @@
(if filter
(semantic-find-nonterminal-by-function filter stream)
(semantic-find-nonterminal-standard stream)))
+ (if (and default (string-match ":" prompt))
+ (setq prompt
+ (concat (substring prompt 0 (match-end 0))
+ " (default: " default ") ")))
(completing-read prompt stream nil t ""
- 'semantic-read-symbol-history default))
+ 'semantic-read-symbol-history
+ default))
(defun semantic-read-variable (prompt &optional default stream)
"Read a variable name from the user for the current buffer.
@@ -576,24 +898,52 @@
;; for tasks of that nature, and also provides reasonable defaults.
(defvar semantic-override-table nil
- "Buffer local semantic function overrides alist.
+ "Buffer local semantic function overrides obarray.
These overrides provide a hook for a `major-mode' to override specific
behaviors with respect to generated semantic toplevel nonterminals and
-things that these non-terminals are useful for.
-Each element must be of the form: (SYM . FUN)
-where SYM is the symbol to override, and FUN is the function to
-override it with.
+things that these non-terminals are useful for. Use the function
+`semantic-install-function-overrides' to install overrides.
+
Available override symbols:
SYBMOL PARAMETERS DESCRIPTION
+ `abbreviate-nonterminal' (tok & parent color) Return summary string.
+ `summarize-nonterminal' (tok & parent color) Return summary string.
+ `prototype-nonterminal' (tok & parent color) Return a prototype
string.
+ `concise-prototype-nonterminal' (tok & parent color) Return a concise prototype
string.
+ `uml-abbreviate-nonterminal' (tok & parent color) Return a UML standard
abbreviation string.
+
`find-dependency' (token) Find the dependency file
`find-nonterminal' (token & parent) Find token in buffer.
`find-documentation' (token & nosnarf) Find doc comments.
- `abbreviate-nonterminal' (token & parent) Return summery string.
- `summerize-nonterminal' (token & parent) Return summery string.
- `prototype-nonterminal' (token) Return a prototype string.
`prototype-file' (buffer) Return a file in which
prototypes are placed
+ `nonterminal-children' (token) Return first rate children.
+ These are children which may
+ contain overlays.
+ `nonterminal-protection' (token & parent) Protection (as a symbol)
+
+ CONTEXT FUNCTIONS:
+ `beginning-of-context' (& point) Move to the beginning of the
+ current context.
+ `end-of-context' (& point) Move to the end of the
+ current context.
+ `up-context' (& point) Move up one context level.
+ `get-local-variables' (& point) Get local variables.
+ `get-all-local-variables'(& point) Get all local variables.
+ `get-local-arguments' (& point) Get arguments to this function.
+
+ `end-of-command' Move to the end of the current
+ command
+ `beginning-of-command' Move to the beginning of the
+ current command
+ `ctxt-current-symbol' (& point) List of related symbols.
+ `ctxt-current-assignment'(& point) Variable being assigned to.
+ `ctxt-current-function' (& point) Function being called at point.
+ `ctxt-current-argument' (& point) The index to the argument of
+ the current function the cursor
+ is in.
+
Parameters mean:
& - Following parameters are optional
@@ -604,11 +954,448 @@
information in it.")
(make-variable-buffer-local 'semantic-override-table)
+(defun semantic-install-function-overrides (overrides &optional transient)
+ "Install function OVERRIDES in `semantic-override-table'.
+If optional TRANSIENT is non-nil installed overrides can in turn be
+overridden by next installation. OVERRIDES must be an alist. Each
+element must be of the form: (SYM . FUN) where SYM is the symbol to
+override, and FUN is the function to override it with."
+ (if (not (arrayp semantic-override-table))
+ (setq semantic-override-table (make-vector 13 nil)))
+ (let (sym sym-name fun override)
+ (while overrides
+ (setq override (car overrides)
+ overrides (cdr overrides)
+ sym-name (symbol-name (car override))
+ fun (cdr override))
+ (if (setq sym (intern-soft sym-name semantic-override-table))
+ (if (get sym 'override)
+ (set sym fun)
+ (or (equal (symbol-value sym) fun)
+ (message "Current `%s' function #'%s not overrode by
#'%s"
+ sym (symbol-value sym) fun)))
+ (setq sym (intern sym-name semantic-override-table))
+ (set sym fun))
+ (put sym 'override transient))))
+
(defun semantic-fetch-overload (sym)
- "Find and return the overload function for SYM."
- (let ((a (assq sym semantic-override-table)))
- (cdr a)))
+ "Find and return the overload function for SYM.
+Return nil if not found."
+ (symbol-value
+ (and (arrayp semantic-override-table)
+ (intern-soft (symbol-name sym) semantic-override-table))))
+
+;;; Token to text overload functions
+;;
+;; Abbreviations, prototypes, and coloring support.
+(eval-when-compile (require 'font-lock))
+
+(defvar semantic-token->text-functions
+ '(semantic-name-nonterminal
+ semantic-abbreviate-nonterminal
+ semantic-summarize-nonterminal
+ semantic-prototype-nonterminal
+ semantic-concise-prototype-nonterminal
+ semantic-uml-abbreviate-nonterminal
+ semantic-uml-prototype-nonterminal
+ )
+ "List of functions which convert a token to text.
+Each function must take the parameters TOKEN &optional PARENT COLOR.
+TOKEN is the token to convert.
+PARENT is a parent token or name which refers to the structure
+or class which contains TOKEN. PARENT is NOT a class which a TOKEN
+would claim as a parent.
+COLOR indicates that the generated text should be colored using
+`font-lock'.")
+
+(defvar semantic-token->text-custom-list
+ (append '(radio)
+ (mapcar (lambda (f) (list 'const f))
+ semantic-token->text-functions)
+ '(function))
+ "A List used by customizeable variables to choose a token to text function.
+Use this variable in the :type field of a customizable variable.")
+
+
+(defvar semantic-face-alist
+ `( (function . font-lock-function-name-face)
+ (variable . font-lock-variable-name-face)
+ (type . font-lock-type-face)
+ ;; These are different between Emacsen.
+ (include . ,(if (featurep 'xemacs)
+ 'font-lock-preprocessor-face
+ 'font-lock-constant-face))
+ (package . ,(if (featurep 'xemacs)
+ 'font-lock-preprocessor-face
+ 'font-lock-constant-face))
+ ;; Not a token, but instead a feature of output
+ (label . font-lock-string-face)
+ (comment . font-lock-comment-face)
+ (keyword . font-lock-keyword-face)
+ )
+ "Face used to colorize tokens of different types.
+Override the value locally if a language supports other token types.
+When adding new elements, try to use symbols also returned by the parser.
+The form of an entry in this list is of the form:
+ ( SYMBOL . FACE )
+where SYMBOL is a token type symbol used with semantic. FACE
+is a symbol representing a face.
+Faces used are generated in `font-lock' for consistency, and will not
+be used unless font lock is a feature.")
+
+;;; Coloring Functions
+(defun semantic-colorize-text (text face-class)
+ "Apply onto TEXT a color associated with FACE-CLASS.
+FACE-CLASS is a token type found in `semantic-face-alist'. See this variable
+for details on adding new types."
+ (let ((face (cdr-safe (assoc face-class semantic-face-alist)))
+ (newtext (concat text)))
+ (put-text-property 0 (length text) 'face face newtext)
+ newtext)
+ )
+
+;;; The token->text functions
+(defun semantic-name-nonterminal (token &optional parent color)
+ "Return the name string describing TOKEN.
+The name is the shortest possible representation.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let ((s (semantic-fetch-overload 'name-nonterminal))
+ tt)
+ ;; No colors without font lock
+ (if (not (featurep 'font-lock)) (setq color nil))
+ (if s
+ (funcall s token parent color)
+ (semantic-name-nonterminal-default token parent color))))
+
+(defun semantic-name-nonterminal-default (token &optional parent color)
+ "Return an abbreviated string describing TOKEN.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let ((name (semantic-token-name token)))
+ (if color
+ (setq name (semantic-colorize-text name (semantic-token-token token))))
+ name))
+
+(defun semantic-abbreviate-nonterminal (token &optional parent color)
+ "Return an abbreviated string describing TOKEN.
+The abbreviation is to be short, with possible symbols indicating
+the type of token, or other information.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let ((s (semantic-fetch-overload 'abbreviate-nonterminal)))
+ ;; No colors without font lock
+ (if (not (featurep 'font-lock)) (setq color nil))
+ (if s
+ (funcall s token parent color)
+ (semantic-abbreviate-nonterminal-default token parent color))))
+
+(defun semantic-abbreviate-nonterminal-default (token &optional parent color)
+ "Return an abbreviated string describing TOKEN.
+Optional argument PARENT is a parent token in the token hierarchy.
+In this case PARENT refers to containment, not inheritance.
+Optional argument COLOR means highlight the prototype with font-lock colors.
+This is a simple C like default."
+ ;; Do lots of complex stuff here.
+ (let ((tok (semantic-token-token token))
+ (name (semantic-name-nonterminal token parent color))
+ (suffix "")
+ str)
+ (cond ((eq tok 'function)
+ (setq suffix "()"))
+ ((eq tok 'include)
+ (setq suffix "<>"))
+ ((eq tok 'variable)
+ (setq suffix (if (semantic-token-variable-default token)
+ "=" "")))
+ )
+ (setq str (concat name suffix))
+ (if parent
+ (setq str
+ (concat (semantic-name-nonterminal parent color)
+ (car semantic-type-relation-separator-character)
+ str)))
+ str))
+
+;; Semantic 1.2.x had this misspelling. Keep it for backwards compatibiity.
+(defalias 'semantic-summerize-nonterminal 'semantic-summarize-nonterminal)
+
+(defun semantic-summarize-nonterminal (token &optional parent color)
+ "Summarize TOKEN in a reasonable way.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let ((s (semantic-fetch-overload 'summarize-nonterminal)))
+ ;; No colors without font lock
+ (if (not (featurep 'font-lock)) (setq color nil))
+ (if s
+ (funcall s token parent color)
+ (semantic-summarize-nonterminal-default token parent color)
+ )))
+
+(defun semantic-summarize-nonterminal-default (token &optional parent color)
+ "Summarize TOKEN in a reasonable way.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let ((proto (semantic-prototype-nonterminal token nil color))
+ (label (capitalize
+ (or (cdr-safe (assoc (semantic-token-token token)
+ semantic-symbol->name-assoc-list))
+ (symbol-name (semantic-token-token token))))))
+ (if color
+ (setq label (semantic-colorize-text label 'label)))
+ (concat label ": " proto))
+ )
+
+(defun semantic-prototype-nonterminal (token &optional parent color)
+ "Return a prototype for TOKEN.
+This function should be overloaded, though it need not be used.
+This is because it can be used to create code by language independent
+tools.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let ((s (semantic-fetch-overload 'prototype-nonterminal)))
+ ;; No colors without font lock
+ (if (not (featurep 'font-lock)) (setq color nil))
+ (if s
+ ;; Prototype is non-local
+ (funcall s token parent color)
+ (semantic-prototype-nonterminal-default token parent color))))
+
+(defun semantic-prototype-nonterminal-default-args (args color)
+ "Create a list of of strings for prototypes of ARGS.
+ARGS can be a list of terminals, or a list of strings.
+COLOR specifies if these arguments should be colored or not."
+ (let ((out nil))
+ (while args
+ (cond ((stringp (car args))
+ (let ((a (car args)))
+ (if color
+ (setq a (semantic-colorize-text a 'variable)))
+ (setq out (cons a out))
+ ))
+ ((semantic-token-p (car args))
+ (setq out
+ (cons (semantic-prototype-nonterminal (car args) nil t)
+ out))))
+ (setq args (cdr args)))
+ (nreverse out)))
+
+(defun semantic-prototype-nonterminal-default (token &optional parent color)
+ "Default method for returning a prototype for TOKEN.
+This will work for C like languages.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let* ((tok (semantic-token-token token))
+ (name (semantic-name-nonterminal token parent color))
+ (type (if (member tok '(function variable type))
+ (semantic-token-type token)))
+ (args (semantic-prototype-nonterminal-default-args
+ (cond ((eq tok 'function)
+ (semantic-token-function-args token))
+ ((eq tok 'type)
+ (semantic-token-type-parts token))
+ (t nil))
+ color))
+ (const (semantic-token-extra-spec token 'const))
+ (mods (append
+ (if const '("const") nil)
+ (semantic-token-extra-spec token 'typemodifiers)))
+ (array (if (eq tok 'variable)
+ (let ((deref
+ (semantic-token-variable-extra-spec
+ token 'dereference))
+ (r ""))
+ (while (and deref (/= deref 0))
+ (setq r (concat r "[]")
+ deref (1- deref)))
+ r)))
+ (suffix (if (eq tok 'variable)
+ (semantic-token-variable-extra-spec token 'suffix)))
+ )
+ (if (and (listp mods) mods)
+ (setq mods (concat (mapconcat (lambda (a) a) mods " ") " ")))
+ (if (and mods color)
+ (setq mods (semantic-colorize-text mods 'type)))
+ (if args
+ (setq args
+ (concat " "
+ (if (eq tok 'type) "{" "(")
+ (mapconcat (lambda (a) a) args ",")
+ (if (eq tok 'type) "}" ")"))))
+ (if type
+ (if (semantic-token-p type)
+ (setq type (semantic-prototype-nonterminal type nil color))
+ (if (listp type)
+ (setq type (car type)))
+ (if color
+ (setq type (semantic-colorize-text type 'type)))))
+ (concat (or mods "")
+ (if type (concat type " "))
+ name
+ (or args "")
+ (or array ""))))
+
+(defun semantic-concise-prototype-nonterminal (token &optional parent color)
+ "Return a concise prototype for TOKEN.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let ((s (semantic-fetch-overload 'concise-prototype-nonterminal)))
+ (if s
+ (funcall s token parent color)
+ (semantic-concise-prototype-nonterminal-default token parent color))))
+
+(defun semantic-concise-prototype-nonterminal-default (token &optional parent
color)
+ "Return a concise prototype for TOKEN.
+This default function will make a cheap concise prototype using C like syntax.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let ((tok (semantic-token-token token)))
+ (cond
+ ((eq tok 'type)
+ (concat (semantic-name-nonterminal token parent color) "{}"))
+ ((eq tok 'function)
+ (let ((args (semantic-token-function-args token)))
+ (concat (semantic-name-nonterminal token parent color)
+ "("
+ (if args
+ (cond ((stringp (car args))
+ (mapconcat
+ (if color
+ (lambda (a) (semantic-colorize-text
+ a 'variable))
+ 'identity)
+ args ","))
+ ((semantic-token-p (car args))
+ (mapconcat
+ (lambda (a)
+ (let ((ty (semantic-token-type a)))
+ (cond ((and (stringp ty) color)
+ (semantic-colorize-text ty 'type))
+ ((stringp ty)
+ ty)
+ ((semantic-token-p ty)
+ (semantic-prototype-nonterminal
+ ty parent nil))
+ ((and (consp ty) color)
+ (semantic-colorize-text (car ty) 'type))
+ ((consp ty)
+ (car ty))
+ (t (error "Concice-prototype")))))
+ args ", "))
+ ((consp (car args))
+ (mapconcat
+ (if color
+ (lambda (a)
+ (semantic-colorize-text (car a) 'type))
+ 'car)
+ args ","))
+ (t (error "Concice-prototype")))
+ "")
+ ")")))
+ ((eq tok 'variable)
+ (let* ((deref (semantic-token-variable-extra-spec
+ token 'dereference))
+ (array "")
+ (suffix (semantic-token-variable-extra-spec
+ token 'suffix)))
+ (while (and deref (/= deref 0))
+ (setq array (concat array "[]")
+ deref (1- deref)))
+ (concat (semantic-name-nonterminal token parent nil)
+ array)))
+ (t
+ (semantic-abbreviate-nonterminal token parent nil)))))
+
+(defun semantic-uml-protection-to-string (protection-symbol)
+ "Convert PROTECTION-SYMBOL to a string for UML."
+ (cond ((eq protection-symbol 'public)
+ "+")
+ ((eq protection-symbol 'private)
+ "-")
+ ((eq protection-symbol 'protected)
+ "#")
+ (t " ")))
+
+(defun semantic-uml-abbreviate-nonterminal (token &optional parent color)
+ "Return a UML style abbreviation for TOKEN.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let ((s (semantic-fetch-overload 'uml-abbreviate-nonterminal)))
+ (if s
+ (funcall s token parent color)
+ (semantic-uml-abbreviate-nonterminal-default token parent color))))
+(defun semantic-uml-abbreviate-nonterminal-default (token &optional parent color)
+ "Return a UML style abbreviation for TOKEN.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let* ((tok (semantic-token-token token))
+ (name (semantic-name-nonterminal token parent color))
+ (type (or (semantic-token-type token) ""))
+ (prot (semantic-nonterminal-protection token parent))
+ )
+ (setq type
+ (cond ((semantic-token-p type)
+ (semantic-prototype-nonterminal type nil color))
+ ((listp type)
+ (car type))
+ ((stringp type)
+ type)
+ (t nil)))
+ (if (and type color)
+ (setq type (semantic-colorize-text type 'type)))
+ (setq prot (semantic-uml-protection-to-string prot))
+ (if type
+ (concat prot name ":" type)
+ name)
+ ))
+
+(defun semantic-uml-prototype-nonterminal (token &optional parent color)
+ "Return a UML style prototype for TOKEN.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let ((s (semantic-fetch-overload 'uml-prototype-nonterminal)))
+ (if s
+ (funcall s token parent color)
+ (semantic-uml-prototype-nonterminal-default token parent color))))
+
+(defun semantic-uml-prototype-nonterminal-default (token &optional parent color)
+ "Return a UML style abbreviation for TOKEN.
+Optional argument PARENT is the parent type if TOKEN is a detail.
+Optional argument COLOR means highlight the prototype with font-lock colors."
+ (let* ((tok (semantic-token-token token))
+ (name (semantic-name-nonterminal token parent color))
+ (type (or (semantic-token-type token) ""))
+ (args (semantic-prototype-nonterminal-default-args
+ (cond ((eq tok 'function)
+ (semantic-token-function-args token))
+ (t nil))
+ color))
+ (prot (semantic-nonterminal-protection token parent))
+ )
+ (if type
+ (if (semantic-token-p type)
+ (setq type (semantic-prototype-nonterminal type nil color))
+ (if (listp type)
+ (setq type (car type)))
+ (if color
+ (setq type (semantic-colorize-text type 'type)))))
+ (setq prot (semantic-uml-protection-to-string prot))
+ (if args
+ (setq args
+ (concat " "
+ (if (eq tok 'type) "{" "(")
+ (mapconcat (lambda (a) a) args ",")
+ (if (eq tok 'type) "}" ")"))))
+ (if type
+ (concat prot name (or args "") ":" type)
+ name)
+ ))
+
+
+
+;;; Multi-file Token information
+;;
(defvar semantic-dependency-include-path nil
"Defines the include path used when searching for files.
This should be a list of directories to search which is specific to
@@ -627,6 +1414,9 @@
(if (not token)
(setq token (car (semantic-find-nonterminal-by-overlay nil))))
+ (if (not (eq (semantic-token-token token) 'include))
+ (signal 'wrong-type-argument (list token 'include)))
+
;; First, see if this file exists in the current EDE projecy
(if (and (fboundp 'ede-expand-filename) ede-minor-mode
(ede-expand-filename (ede-toplevel)
@@ -668,20 +1458,29 @@
nil
(let ((s (semantic-fetch-overload 'find-nonterminal)))
(if s (funcall s token parent)
- (set-buffer (semantic-token-buffer token))
- (let ((start (semantic-token-start token)))
- (if (numberp start)
- ;; If it's a number, go there
- (goto-char start)
- ;; Otherwise, it's a trimmed vector, such as a parameter,
- ;; or a structure part.
- (if (not parent)
- nil
- (goto-char (semantic-token-start parent))
- ;; Here we make an assumtion that the text returned by
- ;; the bovinator and concocted by us actually exists
- ;; in the buffer.
- (re-search-forward (semantic-token-name token) nil t))))))))
+ (if (semantic-token-buffer token)
+ ;; If the token has no buffer, it may be deoverlayed.
+ ;; Assume the tool doing the finding knows that we came
+ ;; in from a database, and use the current buffer.
+ (set-buffer (semantic-token-buffer token)))
+ (if (semantic-token-with-position-p token)
+ ;; If it's a number, go there
+ (goto-char (semantic-token-start token))
+ ;; Otherwise, it's a trimmed vector, such as a parameter,
+ ;; or a structure part.
+ (if (not parent)
+ nil
+ (if (semantic-token-with-position-p parent)
+ (progn
+ (if (semantic-token-buffer parent)
+ ;; If this parent token has no buffer, then it
+ ;; may be deoverlayed.
+ (set-buffer (semantic-token-buffer parent)))
+ (goto-char (semantic-token-start parent))
+ ;; Here we make an assumtion that the text returned by
+ ;; the bovinator and concocted by us actually exists
+ ;; in the buffer.
+ (re-search-forward (semantic-token-name token) nil t)))))))))
(defun semantic-find-documentation (&optional token nosnarf)
"Find documentation from TOKEN and return it as a clean string.
@@ -702,8 +1501,10 @@
(or
;; Is there doc in the token???
(if (semantic-token-docstring token)
- (progn (goto-char (semantic-token-docstring token))
- (semantic-find-doc-snarf-comment nosnarf)))
+ (if (stringp (semantic-token-docstring token))
+ (semantic-token-docstring token)
+ (goto-char (semantic-token-docstring token))
+ (semantic-find-doc-snarf-comment nosnarf)))
;; Check just before the definition.
(save-excursion
(re-search-backward comment-start-skip nil t)
@@ -749,84 +1550,6 @@
;; Now return the text.
ct))))
-(defun semantic-abbreviate-nonterminal (token &optional parent)
- "Return an abbreviated string describing TOKEN.
-The abbreviation is to be short, with possible symbols indicating
-the type of token, or other information.
-Optional argument PARENT is the parent type if TOKEN is a detail."
- (let ((s (semantic-fetch-overload 'abbreviate-nonterminal))
- tt)
- (if s
- (funcall s token parent)
- ;; Do lots of complex stuff here.
- (let ((tok (semantic-token-token token))
- (name (semantic-token-name token)))
- (concat name
- (cond ((eq tok 'function) "()")
- ((eq tok 'include) "<>")
- ((and (eq tok 'variable)
- (semantic-token-variable-default token))
- "=")))
- ))))
-
-(defun semantic-summerize-nonterminal (token &optional parent)
- "Summerize TOKEN in a reasonable way.
-Optional argument PARENT is the parent type if TOKEN is a detail."
- (let ((s (semantic-fetch-overload 'summerize-nonterminal)))
- (if s
- (funcall s token parent)
- ;; FLESH THIS OUT MORE
- (concat (or (capitalize
- (cdr-safe (assoc (semantic-token-token token)
- semantic-symbol->name-assoc-list)))
- (capitalize (symbol-name (semantic-token-token token))))
- ": "
- (semantic-prototype-nonterminal token)))))
-
-(defun semantic-prototype-nonterminal (token)
- "Return a prototype for TOKEN.
-This functin must be overloaded, though it need not be used."
- (let ((tt (semantic-token-token token))
- (s (semantic-fetch-overload 'prototype-nonterminal)))
- (if s
- ;; Prototype is non-local
- (funcall s token)
- ;; Cococt a cheap prototype
- (let* ((tok (semantic-token-token token))
- (type (if (member tok '(function variable type))
- (semantic-token-type token) ""))
- (args (cond ((eq tok 'function)
- (semantic-token-function-args token))
- ((eq tok 'type)
- (semantic-token-type-parts token))
- (t nil)))
- (mods (cond ((eq tok 'variable)
- (semantic-token-variable-modifiers token))
- ((eq tok 'function)
- (semantic-token-function-modifiers token))
- ((eq tok 'type)
- (semantic-token-type-modifiers token))
- (t nil)))
- (array (if (eq tok 'variable)
- (semantic-token-variable-optsuffix token)))
- )
- (if (and (listp mods) mods)
- (setq mods (concat (mapconcat (lambda (a) a) mods " ") " ")))
- (if args
- (setq args
- (concat " " (if (eq tok 'type) "{" "(")
- (if (stringp (car args))
- (mapconcat (lambda (a) a) args ",")
- (mapconcat 'car args ","))
- (if (eq tok 'type) "}" ")"))))
- (if (and type (listp type))
- (setq type (car type)))
- (concat (or mods "")
- (if type (concat type " "))
- (semantic-token-name token)
- (or args "")
- (or array ""))))))
-
(defun semantic-prototype-file (buffer)
"Return a file in which prototypes belonging to BUFFER should be placed.
Default behavior (if not overriden) looks for a token specifying the
@@ -846,6 +1569,83 @@
(if (re-search-forward "::Header:: \\([a-zA-Z0-9.]+\\)" nil t)
(match-string 1)))))))
+
+;;;; Mode-specific Token information
+;;
+(defun semantic-nonterminal-children (token &optional positionalonly)
+ "Return the list of top level children belonging to TOKEN.
+Children are any sub-tokens which may contain overlays.
+The default behavior (if not overriden with `nonterminal-children'
+is to return type parts for a type, and arguments for a function.
+
+If optional argument POSITIONALONLY is non-nil, then only return valid
+children if they contain positions. Some languages may choose to create
+lists of children without position/overlay information.
+
+If this function is overriden, use `semantic-nonterminal-children-default'
+to also include the default behavior, and merely extend your own.
+
+Note for language authors:
+ If a mode defines a language that has tokens in it with overlays that
+should not be considered children, you should still return them with
+this function."
+ (let* ((s (semantic-fetch-overload 'nonterminal-children))
+ (chil (if s (funcall s token)
+ (semantic-nonterminal-children-default token))))
+ (if (or (not positionalonly)
+ (semantic-token-with-position-p (car chil)))
+ chil
+ nil)))
+
+(defun semantic-nonterminal-children-default (token)
+ "Return the children of TOKEN.
+For types, return the type parts.
+For functions return the argument list."
+ (cond ((eq (semantic-token-token token) 'type)
+ (semantic-token-type-parts token))
+ ((eq (semantic-token-token token) 'function)
+ (semantic-token-function-args token))
+ (t nil)))
+
+(defun semantic-nonterminal-protection (token &optional parent)
+ "Return protection information about TOKEN with optional PARENT.
+This function returns on of the following symbols:
+ nil - No special protection. Language dependent.
+ 'public - Anyone can access this TOKEN.
+ 'private - Only methods in the local scope can access TOKEN.
+ 'protected - Like private for outside scopes, like public for child
+ classes.
+Some languages may choose to provide additional return symbols specific
+to themselves. Use of this function should allow for this.
+
+The default behavior (if not overriden with `nonterminal-children'
+is to return a symbol based on type modifiers."
+ (let* ((s (semantic-fetch-overload 'nonterminal-protection)))
+ (if s (funcall s token parent)
+ (semantic-nonterminal-protection-default token parent))))
+
+(defun semantic-nonterminal-protection-default (token &optional parent)
+ "Return the protection of TOKEN as a child of PARENT default action.
+See `semantic-nonterminal-protection'."
+ (let ((mods (semantic-token-modifiers token))
+ (prot nil))
+ (while (and (not prot) mods)
+ (if (stringp (car mods))
+ (let ((s (car mods)))
+ ;; A few silly defaults to get things started.
+ (cond ((or (string= s "public")
+ (string= s "extern")
+ (string= s "export"))
+ 'public)
+ ((or (string= s "private")
+ (string= s "static"))
+ 'private)
+ ((string= s "protected")
+ 'protected))))
+ (setq mods (cdr mods)))
+ prot))
+
+
;;; Do some fancy stuff with overlays
;;
(defun semantic-highlight-token (token &optional face)
@@ -889,15 +1689,27 @@
(semantic-overlay-put (semantic-token-overlay token) 'invisible
(not visible)))
+(defun semantic-token-invisible-p (token)
+ "Return non-nil if TOKEN is invisible."
+ (semantic-overlay-get (semantic-token-overlay token) 'invisible))
+
(defun semantic-set-token-intangible (token &optional tangible)
"Enable the text in TOKEN to be made intangible.
-If TANGIBLE is non-nil, make the text visible."
+If TANGIBLE is non-nil, make the text visible.
+This function does not have meaning in XEmacs because it seems that
+the extent 'intangible' property does not exist."
(semantic-overlay-put (semantic-token-overlay token) 'intangible
(not tangible)))
+(defun semantic-token-intangible-p (token)
+ "Return non-nil if TOKEN is intangible.
+This function does not have meaning in XEmacs because it seems that
+the extent 'intangible' property does not exist."
+ (semantic-overlay-get (semantic-token-overlay token) 'intangible))
+
(defun semantic-overlay-signal-read-only
(overlay after start end &optional len)
- "Hook used in modification hooks to preventi modification.
+ "Hook used in modification hooks to prevent modification.
Allows deletion of the entire text.
Argument OVERLAY, AFTER, START, END, and LEN are passed in by the system."
;; Stolen blithly from cpp.el in Emacs 21.1
@@ -912,36 +1724,114 @@
instead of read-only."
(let ((o (semantic-token-overlay token))
(hook (if writable nil '(semantic-overlay-signal-read-only))))
- (semantic-overlay-put o 'modification-hooks hook)
- (semantic-overlay-put o 'insert-in-front-hooks hook)
- (semantic-overlay-put o 'insert-behind-hooks hook)))
+ (if (featurep 'xemacs)
+ ;; XEmacs extents have a 'read-only' property.
+ (semantic-overlay-put o 'read-only (not writable))
+ (semantic-overlay-put o 'modification-hooks hook)
+ (semantic-overlay-put o 'insert-in-front-hooks hook)
+ (semantic-overlay-put o 'insert-behind-hooks hook))))
+(defun semantic-token-read-only-p (token)
+ "Return non-nil if the current TOKEN is marked read only."
+ (let ((o (semantic-token-overlay token)))
+ (if (featurep 'xemacs)
+ ;; XEmacs extents have a 'read-only' property.
+ (semantic-overlay-get o 'read-only)
+ (member 'semantic-overlay-signal-read-only
+ (semantic-overlay-get o 'modification-hooks)))))
+
+(defun semantic-narrow-to-token (token)
+ "Narrow to the region specified by TOKEN."
+ (narrow-to-region (semantic-token-start token)
+ (semantic-token-end token)))
+
;;; Interactive Functions for bovination
;;
-(eval-when-compile
- (condition-case nil (require 'pp) (error nil)))
+(defun semantic-describe-token (&optional token)
+ "Describe TOKEN in the minibuffer.
+If TOKEN is nil, describe the token under the cursor."
+ (interactive)
+ (if (not token) (setq token (semantic-current-nonterminal)))
+ (semantic-bovinate-toplevel t)
+ (if token (message (semantic-summarize-nonterminal token))))
-(defun bovinate (&optional clear)
- "Bovinate the current buffer. Show output in a temp buffer.
-Optional argument CLEAR will clear the cache before bovinating."
- (interactive "P")
- (if clear (semantic-clear-toplevel-cache))
- (let ((out (semantic-bovinate-toplevel)))
- (pop-to-buffer "*BOVINATE*")
- (require 'pp)
- (erase-buffer)
- (insert (pp-to-string out))
- (goto-char (point-min))))
+
+;;; Putting keys on tokens.
+;;
+(defun semantic-add-label (label value &optional token)
+ "Add a LABEL with VALUE on TOKEN.
+If TOKEN is not specified, use the token at point."
+ (interactive "sLabel: \nXValue (eval): ")
+ (if (not token)
+ (progn
+ (semantic-bovinate-toplevel t)
+ (setq token (semantic-current-nonterminal))))
+ (semantic-token-put token (intern label) value)
+ (message "Added label %s with value %S" label value))
+
+(defun semantic-show-label (label &optional token)
+ "Show the value of LABEL on TOKEN.
+If TOKEN is not specified, use the token at point."
+ (interactive "sLabel: ")
+ (if (not token)
+ (progn
+ (semantic-bovinate-toplevel t)
+ (setq token (semantic-current-nonterminal))))
+ (message "%s: %S" label (semantic-token-get token (intern label))))
-(defun bovinate-debug ()
- "Bovinate the current buffer and run in debug mode."
- (interactive)
- (let ((semantic-edebug t)
- (out (semantic-bovinate-debug-buffer)))
- (pop-to-buffer "*BOVINATE*")
- (require 'pp)
- (erase-buffer)
- (insert (pp-to-string out))))
+
+;;; Show dirty mode
+;;
+;;;###autoload
+(defcustom semantic-show-dirty-mode nil
+ "*If non-nil enable the use of `semantic-show-dirty-mode'."
+ :group 'semantic
+ :type 'boolean
+ :require 'semantic-util
+ :initialize 'custom-initialize-default
+ :set (lambda (sym val)
+ (semantic-show-dirty-mode (if val 1 -1))
+ (custom-set-default sym val)))
+
+(defface semantic-dirty-token-face '((((class color) (background dark))
+ (:background "gray10"))
+ (((class color) (background light))
+ (:background "gray90")))
+ "Face used to show dirty tokens in `semantic-show-dirty-token-mode'."
+ :group 'semantic)
+
+(defun semantic-show-dirty-token-hook-fcn (token start end)
+ "Function set into `semantic-dirty-token-hooks'.
+This will highlight TOKEN as dirty.
+START and END define the region changed, but are not used."
+ (semantic-highlight-token token 'semantic-dirty-token-face))
+
+(defun semantic-show-clean-token-hook-fcn (token)
+ "Function set into `semantic-clean-token-hooks'.
+This will unhighlight TOKEN from being dirty."
+ (semantic-unhighlight-token token))
+
+(defun semantic-show-dirty-mode (&optional arg)
+ "Enable the display of dirty tokens.
+If ARG is positive, enable, if it is negative, disable.
+If ARG is nil, then toggle."
+ (interactive "P")
+ (if (not arg)
+ (if (member #'semantic-show-dirty-token-hook-fcn
+ semantic-dirty-token-hooks)
+ (setq arg -1)
+ (setq arg 1)))
+ (if (< arg 0)
+ (progn
+ ;; Remove hooks
+ (remove-hook 'semantic-dirty-token-hooks 'semantic-show-dirty-token-hook-fcn)
+ (remove-hook 'semantic-clean-token-hooks 'semantic-show-clean-token-hook-fcn)
+ (remove-hook 'after-save-hook 'semantic-rebovinate-quickly-hook)
+ )
+ (add-hook 'semantic-dirty-token-hooks 'semantic-show-dirty-token-hook-fcn)
+ (add-hook 'semantic-clean-token-hooks 'semantic-show-clean-token-hook-fcn)
+ (add-hook 'after-save-hook 'semantic-rebovinate-quickly-hook)
+ ))
;;; Hacks
;;
@@ -950,11 +1840,11 @@
"Display the curent token.
Argument P is the point to search from in the current buffer."
(interactive "d")
- (message
- (mapconcat
- 'semantic-abbreviate-nonterminal
- (semantic-find-innermost-nonterminal-by-position p (current-buffer))
- ",")))
+ (let ((tok (semantic-find-innermost-nonterminal-by-position
+ p (current-buffer))))
+ (message (mapconcat 'semantic-abbreviate-nonterminal tok ","))
+ (car tok))
+ )
(defun semantic-hack-search ()
"Disply info about something under the cursor using generic methods."
Index: xemacs-packages/semantic/semantic.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/semantic/semantic.el,v
retrieving revision 1.7
diff -u -r1.7 semantic.el
--- xemacs-packages/semantic/semantic.el 2001/02/20 03:23:45 1.7
+++ xemacs-packages/semantic/semantic.el 2001/08/15 05:28:22
@@ -3,10 +3,12 @@
;;; Copyright (C) 1999, 2000, 2001 Eric M. Ludlam
;; Author: Eric M. Ludlam <zappo(a)gnu.org>
-;; Version: 1.3.3
;; Keywords: syntax
-;; X-RCS: $Id: semantic.el,v 1.7 2001/02/20 03:23:45 youngs Exp $
+;; X-RCS: $Id: semantic.el,v 1.107 2001/07/13 15:39:35 zappo Exp $
+(defvar semantic-version "1.4beta8"
+ "Current version of Semantic.")
+
;; This file is not part of GNU Emacs.
;; Semantic is free software; you can redistribute it and/or modify
@@ -32,192 +34,14 @@
;; The output of a semantic bovine parse is parse tree. While it is
;; possible to assign actions in the bovine-table in a similar fashion
;; to bison, this is not it's end goal.
-;;
-;; Bovine Table Tips & Tricks:
-;; ---------------------------
-;;
-;; Many of the tricks needed to create rules in bison or yacc can be
-;; used here. The exceptions to this rule are that there is no need to
-;; declare bison tokens, and you cannot put "code" in the middle of a
-;; match rule. In addition, you should avoid empty matching rules as
-;; I haven't quite gotten those to be reliable yet.
-;;
-;; The top-level bovine table is an association list of all the rules
-;; needed to parse your language, or language segment. It is easiest
-;; to create one master rule file, and call the semantic bovinator on
-;; subsections passing down the nonterminal rule you want to match.
-;;
-;; Thus, every entry in the bovine table is of the form:
-;; ( NONTERMINAL-SYMBOL MATCH-LIST )
-;;
-;; The nonterminal symbol is equivalent to the bison RESULT, and the
-;; MATCH-LIST is equivalent to the bison COMPONENTS. Thus, the bison
-;; rule:
-;; expseq: expseq1
-;; | expseq2
-;; ;
-;; becomes:
-;; ( expseq ( expseq1 ) ( expseq2 ) )
-;; which defines RESULT expseq which can be either COMPONENT expseq1
-;; or expseq2. These two table entries also use nonterminal results,
-;; and also use the DEFAULT RESULT LAMBDA (see below for details on
-;; the RESULT LAMBDA).
-;;
-;; You can also have recursive rules, as in bison. For example the
-;; bison rule:
-;; expseq1: exp
-;; | expseq1 ',' exp
-;; ;
-;; becomes:
-;; (expseq1 (exp)
-;; (expseq1 punctuation "," exp
-;; (lambda (val start end)
-;; ( -generator code- ))))
-;;
-;; This time, the second rule uses it's own RESULT LAMBDA.
-;;
-;; Lastly, you can also have STRING LITERALS in your rules, though
-;; these are different from Bison. As can be seen above, a literal is
-;; a constant lexed symbol, such as `punctuation', followed by a string
-;; which is a *regular expression* which must match, or this rule will
-;; fail.
-;;
-;; In BISON, a given rule can have inline ACTIONS. In the semantic
-;; bovinator, there can be only one ACTION which I will refer to here
-;; as the RESULT LAMBDA. There are two default RESULT LAMBDAs which
-;; can be used which cover the default case. The RESULT LAMBDA must
-;; return a valid nonterminal token. A nonterminal token is always of the
-;; form ( NAME TOKEN VALUE1 VALUE2 ... START END). NAME is the name
-;; to use for this token. It is first so that a list of tokens is
-;; also an alist, or completion table. Token should be the same
-;; symbol as the nonterminal token generated, though it does not have to
-;; be. The values can be anything you want, including other tokens.
-;; START and END indicate where in the buffer this token is, and is
-;; easily derived from the START and END parameter passed down.
-;;
-;; A RESULT LAMBDA must take three parameters, VALS, START and END.
-;; VALS is the list of literals derived during the bovination of the
-;; match list, including punctuation, parens, and explicit
-;; matches. other elements
-;;
-;; Here are some example match lists and their code:
-;;
-;; (expression (lambda (vals start end)
-;; (append (car vals) (list start end))))
-;;
-;; In this RESULT LAMBDA, VALS will be of length one, and it's first
-;; element will contain the nonterminal expression result. It is
-;; likely to use a rule like this when there is a top level nonterminal
-;; symbol whose contents are several other single nonterminal rules.
-;; Because of this, we want to result that value with our START and END
-;; appended.
-;;
-;; NOTE: nonterminal values passed in as VALS always have their
-;; START/END parts stripped!
-;;
-;; This example lambda is also one of the DEFAULT lambdas for the case
-;; of a single nonterminal result. Thus, the above rule could also be
-;; written as (expression).
-;;
-;; A more complex example uses more flex elements. Lets match this:
-;;
-;; (defun myfunction (arguments) "docstring" ...)
-;;
-;; If we assume a flex depth of 1, we can write it this way:
-;;
-;; (open-paren "(" symbol "defun" symbol semantic-list string
-;; (lambda (vals start end)
-;; (list (nth 2 vals) 'function nil (nth 3 vals)
-;; (nth 4 vals) start end)))
-;;
-;; The above will create a function token, whose format is
-;; predefined. (See the symbol `semantic-toplevel-bovine-table' for
-;; details on some default symbols that should be provided.)
-;;
-;; From this we can see that VALS will have the value:
-;; ( "(" "defun" "myfunction" "(arguments)"
"docstring")
-;;
-;; If we also want to return a list of arguments in our function
-;; token, we can replace `semantic-list' with the following recursive
-;; nonterminal rule.
-;;
-;; ( arg-list (semantic-list
-;; (lambda (vals start end)
-;; (semantic-bovinate-from-nonterminal start end 'argsyms))))
-;; ( argsyms
-;; (open-paren argsyms (lambda (vals start end)
-;; (append (car (cdr vals)) (list start end))))
-;; (symbol argsyms (lambda (vals start end)
-;; (append (cons (car vals) (car (cdr vals)))
-;; (list start end))))
-;; (symbol close-paren (lambda (vals start end)
-;; (list (car vals) start end))))
-;;
-;; This recursive rule can find a parenthetic list with any number of
-;; symbols in it.
-;;
-;; Here we also see a new function, `semantic-bovinate-from-nonterminal'.
-;; This function takes START END and a nonterminal result symbol to
-;; match. This will return a complete token, including START and
-;; END. This function should ONLY BE USED IN A RESULT LAMBDA. It
-;; uses knowledge of that scope to reduce the number of parameters
-;; that need to be passed in. This is useful for decomposing complex
-;; syntactic elements, such as semantic-list.
-;;
-;; Token's and the VALS argument
-;; -----------------------------
-;;
-;; Not all syntactic tokens are represented by strings in the VALS argument
-;; to the match-list lambda expression. Some are a dotted pair (START . END).
-;; The following are represented as strings:
-;; 1) symbols
-;; 2) punctuation
-;; 3) open/close-paren
-;; 4) charquote
-;; 5) strings
-;; The following are represented as a dotted-pair.
-;; 1) semantic-list
-;; 2) comments
-;; Nonterminals are always lists which are generated in the lambda
-;; expression.
-;;
-;; Semantic Bovine Table Debugger
-;; ------------------------------
-;;
-;; The bovinator also includes a primitive debugger. This debugger
-;; walks through the parsing process and see how it's being
-;; interpretted. There are two steps in debuggin a bovine table.
-;;
-;; First, place the cursor in the source code where the table is
-;; defined. Execute the command `semantic-bovinate-debug-set-table'.
-;; This tells the debugger where you table is.
-;;
-;; Next, place the cursor in a buffer you which to run the bovinator
-;; on, and execute the command `semantic-bovinate-buffer-debug'. This
-;; will parse the table, and highlight the relevant areas and walk
-;; through the match list with the cursor, displaying the current list
-;; of values (which is always backwards.)
-;;
-;; DESIGN ISSUES:
-;; -------------
-;;
-;; At the moment, the only thing I really dislike is the RESULT
-;; LAMBDA format. While having some good defaults is nice, the use
-;; of append and list in the lambda seems unnecessarily complex.
-;;
-;; Also of issue, I am still not sure I like the idea of stripping
-;; BEGIN/END off of nonterminal tokens passed down in VALS. While they
-;; are often unnecessary, I can imagine that they could prove useful.
-;; Only time will tell.
;;; History:
;;
(require 'working)
-(require 'semantic-util)
(defgroup semantic nil
- "File and tag browser frame."
+ "Parser Generator/Parser."
)
;;; Code:
@@ -243,6 +67,14 @@
(defalias 'semantic-overlay-lists
(lambda () (list (extent-list))))
(defalias 'semantic-overlay-p 'extentp)
+ (defun semantic-read-event ()
+ (let ((event (next-command-event)))
+ (if (key-press-event-p event)
+ (let ((c (event-to-character event)))
+ (if (char-equal c (quit-char))
+ (keyboard-quit)
+ c)))
+ event))
)
(defalias 'semantic-overlay-live-p 'overlay-buffer)
(defalias 'semantic-make-overlay 'make-overlay)
@@ -258,6 +90,7 @@
(defalias 'semantic-overlay-previous-change 'previous-overlay-change)
(defalias 'semantic-overlay-lists 'overlay-lists)
(defalias 'semantic-overlay-p 'overlayp)
+ (defalias 'semantic-read-event 'read-event)
)
(defvar semantic-edebug nil
@@ -317,7 +150,7 @@
Bovine table entry return elements are up to the table author. It is
recommended, however, that the following format be used.
- (\"NAME\" type-symbol [\"TYPE\"] ... \"DOCSTRING\"
OVERLAY)
+ (\"NAME\" type-symbol [\"TYPE\"] ... \"DOCSTRING\"
PROPERTIES OVERLAY)
Where type-symbol is the type of return token found, and NAME is it's
name. If there is any typing information needed to describe this
@@ -327,10 +160,18 @@
Emacs Lisp. It could be the text of a comment appearing just before a
function call, or in line with a variable.
-The last element must be OVERLAY.
-The OVERLAY is automatically created by semantic from an input that
-consists of START and END. When building a parser table, use START
-and END as positions in the buffer.
+PROPERTIES is a list of additional properties for this token.
+PRORPERTIES is not for details of the token. It is used for
+additional tags needed by tools using the parse stream. For example,
+the `dirty' property is used when a given token needs to be reparsed.
+
+PROPERTIES are automatically added to the token by the system when
+using BNF, or `semantic-lambda' in the table.
+
+The last element must be OVERLAY. The OVERLAY is automatically
+created by the parsing system. When programming with BNF, or using
+`semantic-lambda', no extra work needs to be done. If you are
+building the parse table yourself, use START and END.
It may seem odd to place NAME in slot 0, and the type-symbol in slot
1, but this turns the returned elements into a list which can be used
@@ -348,53 +189,83 @@
TOP-LEVEL ENTRIES:
- (\"NAME\" variable \"TYPE\" CONST DEFAULT-VALUE MODIFIERS
[OPTSUFFIX]
- \"DOCSTRING\" OVERLAY)
+ (\"NAME\" variable \"TYPE\" DEFAULT-VALUE EXTRA-SPEC
+ \"DOCSTRING\" PROPERTIES OVERLAY)
The definition of a variable, or constant.
- CONST is a boolean representing if this variable is considered a constant.
DEFAULT-VALUE can be something apropriate such a a string,
or list of parsed elements.
- MODIFIERS are details about a variable that are not covered in the TYPE.
- OPTSUFFIX is an optional field specifying trailing modifiers such as
- array dimentions or bit fields.
+ EXTRA-SPEC are details about a variable that are not covered in the TYPE.
+ See detail on EXTRA-SPEC after entries section.
DOCSTRING is optional.
- (\"NAME\" function \"TYPE\" ( ARG-LIST ) MODIFIERS [THROWS]
- \"DOCSTRING\" OVERLAY)
+ (\"NAME\" function \"TYPE\" ( ARG-LIST ) EXTRA-SPEC
+ \"DOCSTRING\" PROPERTIES OVERLAY)
A function/procedure definition.
ARG-LIST is a list of variable definitions.
- THROWS is an optional argument for functions or methods in languages
- that support typed signal throwing.
DOCSTRING is optional.
- (\"NAME\" type \"TYPE\" ( PART-LIST ) ( PARENTS ) MODIFIERS
- \"DOCSTRING\" OVERLAY)
+ (\"NAME\" type \"TYPE\" ( PART-LIST ) ( PARENTS ) EXTRA-SPEC
+ \"DOCSTRING\" PROPERTIES OVERLAY)
A type definition.
TYPE of a type could be anything, such as (in C) struct, union, typedef,
- or class.
+ or class.
PART-LIST is only useful for structs that have multiple individual parts.
(It is recommended that these be variables, functions or types).
PARENTS is strictly for classes where there is inheritance.
-
+ See `semantic-token-parent' for a description of this value.
- (\"FILE\" include SYSTEM \"DOCSTRING\" OVERLAY)
+ (\"FILE\" include SYSTEM \"DOCSTRING\" PROPERTIES OVERLAY)
In C, an #include statement. In elisp, a require statement.
Indicates additional locations of sources or definitions.
SYSTEM is true if this include is part of a set of system includes.
- (\"NAME\" package DETAIL \"DOCSTRING\" OVERLAY)
+ (\"NAME\" package DETAIL \"DOCSTRING\" PROPERTIES OVERLAY)
In Emacs Lisp, a `provide' statement. DETAIL might be an
- associated file name.
+ associated file name. In Java, this is a package statement.
+
+EXTRA-SPEC:
+
+ The EXTRA-SPEC section of variables, functions, and types provide a
+location to place language specific details which are not accounted
+for by the base token type. Because there is an arbitrary number of
+things that could be associated in the EXTRA-SPEC section, this should
+be formatted as an association list.
+
+ Here are some typed extra specifiers that may exist. Any arbitrary
+number of extra specifiers may be created, and specifiers not
+documented here are allowed.
-OTHER ENTRIES:")
+ (parent . \"text\") - Name of a parent type/class. C++ and CLOS allow
+ the creation of a function outside the body of that type/class.
+
+ (dereference . INT) - Number of levels of dereference. In C, the number
+ of `*' characters indicating pointers.
+
+ (typemodifiers . \"text\") - Keyword modifiers for a type. In C, such
+ words would include `register', and `volatile'.
+
+ (suffix . \"text\") - Suffix information for a variable.
+
+ (const . t) - This exists if the variable or return value is constant.
+
+ (throws . \"text\") - For functions or methods in languages that support
+ typed signal throwing.
+
+ (user-visible . t) - For functions in interpreted languages such as Emacs Lisp,
+ this signals that a function or variable is user visible. In Emacs Lisp,
+ this means a function is `interactive'.")
(make-variable-buffer-local 'semantic-toplevel-bovine-table)
+(defvar semantic-toplevel-bovine-table-source nil
+ "The .bnf source file the current table was created from.")
+(make-variable-buffer-local 'semantic-toplevel-bovine-table-source)
+
(defvar semantic-symbol->name-assoc-list
'((variable . "Variables")
(function . "Functions")
- (type . "Types")
- (include . "Dependencies")
- (package . "Provides"))
+ (type . "Types")
+ (include . "Dependencies")
+ (package . "Provides"))
"Association between symbols returned, and a string.
The string is used to represent a group of objects of the given type.
It is sometimes useful for a language to use a different string
@@ -419,62 +290,235 @@
(make-variable-buffer-local 'semantic-ignore-comments)
(defvar semantic-expand-nonterminal nil
- "Function to call for each returned Non-terminal.
+ "Function to call for each nonterminal production.
Return a list of non-terminals derived from the first argument, or nil
-if it does not need to be expanded.")
+if it does not need to be expanded.
+Languages with compound definitions should use this function to expand
+from one compound symbol into several. For example, in C the definition
+ int a, b;
+is easily parsed into one token. This function should take this
+compound token and turn it into two tokens, one for A, and the other for B.")
(make-variable-buffer-local 'semantic-expand-nonterminal)
(defvar semantic-toplevel-bovine-cache nil
"A cached copy of a recent bovination, plus state.
If no significant changes have been made (based on the state) then
-this is returned instead of re-parsing the buffer.")
+this is returned instead of re-parsing the buffer.
+
+ DO NOT USE THIS VARIABLE IN PROGRAMS.
+
+If you need a token list, use `semantic-bovinate-toplevel'. If you
+need the cached values for some reason, chances are you can, add a
+hook to `semantic-after-toplevel-cache-change-hook'.")
(make-variable-buffer-local 'semantic-toplevel-bovine-cache)
+(defvar semantic-edits-are-safe nil
+ "When non-nil, modifications do not require a reparse.
+This prevents tokens from being marked dirty, and it
+prevents top level edits from causing a cache check.
+Use this when writing programs that could cause a full
+reparse, but will not change the tag structure, such
+as adding or updating top-level comments.")
+
(defvar semantic-toplevel-bovine-cache-check nil
"Non nil if the bovine cache is out of date.
This is tracked with `semantic-change-function'.")
(make-variable-buffer-local 'semantic-toplevel-bovine-cache-check)
+
+(defvar semantic-toplevel-bovine-force-reparse nil
+ "Non nil if the next token request forces a reparse.")
+(make-variable-buffer-local 'semantic-toplevel-bovine-force-reparse)
+
+(defvar semantic-dirty-tokens nil
+ "List of tokens in the current buffer which are dirty.
+Dirty functions can then be reparsed, and spliced back into the main list.")
+(make-variable-buffer-local 'semantic-dirty-tokens)
+
+(defvar semantic-bovinate-nonterminal-check-obarray nil
+ "Obarray of streams already parsed for nonterminal symbols.")
+(make-variable-buffer-local 'semantic-bovinate-nonterminal-check-obarray)
+
+(defvar semantic-dirty-token-hooks nil
+ "Hooks run after when a token is marked as dirty (edited by the user).
+The functions must take TOKEN, START, and END as a parameters.
+This hook will only be called once when a token is first made dirty,
+subsequent edits will not cause this to run a second time unless that
+token is first cleaned. Any token marked as dirty will
+also be called with `semantic-clean-token-hooks', unless a full
+reprase is done instead.")
+
+(defvar semantic-clean-token-hooks nil
+ "Hooks run after a token is marked as clean (reparsed after user edits.)
+The functions must take a TOKEN as a parameter.
+Any token sent to this hook will have first been called with
+`semantic-dirty-token-hooks'. This hook is not called for tokens
+marked dirty if the buffer is completely reparsed. In that case, use
+`semantic-after-toplevel-bovinate-hook'.")
+
+(defvar semantic-change-hooks nil
+ "Hooks run when semantic detects a change in a buffer.
+Each hook function must take three arguments, identical to the
+common hook `after-change-function'.")
-(defvar semantic-toplevel-bovinate-override nil
+(defvar semantic-bovinate-toplevel-override nil
"Local variable set by major modes which provide their own bovination.
This function should behave as the function `semantic-bovinate-toplevel'.")
-(make-variable-buffer-local 'semantic-toplevel-bovinate-override)
+(make-variable-buffer-local 'semantic-bovinate-toplevel-override)
(defvar semantic-after-toplevel-bovinate-hook nil
"Hooks run after a toplevel token parse.
It is not run if the toplevel parse command is called, and buffer does
-not need to be reparsed.
+not need to be fully reparsed.
For language specific hooks, make sure you define this as a local hook.")
+(defvar semantic-after-toplevel-cache-change-hook nil
+ "Hooks run after the buffer token list has changed.
+This list will change when a buffer is reparsed, or when the token
+list in a buffer is cleared. It is *NOT* called if the current token
+list partially reparsed.
+
+Hook functions must take one argument, which is the new list of
+tokens associated with this buffer.
+
+For language specific hooks, make sure you define this as a local hook.")
+
(defvar semantic-before-toplevel-cache-flush-hook nil
"Hooks run before the toplevel nonterminal cache is flushed.
-For language specific hooks, make sure you define this as a local hook.")
+For language specific hooks, make sure you define this as a local hook.
+This hook is called before a corresponding
+`semantic-after-toplevel-bovinate-hook' which is also called during a
+flush when the cache is given a new value of nil.")
(defvar semantic-reparse-needed-change-hook nil
"Hooks run when a user edit is detected as needing a reparse.
-For language specific hooks, make sure you define this as a local hook.")
+For language specific hooks, make sure you define this as a local
+hook.
+Not used yet; part of the next generation reparse mechanism")
(defvar semantic-no-reparse-needed-change-hook nil
"Hooks run when a user edit is detected as not needing a reparse.
If the hook returns non-nil, then declare that a reparse is needed.
-For language specific hooks, make sure you define this as a local hook.")
+For language specific hooks, make sure you define this as a local
+hook.
+Not used yet; part of the next generation reparse mechanism.")
-;;; Utility API functions
-;;
-;; These functions use the flex and bovination engines to perform some
-;; simple tasks useful to other programs. These are just the most
-;; critical entries.
+;;; Primitive Token access system:
;;
-;; See semantic-util for a wider range of utility functions and macros.
-;;
+;; These are token level APIs (similar to some APIs in semantic-util)
+;; which are required for parsing operations. Semantic.el should have
+;; no dependencies on other semantic files.
+;;
+;; TFE = Token From End
+
+(defconst semantic-tfe-overlay 1
+ "Amount to subtract from the length of the token to get the overlay.")
+(defconst semantic-tfe-properties 2
+ "Amount to subtract from the length of the token to get the property
list.")
+(defconst semantic-tfe-docstring 3
+ "Amount to subtract from the length of the token to get the doc string.")
+(defconst semantic-tfe-number 2
+ "The number of required end elements.")
+
+(defmacro semantic-token-token (token)
+ "Retrieve from TOKEN the token identifier.
+ie, the symbol 'variable, 'function, 'type, or other."
+ `(nth 1 ,token))
+
+(defun semantic-token-name (token)
+ "Retrieve the name of TOKEN."
+ (car token))
+
+(defun semantic-token-docstring (token &optional buffer)
+ "Retrieve the documentation of TOKEN.
+Optional argument BUFFER indicates where to get the text from.
+If not provided, then only the POSITION can be provided."
+ (let ((p (nth (- (length token) semantic-tfe-docstring) token)))
+ (if (and p buffer)
+ (save-excursion
+ (set-buffer buffer)
+ (semantic-flex-text (car (semantic-flex p (1+ p)))))
+ p)))
+
+(defmacro semantic-token-properties (token)
+ "Retrieve the PROPERTIES part of TOKEN.
+The returned item is an ALIST of (KEY . VALUE) pairs."
+ `(nth (- (length ,token) semantic-tfe-properties) ,token))
+
+(defmacro semantic-token-properties-cdr (token)
+ "Retrieve the cons cell for the PROPERTIES part of TOKEN."
+ `(nthcdr (- (length ,token) semantic-tfe-properties) ,token))
+
+(defun semantic-token-put (token key value)
+ "For TOKEN, put the property KEY on it with VALUE.
+If VALUE is nil, then remove the property from TOKEN."
+ (let* ((c (semantic-token-properties-cdr token))
+ (al (car c))
+ (a (assoc key (car c))))
+ (if a
+ (if value
+ (setcdr a value)
+ (adelete 'al key)
+ (setcar c al))
+ (if value
+ (setcar c (cons (cons key value) (car c)))))
+ ))
+
+(defun semantic-token-get (token key)
+ "For TOKEN, get the value for property KEY."
+ (cdr (assoc key (semantic-token-properties token))))
+
+(defmacro semantic-token-overlay (token)
+ "Retrieve the OVERLAY part of TOKEN.
+The returned item may be an overlay or an unloaded buffer representation."
+ `(nth (- (length ,token) semantic-tfe-overlay) ,token))
+
+(defmacro semantic-token-overlay-cdr (token)
+ "Retrieve the cons cell containing the OVERLAY part of TOKEN."
+ `(nthcdr (- (length ,token) semantic-tfe-overlay) ,token))
+
+(defmacro semantic-token-extent (token)
+ "Retrieve the extent (START END) of TOKEN."
+ `(let ((o (semantic-token-overlay ,token)))
+ (if (semantic-overlay-p o)
+ (list (semantic-overlay-start o) (semantic-overlay-end o))
+ (list (aref o 0) (aref o 1)))))
+
+(defun semantic-token-start (token)
+ "Retrieve the start location of TOKEN."
+ (let ((o (semantic-token-overlay token)))
+ (if (semantic-overlay-p o) (semantic-overlay-start o) (aref o 0))))
+
+(defun semantic-token-end (token)
+ "Retrieve the end location of TOKEN."
+ (let ((o (semantic-token-overlay token)))
+ (if (semantic-overlay-p o) (semantic-overlay-end o) (aref o 1))))
+
+(defun semantic-token-buffer (token)
+ "Retrieve the buffer TOKEN resides in."
+ (let ((o (semantic-token-overlay token)))
+ (if (semantic-overlay-p o) (semantic-overlay-buffer o)
+ ;; We have no buffer for this token (It's not in Emacs right now.)
+ nil)))
+
(defun semantic-token-p (token)
"Return non-nil if TOKEN is most likely a semantic token."
(and (listp token)
(stringp (car token))
+ (car (cdr token))
(symbolp (car (cdr token)))))
-;;; Parsing functions
+(defun semantic-token-with-position-p (token)
+ "Return non-nil if TOKEN is a semantic token with positional information."
+ (and (listp token)
+ (stringp (car token))
+ (symbolp (car (cdr token)))
+ (let ((o (semantic-token-overlay token)))
+ (or (semantic-overlay-p o)
+ (arrayp o)))))
+
+
+;;; Overlay and error stacks.
;;
(defvar semantic-overlay-error-recovery-stack nil
"List of overlays used during error recovery.")
@@ -498,8 +542,98 @@
(if (semantic-overlay-get overlay 'semantic)
(semantic-overlay-delete overlay)))
+;;; Interfacing with the system
+;;
+(defvar semantic-init-hooks nil
+ "*Hooks run when a buffer is initialized with a parsing table.")
+
+(defun semantic-active-p ()
+ "Return non-nil if the current buffer was set up for parsing."
+ (or semantic-toplevel-bovine-table
+ semantic-bovinate-toplevel-override))
+
+(defun semantic-new-buffer-fcn ()
+ "Setup Semantic in the current buffer.
+Runs `semantic-init-hook' if the major mode is setup to use Semantic."
+ (when (semantic-active-p)
+ (semantic-clear-toplevel-cache)
+ (setq semantic-toplevel-bovine-force-reparse t)
+ (run-hooks 'semantic-init-hooks)))
+
+(defvar semantic-changed-mode-buffers nil
+ "List of buffers whose `major-mode' has changed recently.")
+
+(defun semantic-post-change-major-mode-function ()
+ "`post-command-hook' run when there is a `major-mode' change.
+This makes sure semantic-init type stuff can occur."
+ (remove-hook 'post-command-hook
+ 'semantic-post-change-major-mode-function)
+ (let (buf)
+ (while semantic-changed-mode-buffers
+ (setq buf (car semantic-changed-mode-buffers)
+ semantic-changed-mode-buffers
+ (cdr semantic-changed-mode-buffers))
+ (and (buffer-live-p buf)
+ (buffer-file-name buf)
+ (with-current-buffer buf
+ (semantic-new-buffer-fcn))))))
+
+(defun semantic-change-major-mode-hook-function ()
+ "Function called in `change-major-mode-hook'."
+ (add-to-list 'semantic-changed-mode-buffers (current-buffer))
+ (add-hook 'post-command-hook 'semantic-post-change-major-mode-function))
+
+(add-hook 'find-file-hooks
+ 'semantic-post-change-major-mode-function)
+(add-hook 'change-major-mode-hook
+ 'semantic-change-major-mode-hook-function)
+
+;; Test the above hook.
+;;(add-hook 'semantic-init-hooks (lambda () (message "init for
semantic")))
+
+(defun semantic-rebovinate-quickly-hook ()
+ "For use in a hook. When only a partial reparse is needed, reparse."
+ (condition-case nil
+ (if (semantic-bovine-toplevel-partial-reparse-needed-p nil)
+ (semantic-bovinate-toplevel))
+ (error nil)))
+
+(if (boundp 'eval-defun-hooks)
+ (add-hook 'eval-defun-hooks 'semantic-rebovinate-quickly-hook))
+
+;;; Parsing Commands
+;;
+(eval-when-compile
+ (condition-case nil (require 'pp) (error nil)))
+
+(defun bovinate (&optional clear)
+ "Bovinate the current buffer. Show output in a temp buffer.
+Optional argument CLEAR will clear the cache before bovinating."
+ (interactive "P")
+ (if clear (semantic-clear-toplevel-cache))
+ (let ((out (semantic-bovinate-toplevel t)))
+ (pop-to-buffer "*BOVINATE*")
+ (require 'pp)
+ (erase-buffer)
+ (insert (pp-to-string out))
+ (goto-char (point-min))))
+
+(defun bovinate-debug ()
+ "Bovinate the current buffer and run in debug mode."
+ (interactive)
+ (let ((semantic-edebug t)
+ (out (semantic-bovinate-debug-buffer)))
+ (pop-to-buffer "*BOVINATE*")
+ (require 'pp)
+ (erase-buffer)
+ (insert (pp-to-string out))))
+
+;;; Parsing functions
+;;
(defun semantic-clear-toplevel-cache ()
- "Clear the toplevel bovin cache for the current buffer."
+ "Clear the toplevel bovin cache for the current buffer.
+Clearing the cache will force a complete reparse next time a token
+stream is requested."
(interactive)
(run-hooks 'semantic-before-toplevel-cache-flush-hook)
(setq semantic-toplevel-bovine-cache nil)
@@ -509,94 +643,241 @@
(mapcar 'semantic-delete-overlay-maybe (car l))
(mapcar 'semantic-delete-overlay-maybe (cdr l))
)
+ ;; Clear the dirty tokens... no longer relevant
+ (setq semantic-dirty-tokens nil)
+ (setq semantic-toplevel-bovine-force-reparse t)
;; Remove this hook which tracks if a buffer is up to date or not.
(remove-hook 'after-change-functions 'semantic-change-function t)
+ ;; Old model. Delete someday.
+ ;;(run-hooks 'semantic-after-toplevel-bovinate-hook)
+ (run-hook-with-args 'semantic-after-toplevel-cache-change-hook
+ semantic-toplevel-bovine-cache)
)
-(add-hook 'change-major-mode-hook 'semantic-clear-toplevel-cache)
+
+(defvar semantic-bovination-working-type 'percent
+ "*The type of working message to use when bovinating.
+'percent means we are doing a linear parse through the buffer.
+'dynamic means we are rebovinating specific tokens.")
+
+(defun semantic-bovine-toplevel-full-reparse-needed-p (&optional checkcache)
+ "Return non-nil if the current buffer needs a full reparse.
+Optional argument CHECKCACHE indicates if the cache check should be made."
+ (or semantic-toplevel-bovine-force-reparse
+ (and
+ checkcache
+ semantic-toplevel-bovine-cache-check)))
+
+(defun semantic-bovine-toplevel-partial-reparse-needed-p (&optional checkcache)
+ "Return non-nil if the current buffer needs a partial reparse.
+This only returns non-nil if `semantic-bovine-toplevel-full-reparse-needed-p'
+returns nil.
+Optional argument CHECKCACHE indicates if the cache check should be made
+when checking `semantic-bovine-toplevel-full-reparse-needed-p'."
+ (and semantic-toplevel-bovine-cache
+ semantic-dirty-tokens
+ (not (semantic-bovine-toplevel-full-reparse-needed-p checkcache))))
;;;###autoload
(defun semantic-bovinate-toplevel (&optional checkcache)
"Bovinate the entire current buffer.
-If the optional argument CHECKCACHE is non-nil, then flush the cache iff
-there has been a size change."
- (if (and semantic-toplevel-bovine-cache
- checkcache
- semantic-toplevel-bovine-cache-check)
- (semantic-clear-toplevel-cache))
- (prog1
- (cond
- (semantic-toplevel-bovinate-override
- (funcall semantic-toplevel-bovinate-override checkcache))
- ((and semantic-toplevel-bovine-cache
- (car semantic-toplevel-bovine-cache)
- ;; Add a rule that knows how to see if there have
- ;; been "big chagnes"
- )
- (car semantic-toplevel-bovine-cache))
- (t
- (let ((ss (semantic-flex (point-min) (point-max)))
- (res nil)
- (semantic-overlay-error-recovery-stack nil))
- ;; Init a dump
- (if semantic-dump-parse (semantic-dump-buffer-init))
- ;; Parse!
- (working-status-forms (buffer-name) "done"
- (setq res
- (semantic-bovinate-nonterminals
- ss 'bovine-toplevel semantic-flex-depth))
- (working-status t))
- (setq semantic-toplevel-bovine-cache
- (list (nreverse res) (point-max))
- semantic-toplevel-bovine-cache-check nil)
- (add-hook 'after-change-functions 'semantic-change-function nil t)
- (run-hooks 'semantic-after-toplevel-bovinate-hook)
- (car semantic-toplevel-bovine-cache))))
- ))
+If the optional argument CHECKCACHE is non-nil, then make sure the
+cached token list is up to date. If a partial reparse is possible, do
+that, otherwise, do a full reparse."
+ (cond
+ ((and semantic-bovinate-toplevel-override
+ ;; We cannot predict partial reparsing for these parsers. Let them
+ ;; fend for themselves. We can, however, handle the main cache for them.
+ (or (semantic-bovine-toplevel-partial-reparse-needed-p checkcache)
+ (semantic-bovine-toplevel-full-reparse-needed-p checkcache)))
+ (semantic-clear-toplevel-cache)
+ ;; Call a custom function
+ (let ((res (funcall semantic-bovinate-toplevel-override checkcache)))
+ (semantic-set-toplevel-bovine-cache res))
+ ;; Check: The below is not needed because of the -set- command above?
+ ;;(run-hooks 'semantic-after-toplevel-bovinate-hook)
+ semantic-toplevel-bovine-cache
+ )
+ ((semantic-bovine-toplevel-partial-reparse-needed-p checkcache)
+ ;; We have a cache, and some dirty tokens
+ (let ((semantic-bovination-working-type 'dynamic))
+ (working-status-forms (buffer-name) "done"
+ (while (and semantic-dirty-tokens
+ (not (semantic-bovine-toplevel-full-reparse-needed-p
+ checkcache)))
+ (semantic-rebovinate-token (car semantic-dirty-tokens))
+ (setq semantic-dirty-tokens (cdr semantic-dirty-tokens))
+ (working-dynamic-status))
+ (working-dynamic-status t))
+ (setq semantic-dirty-tokens nil)
+ )
+ (if (semantic-bovine-toplevel-full-reparse-needed-p checkcache)
+ ;; If the partial reparse fails, jump to a full reparse.
+ (semantic-bovinate-toplevel checkcache)
+ semantic-toplevel-bovine-cache)
+ )
+ ((semantic-bovine-toplevel-full-reparse-needed-p checkcache)
+ (semantic-clear-toplevel-cache)
+ ;; Reparse the whole system
+ (let ((ss (semantic-flex (point-min) (point-max)))
+ (res nil)
+ (semantic-overlay-error-recovery-stack nil))
+ ;; Init a dump
+ (if semantic-dump-parse (semantic-dump-buffer-init))
+ ;; Parse!
+ (working-status-forms (buffer-name) "done"
+ (setq res
+ (semantic-bovinate-nonterminals
+ ss 'bovine-toplevel semantic-flex-depth))
+ (working-status t))
+ (semantic-set-toplevel-bovine-cache (nreverse res))
+ semantic-toplevel-bovine-cache))
+ (t
+ ;; We have a cache with stuff in it, so return it
+ semantic-toplevel-bovine-cache
+ )))
+
+(defun semantic-set-toplevel-bovine-cache (tokenlist)
+ "Set the toplevel bovine cache to TOKENLIST."
+ (setq semantic-toplevel-bovine-cache tokenlist
+ semantic-toplevel-bovine-cache-check nil
+ semantic-toplevel-bovine-force-reparse nil
+ semantic-bovinate-nonterminal-check-obarray nil)
+ (add-hook 'after-change-functions 'semantic-change-function nil t)
+ (run-hook-with-args 'semantic-after-toplevel-cache-change-hook
+ semantic-toplevel-bovine-cache)
+ ;; Old Semantic 1.3 hook API. Maybe useful forever?
+ (run-hooks 'semantic-after-toplevel-bovinate-hook)
+ )
(defun semantic-change-function (start end length)
- "Run whenever a buffer controlled by `semantic-mode' change.
-Tracks when and how the buffer is re-parsed.
+ "Provide a mechanism for semantic token management.
Argument START, END, and LENGTH specify the bounds of the change."
- (when (not semantic-toplevel-bovine-cache-check)
- (let ((tl (condition-case nil
- (semantic-find-nonterminal-by-overlay-in-region
- (1- start) (1+ end))
- (error nil))))
- (if tl
- ;; Loop over the token list
- (while tl
- (cond
- ;; If we are completely enclosed in this overlay, throw away.
- ((and (> start (semantic-token-start (car tl)))
- (< end (semantic-token-end (car tl))))
- (if (and (eq (semantic-token-token (car tl)) 'type)
- (not (cdr tl))
- (semantic-token-type-parts (car tl)))
- (progn
- ;; This is between two items in a type with
- ;; stuff in it.
- (setq semantic-toplevel-bovine-cache-check t)
- (run-hooks 'semantic-reparse-needed-change-hook))
- ;; This is might be ok, chuck it.
- (if (run-hooks 'semantic-no-reparse-needed-change-hook)
- (progn
- ;; The hook says so, so flush it.
- (setq semantic-toplevel-bovine-cache-check t)
- (run-hooks 'semantic-reparse-needed-change-hook))
- nil)))
- ;; If we cover the beginning or end of this item, we must
- ;; reparse this object.
- (t
- (setq semantic-toplevel-bovine-cache-check t)
- (run-hooks 'semantic-reparse-needed-change-hook)))
- ;; next
- (setq tl (cdr tl)))
- ;; There was no hit, perhaps we need to reparse this intermediate area.
- (setq semantic-toplevel-bovine-cache-check t)
- )
- (if semantic-toplevel-bovine-cache-check
- (message "Reparse needed...")))))
+ (run-hook-with-args 'semantic-change-hooks start end length))
+
+;;; Force token lists in and out of overlay mode.
+;;
+(defun semantic-deoverlay-token (token)
+ "Convert TOKEN from using an overlay to using an overlay proxy."
+ (when (semantic-token-p token)
+ (let ((c (semantic-token-overlay-cdr token))
+ a)
+ (when (and c (semantic-overlay-p (car c)))
+ (setq a (vector (semantic-overlay-start (car c))
+ (semantic-overlay-end (car c))))
+ (semantic-overlay-delete (car c))
+ (setcar c a)
+ ;; Fix the children of this token.
+ ;; Semantic-util is required and the end of semantic, so this will
+ ;; throw a warning
+ (semantic-deoverlay-list (semantic-nonterminal-children token)))
+ )))
+
+(defun semantic-overlay-token (token)
+ "Convert TOKEN from using an overlay proxy to using an overlay."
+ (when (semantic-token-p token)
+ (let ((c (semantic-token-overlay-cdr token))
+ o)
+ (when (and c (vectorp (car c)) (= (length (car c)) 2))
+ (setq o (semantic-make-overlay (aref (car c) 0)
+ (aref (car c) 1)
+ (current-buffer)))
+ (setcar c o)
+ (semantic-overlay-put o 'semantic token)
+ ;; Fix overlays in children of this token
+ ;; Semantic-util is required and the end of semantic, so this will
+ ;; throw a warning
+ (semantic-overlay-list (semantic-nonterminal-children token))
+ ))))
+
+(defun semantic-deoverlay-list (l)
+ "Remove overlays from the list L."
+ (mapcar 'semantic-deoverlay-token l))
+
+(defun semantic-overlay-list (l)
+ "Convert numbers to overlays from the list L."
+ (mapcar 'semantic-overlay-token l))
+
+(defun semantic-deoverlay-cache ()
+ "Convert all tokens in the current cache to use overlay proxies."
+ (semantic-deoverlay-list (semantic-bovinate-toplevel)))
+(defun semantic-overlay-cache ()
+ "Convert all tokens in the current cache to use overlays."
+ (condition-case nil
+ ;; In this unique case, we cannot call the usual toplevel fn.
+ ;; because we don't want a reparse, we want the old overlays.
+ (semantic-overlay-list semantic-toplevel-bovine-cache)
+ ;; Recover when there is an error restoring the cache.
+ (error (message "Error recovering token list.")
+ (semantic-clear-toplevel-cache)
+ nil)))
+
+;;; Token parsing utilities
+;;
+(defun semantic-raw-to-cooked-token (token)
+ "Convert TOKEN from a raw state to a cooked state.
+The parser returns raw tokens with positional data START/END.
+We convert it from that to a cooked state with a property list and an overlay.
+Change the token with side effects and returns TOKEN."
+ (let* ((result nil)
+ (expandedtokens nil)
+ (ncdr (- (length token) 2))
+ (propcdr (if (natnump ncdr) (nthcdr ncdr token)))
+ (overcdr (cdr propcdr))
+ ;; propcdr is the CDR containing the START from the token.
+ ;; overcdr is the CDR containing the END from the token.
+ ;; PROPCDR will contain the property list after cooking.
+ ;; OVERCDR will contain the overlay after cooking.
+ (o (condition-case nil
+ (semantic-make-overlay (car propcdr)
+ (car overcdr)
+ (current-buffer)
+ ;; Examin start/rear
+ ;; advance flags.
+ )
+ (error (debug token)
+ nil))))
+ ;; Convert START/END into PROPERTIES/OVERLAY.
+ (setcar overcdr o)
+ (setcar propcdr nil)
+ (semantic-overlay-put o 'semantic token)
+ ;; Expand based on local configuration
+ (if (not semantic-expand-nonterminal)
+ ;; no expanders
+ (setq result (cons token result))
+ ;; Glom generated tokens
+ (setq expandedtokens (funcall semantic-expand-nonterminal token))
+ (if (not expandedtokens)
+ (progn (setq result (cons token result))
+ (semantic-overlay-stack-add o))
+ ;; Fixup all overlays, start by deleting the old one
+ (let ((tokenloop expandedtokens) o start end)
+ (while tokenloop
+ (setq propcdr (nthcdr (- (length (car tokenloop)) 2)
+ (car tokenloop))
+ overcdr (nthcdr (- (length (car tokenloop)) 1)
+ (car tokenloop))
+ ;; this will support new overlays created by
+ ;; the special function, or recycles
+ start (if (semantic-overlay-live-p (car overcdr))
+ (semantic-overlay-start (car overcdr))
+ start)
+ end (if (semantic-overlay-live-p (car overcdr))
+ (semantic-overlay-end (car overcdr))
+ end)
+ o (semantic-make-overlay start end
+ (current-buffer)))
+ (if (semantic-overlay-live-p (car overcdr))
+ (semantic-overlay-delete (semantic-token-overlay
+ (car tokenloop))))
+ (semantic-overlay-stack-add o)
+ (setcar propcdr nil)
+ (setcar overcdr o)
+ (semantic-overlay-put o 'semantic (car tokenloop))
+ (setq tokenloop (cdr tokenloop))))
+ (setq result (append expandedtokens result))))
+ result))
+
(defun semantic-bovinate-nonterminals (stream nonterm &optional
depth returnonerror)
"Bovinate the entire stream STREAM starting with NONTERM.
@@ -610,71 +891,129 @@
(semantic-bovinate-nonterminal
stream semantic-toplevel-bovine-table nonterm))
(stream-overlays (car (cdr (cdr nontermsym))))
- (tmpet nil)
- (token (car (cdr nontermsym)))
- (ncdr (- (length token) 2))
- (startcdr (if (natnump ncdr) (nthcdr ncdr token))))
+ (token (car (cdr nontermsym))))
(if (not nontermsym)
(error "Parse error @ %d" (car (cdr (car stream)))))
(semantic-overlay-stack-add stream-overlays)
(if token
- (let ((o (condition-case nil
- (semantic-make-overlay (car startcdr)
- (car (cdr startcdr))
- (current-buffer)
- ;; Examin start/rear
- ;; advance flags.
- )
- (error (debug token)
- nil))))
- ;; Convert START/END into an overlay.
- (setcdr startcdr nil)
- (setcar startcdr o)
- (semantic-overlay-put o 'semantic token)
- ;; Expand based on local configuration
- (if (not semantic-expand-nonterminal)
- ;; no expanders
- (setq result (cons token result))
- ;; Glom generated tokens
- (setq tmpet (funcall semantic-expand-nonterminal token))
- (if (not tmpet)
- (progn (setq result (cons token result))
- (semantic-overlay-stack-add o))
- ;; Fixup all overlays, start by deleting the old one
- (let ((motok tmpet) o start end)
- (while motok
- (setq startcdr (nthcdr (- (length (car motok)) 1)
- (car motok))
- ;; this will support new overlays created by
- ;; the special function, or recycles
- start (if (semantic-overlay-live-p (car startcdr))
- (semantic-overlay-start (car startcdr))
- start)
- end (if (semantic-overlay-live-p (car startcdr))
- (semantic-overlay-end (car startcdr))
- end)
- o (semantic-make-overlay start end
- (current-buffer)))
- (if (semantic-overlay-live-p (car startcdr))
- (semantic-overlay-delete (semantic-token-overlay
- (car motok))))
- (semantic-overlay-stack-add o)
- (setcdr startcdr nil)
- (setcar startcdr o)
- (semantic-overlay-put o 'semantic (car motok))
- (setq motok (cdr motok))))
- (setq result (append tmpet result)))))
+ (if (car token)
+ (progn
+ (setq result (append (semantic-raw-to-cooked-token token)
+ result))
+ ;; Place the nonterm into the token.
+ (if (not (eq nonterm 'bovine-toplevel))
+ (semantic-token-put token 'reparse-symbol nonterm)))
+ ;; No error in this case, a purposeful nil means don't store
+ ;; anything.
+ )
(if returnonerror (setq stream nil))
;;(error "Parse error")
)
;; Designated to ignore.
(setq stream (car nontermsym)))
(if stream
- (working-status (floor
- (* 100.0 (/ (float (car (cdr (car stream))))
- (float (point-max))))))))
+ (if (eq semantic-bovination-working-type 'percent)
+ (working-status (floor
+ (* 100.0 (/ (float (car (cdr (car stream))))
+ (float (point-max))))))
+ (working-dynamic-status))))
result))
+(defun semantic-remove-dirty-children-internal (token dirties)
+ "Remove TOKEN children from DIRTIES.
+Return the new value of DIRTIES."
+ (if dirties
+ (let ((children (semantic-nonterminal-children token t))
+ child)
+ (while (and children dirties)
+ (setq child (car children)
+ children (cdr children)
+ dirties (semantic-remove-dirty-children-internal
+ child (delq child dirties))))))
+ dirties)
+
+(defun semantic-remove-dirty-children (token)
+ "Remove TOKEN children from the list of dirty tokens.
+This must be done before deoverlaying TOKEN. At this point (when
+called by `semantic-rebovinate-token') TOKEN is the first element of
+`semantic-dirty-tokens' so only the rest of `semantic-dirty-tokens' is
+considered."
+ (setq semantic-dirty-tokens
+ (cons (car semantic-dirty-tokens)
+ (semantic-remove-dirty-children-internal
+ token (cdr semantic-dirty-tokens)))))
+
+(defun semantic-rebovinate-token (token)
+ "Use TOKEN for extents, and reparse it, splicing it back into the cache."
+ (let* ((flexbits (semantic-flex (semantic-token-start token)
+ (semantic-token-end token)))
+ ;; For embeded tokens (type parts, for example) we need a
+ ;; different symbol. Come up with a plan to solve this.
+ (nonterminal (or (semantic-token-get token 'reparse-symbol)
+ 'bovine-toplevel))
+ (new (condition-case nil
+ (semantic-bovinate-nonterminal
+ flexbits
+ semantic-toplevel-bovine-table
+ nonterminal)
+ ;; Trap `read' errors which may temporarily occurs
+ ;; when re-parsing a dirty Elisp token.
+ (end-of-file 'delay)
+ (invalid-read-syntax 'delay)))
+ (cooked nil)
+ )
+ (if (eq new 'delay)
+ ;; If a `read' error occured during re-parsing of an Elisp
+ ;; token just delay rebovination. Thus features like Semantic
+ ;; completion could continue to work until a clean syntax
+ ;; state is reached and re-parse succeeds.
+ nil
+ (setq new (car (cdr new)))
+ (if (not new)
+ ;; Clever reparse failed, queuing full reparse.
+ (setq semantic-toplevel-bovine-cache-check t)
+ (setq cooked (semantic-raw-to-cooked-token new))
+ (if (not (eq new (car cooked)))
+ (if (= (length cooked) 1)
+ ;; Cooking did a 1 to 1 replacement. Use it.
+ (setq new (car cooked))
+ ;; If cooking results in multiple things, do a full reparse.
+ (setq semantic-toplevel-bovine-cache-check t))))
+ ;; Don't do much if we have to do a full recheck.
+ (if semantic-toplevel-bovine-cache-check
+ nil
+ (let ((oo (semantic-token-overlay token))
+ (o (semantic-token-overlay new)))
+ ;; Copy all properties of the old overlay here.
+ ;; I think I can use plists in emacs, but not in XEmacs.
+ ;; Ack!
+ (semantic-overlay-put o 'face (semantic-overlay-get oo 'face))
+ (semantic-overlay-put o 'old-face (semantic-overlay-get oo
'old-face))
+ (semantic-overlay-put o 'intangible (semantic-overlay-get oo
'intangible))
+ (semantic-overlay-put o 'invisible (semantic-overlay-get oo
'invisible))
+ ;; Remove TOKEN children from `semantic-dirty-tokens'
+ (semantic-remove-dirty-children token)
+ ;; Free the old overlay(s)
+ (semantic-deoverlay-token token)
+ ;; Recover properties
+ (let ((p (semantic-token-properties token)))
+ (while p
+ (semantic-token-put new (car (car p)) (cdr (car p)))
+ (setq p (cdr p))))
+ (if (not (eq nonterminal 'bovine-toplevel))
+ (semantic-token-put new 'reparse-symbol nonterminal))
+ (semantic-token-put new 'dirty nil)
+ ;; Splice into the main list.
+ (setcdr token (cdr new))
+ (setcar token (car new))
+ ;; This important bit is because the CONS cell representing TOKEN
+ ;; is what we need here, even though the whole thing is the same.
+ (semantic-overlay-put o 'semantic token)
+ ;; Hooks
+ (run-hook-with-args 'semantic-clean-token-hooks token)
+ )
+ ))))
+
;;; Semantic Bovination
;;
@@ -682,159 +1021,254 @@
;; The bovinator takes a state table, and converts the token stream
;; into a new semantic stream defined by the bovination table.
;;
-(defun semantic-bovinate-nonterminal (stream table &optional nonterminal)
- "Bovinate STREAM based on the TABLE of nonterminal symbols.
-Optional argument NONTERMINAL is the nonterminal symbol to start with.
-Use `bovine-toplevel' if it is not provided."
- (if (not nonterminal) (setq nonterminal 'bovine-toplevel))
- (let ((ml (assq nonterminal table)))
- (semantic-bovinate-stream stream (cdr ml) table)))
-
(defsubst semantic-bovinate-symbol-nonterminal-p (sym table)
"Return non-nil if SYM is in TABLE, indicating it is NONTERMINAL."
;; sym is always a sym, so assq should be ok.
(if (assq sym table) t nil))
-(defun semantic-bovinate-stream (stream matchlist table)
- "Bovinate STREAM using MATCHLIST resolving nonterminals with TABLE.
+(defmacro semantic-bovinate-nonterminal-db-nt ()
+ "Return the current nonterminal symbol.
+Part of the BNF source debugger. Depends on the existing environment
+of `semantic-bovinate-nonterminal'."
+ `(if nt-stack
+ (car (aref (car nt-stack) 2))
+ nonterminal))
+
+(defun semantic-bovinate-nonterminal-check (stream nonterminal)
+ "Check if STREAM not already parsed for NONTERMINAL.
+If so abort because an infinite recursive parse is suspected."
+ (or (vectorp semantic-bovinate-nonterminal-check-obarray)
+ (setq semantic-bovinate-nonterminal-check-obarray
+ (make-vector 13 nil)))
+ (let* ((nt (symbol-name nonterminal))
+ (vs (symbol-value
+ (intern-soft
+ nt semantic-bovinate-nonterminal-check-obarray))))
+ (if (memq stream vs)
+ ;; Always enter debugger to see the backtrace
+ (let ((debug-on-signal t)
+ (debug-on-error t))
+ (setq semantic-bovinate-nonterminal-check-obarray nil)
+ (error "Infinite recursive parse suspected on %s" nt))
+ (set (intern nt semantic-bovinate-nonterminal-check-obarray)
+ (cons stream vs)))))
+
+(defun semantic-bovinate-nonterminal (stream table &optional nonterminal)
+ "Bovinate STREAM based on the TABLE of nonterminal symbols.
+Optional argument NONTERMINAL is the nonterminal symbol to start with.
+Use `bovine-toplevel' if it is not provided.
This is the core routine for converting a stream into a table.
-See the variable `semantic-toplevel-bovine-table' for details on the
-format of MATCHLIST.
Return the list (STREAM SEMANTIC-STREAM OVERLAYS) where STREAM are those
elements of STREAM that have not been used. SEMANTIC-STREAM is the
list of semantic tokens found. OVERLAYS is the list of overlays found
so far, to be used in the error recovery stack."
- (let ((s nil) ;Temp Stream Tracker
- (lse nil) ;Local Semantic Element
- (lte nil) ;Local matchlist element
- (tev nil) ;Matchlist entry values from buffer
- (val nil) ;Value found in buffer.
- (cvl nil) ;collected values list.
- (out nil) ;Output
- (ov nil) ;Overlay
- (s-stack nil) ;rollback stream stack
- (start nil) ;the beginning and end.
- (end nil)
- (db-mlen (length matchlist))
- (db-tlen 0)
- (semantic-overlay-error-recovery-stack nil) ;part of error recovery
- )
- ;; prime the rollback stack
- (setq s-stack (cons stream s-stack)
- start (car (cdr (car stream)))
- end (cdr (cdr (car stream))))
- (while matchlist
- (setq s (car s-stack) ;init s from the stack.
- cvl nil ;re-init the collected value list.
- lte (car matchlist) ;Get the local matchlist entry.
- db-tlen (length lte)) ;length of the local match.
- (if (or (byte-code-function-p (car lte))
- (listp (car lte)))
- ;; In this case, we have an EMPTY match! Make stuff up.
- (setq cvl (list nil)))
- (while (and lte (not (or (byte-code-function-p (car lte))
- (listp (car lte)))))
- ;; debugging!
- (if (and lte semantic-edebug)
- ;; The below reference to nonterminal is a hack and the byte
- ;; compiler will complain about it.
- (let ((r (semantic-bovinate-show (car s) nonterminal
- (- db-mlen (length matchlist))
- (- db-tlen (length lte))
- cvl)))
- (cond ((eq r 'fail)
- (setq lte '(trash 0 . 0)))
- (t nil))))
- (cond
- ;; We have a nonterminal symbol. Recurse inline.
- ((semantic-bovinate-symbol-nonterminal-p (car lte) table)
- (let ((nontermout (semantic-bovinate-nonterminal s table (car lte))))
- (setq s (car nontermout)
- val (car (cdr nontermout))
- ov (car (cdr (cdr nontermout))))
- (if ov (semantic-overlay-stack-add ov))
- (if val
- (let ((len (length val))
- (strip (nreverse (cdr (cdr (reverse val))))))
- (if semantic-dump-parse
- (semantic-dump-detail (cdr nontermout)
- (car lte)
- ""
- "NonTerm Match"))
- (setq end (nth (1- len) val) ;reset end to the end of exp
- cvl (cons strip cvl) ;prepend value of exp
- lte (cdr lte)) ;update the local table entry
- )
- ;; No value means that we need to terminate this match.
- (semantic-overlay-stack-clear)
- (setq lte nil cvl nil)) ;No match, exit
- ))
- ;; Default case
- (t
- (setq lse (car s) ;Get the local stream element
- s (cdr s)) ;update stream.
- ;; Do the compare
- (if (eq (car lte) (car lse)) ;syntactic match
- (let ((valdot (cdr lse)))
- (setq val (semantic-flex-text lse))
- ;; DEBUG SECTION
- (if semantic-dump-parse
- (semantic-dump-detail
- (if (stringp (car (cdr lte)))
- (list (car (cdr lte)) (car lte))
- (list (car lte)))
- nonterminal val
- (if (stringp (car (cdr lte)))
- (if (string-match (car (cdr lte)) val)
- "Term Match" "Term Fail")
- "Term Type=")))
- ;; END DEBUG SECTION
- (setq lte (cdr lte))
- (if (stringp (car lte))
- (progn
- (setq tev (car lte)
- lte (cdr lte))
- (if (string-match tev val)
- (setq cvl (cons val cvl)) ;append this value
- (semantic-overlay-stack-clear)
- (setq lte nil cvl nil))) ;clear the entry (exit)
- (setq cvl (cons
- (if (member (car lse)
- '(comment semantic-list))
- valdot val) cvl))) ;append unchecked value.
- (setq end (cdr (cdr lse)))
- )
- (if (and semantic-dump-parse nil)
- (semantic-dump-detail (car lte)
- nonterminal (semantic-flex-text lse)
- "Term Type Fail"))
- (semantic-overlay-stack-clear)
- (setq lte nil cvl nil)) ;No more matches, exit
- )))
- (if (not cvl) ;lte=nil; there was no match.
- (setq matchlist (cdr matchlist)) ;Move to next matchlist entry
- (setq out (if (car lte)
-; REMOVE THIS TO USE THE REFERENCE/COMPARE CODE
-; (let ((o (apply (car lte) ;call matchlist fn on values
-; (nreverse cvl) start (list end))))
-; (if semantic-bovinate-create-reference (semantic-bovinate-add-reference o))
-; (if semantic-bovinate-compare-reference (semantic-bovinate-compare-against-reference
o))
-; o
-; )
- (funcall (car lte) ;call matchlist fn on values
- (nreverse cvl) start end)
- (cond ((and (= (length cvl) 1)
- (listp (car cvl))
- (not (numberp (car (car cvl)))) )
- (append (car cvl) (list start end)))
- (t
- (append (nreverse cvl) (list start end))))
- )
- matchlist nil) ;generate exit condition
- (if (not end) (setq out nil))
- ;; Nothin?
- ))
- (list s out semantic-overlay-error-recovery-stack)))
+ (if (not nonterminal)
+ (setq nonterminal 'bovine-toplevel))
+
+ ;; Try to detect infinite recursive parse when doing a full reparse.
+ (or semantic-toplevel-bovine-cache
+ (semantic-bovinate-nonterminal-check stream nonterminal))
+
+ (let ((matchlist (cdr (assq nonterminal table)))
+ (starting-stream stream)
+ (nt-loop t) ;non-terminal loop condition
+ nt-popup ;non-nil if return from nt recursion
+ nt-stack ;non-terminal recursion stack
+ s ;Temp Stream Tracker
+ lse ;Local Semantic Element
+ lte ;Local matchlist element
+ tev ;Matchlist entry values from buffer
+ val ;Value found in buffer.
+ cvl ;collected values list.
+ out ;Output
+ end ;End of match
+ result
+ semantic-overlay-error-recovery-stack ;part of error recovery
+ )
+ (while nt-loop
+ (catch 'push-non-terminal
+ (setq semantic-overlay-error-recovery-stack nil
+ nt-popup nil
+ end (cdr (cdr (car stream))))
+ (while (or nt-loop nt-popup)
+ (setq nt-loop nil
+ out nil)
+ (while (or nt-popup matchlist)
+ (if nt-popup
+ ;; End of a non-terminal recursion
+ (setq nt-popup nil)
+ ;; New matching process
+ (setq s stream ;init s from stream.
+ cvl nil ;re-init the collected value list.
+ lte (car matchlist) ;Get the local matchlist entry.
+ )
+ (if (or (byte-code-function-p (car lte))
+ (listp (car lte)))
+ ;; In this case, we have an EMPTY match! Make stuff
+ ;; up.
+ (setq cvl (list nil))))
+
+ (while (and lte
+ (not (byte-code-function-p (car lte)))
+ (not (listp (car lte))))
+
+ ;; BNF SOURCE DEBUGGING!
+ (if semantic-edebug
+ (let* ((db-nt (semantic-bovinate-nonterminal-db-nt))
+ (db-ml (cdr (assq db-nt table)))
+ (db-mlen (length db-ml))
+ (db-midx (- db-mlen (length matchlist)))
+ (db-tlen (length (nth db-midx db-ml)))
+ (db-tidx (- db-tlen (length lte))))
+ (if (eq 'fail
+ (semantic-bovinate-show
+ (car s) db-nt db-midx db-tidx cvl))
+ (setq lte '(trash 0 . 0)))))
+ ;; END BNF SOURCE DEBUGGING!
+
+ (cond
+ ;; We have a nonterminal symbol. Recurse inline.
+ ((setq nt-loop (assq (car lte) table))
+
+ (setq
+ ;; push state into the nt-stack
+ nt-stack (cons (vector matchlist cvl lte stream end
+ ;; error recovery
+ semantic-overlay-error-recovery-stack
+ )
+ nt-stack)
+ ;; new non-terminal matchlist
+ matchlist (cdr nt-loop)
+ ;; new non-terminal stream
+ stream s)
+
+ (throw 'push-non-terminal t)
+
+ )
+ ;; Default case
+ (t
+ (setq lse (car s) ;Get the local stream element
+ s (cdr s)) ;update stream.
+ ;; Do the compare
+ (if (eq (car lte) (car lse)) ;syntactic match
+ (let ((valdot (cdr lse)))
+ (setq val (semantic-flex-text lse))
+ ;; DEBUG SECTION
+ (if semantic-dump-parse
+ (semantic-dump-detail
+ (if (stringp (car (cdr lte)))
+ (list (car (cdr lte)) (car lte))
+ (list (car lte)))
+ (semantic-bovinate-nonterminal-db-nt)
+ val
+ (if (stringp (car (cdr lte)))
+ (if (string-match (car (cdr lte)) val)
+ "Term Match" "Term Fail")
+ "Term Type=")))
+ ;; END DEBUG SECTION
+ (setq lte (cdr lte))
+ (if (stringp (car lte))
+ (progn
+ (setq tev (car lte)
+ lte (cdr lte))
+ (if (string-match tev val)
+ (setq cvl (cons
+ (if (memq (car lse)
+ '(comment semantic-list))
+ valdot val)
+ cvl)) ;append this value
+ (semantic-overlay-stack-clear)
+ (setq lte nil cvl nil))) ;clear the entry (exit)
+ (setq cvl (cons
+ (if (memq (car lse)
+ '(comment semantic-list))
+ valdot val) cvl))) ;append unchecked value.
+ (setq end (cdr (cdr lse)))
+ )
+ (if (and semantic-dump-parse nil)
+ (semantic-dump-detail (car lte)
+ (semantic-bovinate-nonterminal-db-nt)
+ (semantic-flex-text lse)
+ "Term Type Fail"))
+ (semantic-overlay-stack-clear)
+ (setq lte nil cvl nil)) ;No more matches, exit
+ )))
+ (if (not cvl) ;lte=nil; there was no match.
+ (setq matchlist (cdr matchlist)) ;Move to next matchlist entry
+ (let ((start (car (cdr (car stream)))))
+ (setq out (cond
+ ((car lte)
+
+ ;; REMOVE THIS TO USE THE REFERENCE/COMPARE CODE
+ ;;(let ((o (apply (car lte) ;call matchlist fn on values
+ ;; (nreverse cvl) start (list end))))
+ ;; (if semantic-bovinate-create-reference
+ ;; (semantic-bovinate-add-reference o))
+ ;; (if semantic-bovinate-compare-reference
+ ;; (semantic-bovinate-compare-against-reference o))
+ ;; o
+ ;; )
+
+ (funcall (car lte) ;call matchlist fn on values
+ (nreverse cvl) start end))
+ ((and (= (length cvl) 1)
+ (listp (car cvl))
+ (not (numberp (car (car cvl)))))
+ (append (car cvl) (list start end)))
+ (t
+ ;;(append (nreverse cvl) (list start end))))
+ ;; MAYBE THE FOLLOWING NEEDS LESS CONS
+ ;; CELLS THAN THE ABOVE?
+ (nreverse (cons end (cons start cvl)))))
+ matchlist nil) ;;generate exit condition
+ (if (not end)
+ (setq out nil)))
+ ;; Nothin?
+ ))
+ (setq result
+ (if (eq s starting-stream)
+ (list (cdr s) nil
+ semantic-overlay-error-recovery-stack)
+ (list s out
+ semantic-overlay-error-recovery-stack)))
+ (if nt-stack
+ ;; pop previous state from the nt-stack
+ (let ((state (car nt-stack))
+ (ov semantic-overlay-error-recovery-stack))
+
+ (setq nt-popup t
+ ;; pop actual parser state
+ matchlist (aref state 0)
+ cvl (aref state 1)
+ lte (aref state 2)
+ stream (aref state 3)
+ end (aref state 4)
+ ;; pop error recovery state
+ semantic-overlay-error-recovery-stack (aref state 5)
+ ;; update the stack
+ nt-stack (cdr nt-stack))
+
+ (if ov
+ (semantic-overlay-stack-add ov))
+
+ (if out
+ (let ((len (length out))
+ (strip (nreverse (cdr (cdr (reverse out))))))
+ (if semantic-dump-parse
+ (semantic-dump-detail (cdr result)
+ (car lte)
+ ""
+ "NonTerm Match"))
+ (setq end (nth (1- len) out) ;reset end to the end of exp
+ cvl (cons strip cvl) ;prepend value of exp
+ lte (cdr lte)) ;update the local table entry
+ )
+ ;; No value means that we need to terminate this
+ ;; match.
+ (semantic-overlay-stack-clear)
+ (setq lte nil cvl nil)) ;No match, exit
+ )))))
+ result))
;;; Bovine table functions
@@ -877,22 +1311,38 @@
nonterm
depth)))
-(defun semantic-bovinate-block-until-header (start end nonterm &optional depth)
+(defun semantic-bovinate-region-until-error (start end nonterm &optional depth)
"Bovinate between START and END starting with NONTERM.
-If NONTERM is nil, start with `bovine-block-toplevel'.
Optinal DEPTH specifies how many levels of parenthesis to enter.
This command will parse until an error is encountered, and return
the list of everything found until that moment.
This is meant for finding variable definitions at the beginning of
-code blocks in methods. If `bovine-block-toplevel' can also support
+code blocks in methods. If `bovine-inner-scope' can also support
commands, use `semantic-bovinate-from-nonterminal-full'."
(nreverse
- (semantic-bovinate-nonterminals (semantic-flex start end (or depth 1))
+ (semantic-bovinate-nonterminals (semantic-flex start end depth)
nonterm
depth
;; This says stop on an error.
t)))
+(defun semantic-bovinate-make-assoc-list (&rest args)
+ "Create an association list with ARGS.
+Args are of the form (KEY1 VALUE1 ... KEYN VALUEN).
+The return value will be of the form: ((KEY1 . VALUE1) ... (KEYN . VALUEN))
+Where KEY is a symbol, and VALUE is the value for that symbol.
+If VALUE is nil, then KEY is excluded from the return association list."
+ (let ((ret nil))
+ (while args
+ (let ((value (car-safe (cdr args))))
+ (if (and value
+ (or (not (stringp value))
+ (not (string= value "")))
+ (or (not (numberp value))
+ (not (= value 0))))
+ (setq ret (cons (cons (car args) (car (cdr args))) ret)))
+ (setq args (cdr (cdr args)))))
+ (nreverse ret)))
;;; Debugging in bovine tables
;;
@@ -930,18 +1380,27 @@
(beginning-of-defun)
(setq semantic-bovinate-debug-table (point-marker)))
+;; We will get warnings in here about semantic-bnf-* fns.
+;; We cannot require semantic-bnf due to compile eerrors.
(defun semantic-bovinate-debug-buffer ()
"Bovinate the current buffer in debug mode."
(interactive)
- (if (not semantic-bovinate-debug-table)
+ (if (and (not semantic-toplevel-bovine-table-source)
+ (not semantic-bovinate-debug-table))
(error
"Call `semantic-bovinate-debug-set-table' from your semantic
table"))
+ (delete-other-windows)
+ (split-window-vertically)
+ (if semantic-bovinate-debug-table
+ (switch-to-buffer (marker-buffer semantic-bovinate-debug-table))
+ (if (not semantic-toplevel-bovine-table-source)
+ (error "No debuggable BNF source found"))
+ (require 'semantic-bnf)
+ (switch-to-buffer (semantic-bnf-find-source-on-load-path
+ semantic-toplevel-bovine-table-source)))
+ (other-window 1)
+ (semantic-clear-toplevel-cache)
(let ((semantic-edebug t))
- (delete-other-windows)
- (split-window-vertically)
- (switch-to-buffer (marker-buffer semantic-bovinate-debug-table))
- (other-window 1)
- (semantic-clear-toplevel-cache)
(semantic-bovinate-toplevel)))
(defun semantic-bovinate-show (lse nonterminal matchlen tokenlen collection)
@@ -952,7 +1411,10 @@
MATCHLEN is the number of match lists tried.
TOKENLEN is the number of match tokens tried.
COLLECTION is the list of things collected so far."
- (let ((ol1 nil) (ol2 nil) (ret nil))
+ (let* ((semantic-edebug nil)
+ (ol1 nil) (ol2 nil) (ret nil)
+ (bnf-buffer (semantic-bnf-find-source-on-load-path
+ semantic-toplevel-bovine-table-source)))
(unwind-protect
(progn
(goto-char (car (cdr lse)))
@@ -961,20 +1423,37 @@
(goto-char (car (cdr lse)))
(if window-system nil (sit-for 1))
(other-window 1)
- (set-buffer (marker-buffer semantic-bovinate-debug-table))
- (goto-char semantic-bovinate-debug-table)
- (re-search-forward
- (concat "^\\s-*\\((\\|['`]((\\)\\(" (symbol-name nonterminal)
- "\\)[ \t\n]+(")
- nil t)
- (setq ol2 (semantic-make-overlay (match-beginning 2) (match-end 2)))
- (semantic-overlay-put ol2 'face 'highlight)
- (forward-char -2)
- (forward-list matchlen)
- (skip-chars-forward " \t\n(")
- (forward-sexp tokenlen)
+ (let (s e)
+ (if semantic-bovinate-debug-table
+ (progn
+ (set-buffer (marker-buffer semantic-bovinate-debug-table))
+ (goto-char semantic-bovinate-debug-table)
+ (re-search-forward
+ (concat "^\\s-*\\((\\|['`]((\\)\\(" (symbol-name nonterminal)
+ "\\)[ \t\n]+(")
+ nil t)
+ (setq s (match-beginning 2)
+ e (match-end 2))
+ (forward-char -2)
+ (forward-list matchlen)
+ (skip-chars-forward " \t\n(")
+ (forward-sexp tokenlen)
+ )
+ ;; The user didn't specify a lisp level table.
+ ;; go to the source...
+ (set-buffer bnf-buffer)
+ (semantic-bnf-find-state-position
+ nonterminal matchlen tokenlen)
+ (save-excursion
+ (goto-char (semantic-token-start (semantic-current-nonterminal)))
+ (setq s (point)
+ e (progn (forward-sexp 1) (point))))
+ )
+ (setq ol2 (semantic-make-overlay s e))
+ (semantic-overlay-put ol2 'face 'highlight)
+ )
(message "%s: %S" lse collection)
- (let ((e (read-event)))
+ (let ((e (semantic-read-event)))
(cond ((eq e ?f) ;force a failure on this symbol.
(setq ret 'fail))
(t nil)))
@@ -1073,18 +1552,92 @@
))
+;;; Keyword Table Handling.
+;;
+(defvar semantic-flex-keywords-obarray nil
+ "Buffer local keyword obarray for the lexical analyzer.
+These keywords are matched explicitly, and converted into special symbols.")
+(make-variable-buffer-local 'semantic-flex-keywords-obarray)
+
+(defun semantic-flex-make-keyword-table (keywords &optional propertyalist)
+ "Convert a list of KEYWORDS into an obarray.
+Save the obarry into `semantic-flex-keywords-obarray'.
+If optional argument PROPERTYALIST is non nil, then interpret it, and
+apply those properties"
+ ;; Create the symbol hash table
+ (let ((obarray (make-vector 13 nil)))
+ ;; fill it with stuff
+ (while keywords
+ (set (intern (car (car keywords)) obarray)
+ (cdr (car keywords)))
+ (setq keywords (cdr keywords)))
+ ;; Apply all properties
+ (let ((semantic-flex-keywords-obarray obarray))
+ (while propertyalist
+ (semantic-flex-keyword-put (car (car propertyalist))
+ (nth 1 (car propertyalist))
+ (nth 2 (car propertyalist)))
+ (setq propertyalist (cdr propertyalist))))
+ obarray))
+
+(defun semantic-flex-keyword-p (text)
+ "Return a symbol if TEXT is a keyword in the keyword table.
+Return nil if TEXT is not in the symbol table."
+ (let ((sym (intern-soft text semantic-flex-keywords-obarray)))
+ (if sym (symbol-value sym))))
+
+(defun semantic-flex-keyword-put (text property value)
+ "For keyword TEXT, set PROPERTY to have VALUE."
+ (let ((sym (intern-soft text semantic-flex-keywords-obarray)))
+ (if (not sym) (signal 'wrong-type-argument (list text 'keyword)))
+ (put sym property value)))
+
+(defun semantic-flex-keyword-get (text property)
+ "For keyword TEXT, get the value of PROPERTY."
+ (let ((sym (intern-soft text semantic-flex-keywords-obarray)))
+ (if (not sym) (signal 'wrong-type-argument (list text 'keyword)))
+ (get sym property)))
+
+;; David Ponce
+(defun semantic-flex-map-keywords (fun &optional property)
+ "Call function FUN on every semantic keyword.
+If optional PROPERTY is non-nil call FUN only on every keyword which
+have a PROPERTY value. FUN receives a semantic keyword as argument."
+ (if (arrayp semantic-flex-keywords-obarray)
+ (mapatoms
+ (function
+ (lambda (keyword)
+ (and keyword
+ (or (null property) (get keyword property))
+ (funcall fun keyword))))
+ semantic-flex-keywords-obarray)))
+
+;; David Ponce
+(defun semantic-flex-keywords (&optional property)
+ "Return a list of semantic keywords.
+If optional PROPERTY is non-nil return only keyword which have a
+PROPERTY value."
+ (let (keywords)
+ (semantic-flex-map-keywords
+ (function
+ (lambda (keyword)
+ (setq keywords (cons keyword keywords))))
+ property)
+ keywords))
+
+;;; Lexical Analysis
+;;
(defvar semantic-flex-extensions nil
"Buffer local extensions to the lexical analyzer.
This should contain an alist with a key of a regex and a data element of
a function. The function should both move point, and return a lexical
-token of the form ( TYPE START . END). nil is also a valid return.")
+token of the form:
+ ( TYPE START . END)
+nil is also a valid return.
+TYPE can be any type of symbol, as long as it doesn't occur as a
+nonterminal in the language definition.")
(make-variable-buffer-local 'semantic-flex-extensions)
-(defvar semantic-flex-keywords-obarray nil
- "Buffer local keyword obarray for the lexical analyzer.
-These keywords are matched explicitly, and converted into special symbols.")
-(make-variable-buffer-local 'semantic-flex-keywords-obarray)
-
(defvar semantic-flex-syntax-modifications nil
"Updates to the syntax table for this buffer.
These changes are active only while this file is being flexed.
@@ -1101,23 +1654,6 @@
Only set this on a per mode basis, not globally.")
(make-variable-buffer-local 'semantic-flex-enable-newlines)
-(defun semantic-flex-make-keyword-table (keywords)
- "Convert a list of KEYWORDS into an obarray.
-Save the obarry into `semantic-flex-keywords-obarray'."
- ;; Create the symbol hash table
- (let ((obarray (make-vector 13 nil)))
- ;; fill it with stuff
- (while keywords
- (set (intern (car (car keywords)) obarray)
- (cdr (car keywords)))
- (setq keywords (cdr keywords)))
- obarray))
-
-(defun semantic-flex-is-keyword (text)
- "Return a symbol if TEXT is a keyword."
- (let ((sym (intern-soft text semantic-flex-keywords-obarray)))
- (if sym (symbol-value sym))))
-
(defun semantic-flex-buffer (&optional depth)
"Sematically flex the current buffer.
Optional argument DEPTH is the depth to scan into lists."
@@ -1159,9 +1695,10 @@
(while (and (< (point) end) (or (not length) (<= (length ts) length)))
(cond (;; catch newlines when needed
(and semantic-flex-enable-newlines
- (looking-at "\n"))
- (setq ts (cons (cons 'newline
- (cons (match-beginning 0) (match-end 0)))
+ (looking-at "\\s-*\\(\n\\)"))
+ (setq ep (match-end 1)
+ ts (cons (cons 'newline
+ (cons (match-beginning 1) ep))
ts)))
;; special extentions, sometimes includes some whitespace.
((and semantic-flex-extensions
@@ -1182,7 +1719,7 @@
((looking-at "\\(\\sw\\|\\s_\\)+")
(setq ts (cons (cons
;; Get info on if this is a keyword or not
- (or (semantic-flex-is-keyword (match-string 0))
+ (or (semantic-flex-keyword-p (match-string 0))
'symbol)
(cons (match-beginning 0) (match-end 0)))
ts)))
@@ -1207,7 +1744,7 @@
(forward-list 1)
;; This case makes flex robust
;; to broken lists.
- (error (goto-char (point-max))))
+ (error (goto-char end)))
(setq ep (point)))))
ts))))
;; Close parens
@@ -1229,8 +1766,21 @@
(if semantic-ignore-comments
;; If the language doesn't deal with comments,
;; ignore them here.
- (progn (forward-comment 1)
- (setq ep (point)))
+ (let ((comment-start-point (point)))
+ (forward-comment 1)
+ (if (eq (point) comment-start-point)
+ ;; In this case our start-skip string failed
+ ;; to work properly. Lets try and move over
+ ;; whatever white space we matched to begin
+ ;; with.
+ (skip-syntax-forward "-.'"
+ (save-excursion
+ (end-of-line)
+ (point)))
+ (forward-comment 1))
+ (if (eq (point) comment-start-point)
+ (error "Strange comment syntax prevents lexical analysis"))
+ (setq ep (point)))
;; Language wants comments, link them together.
(if (eq (car (car ts)) 'comment)
(setcdr (cdr (car ts)) (save-excursion
@@ -1273,13 +1823,15 @@
;;
(autoload 'semantic-create-imenu-index "semantic-imenu"
"Create an imenu index for any buffer which supports Semantic.")
-(autoload 'bovinate "semantic-util"
- "Bovinate the current buffer. Show output in a temp buffer.
-Optional argument CLEAR will clear the cache before bovinating." t)
-(autoload 'bovinate-debug "semantic-util"
- "Bovinate the current buffer and run in debug mode." t)
+(autoload 'senator-minor-mode "senator"
+ "Minor mode for the SEmantic NAvigaTOR." t)
+(autoload 'global-semanticdb-minor-mode "semanticdb"
+ "Mode saving token lists between sessions." t)
(provide 'semantic)
;;; semantic.el ends here
+;; Semantic-util is a part of the semantic API. Include it last
+;; because it depends on semantic.
+(require 'semantic-util)
Index: xemacs-packages/semantic/semantic.el.upstream
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/semantic/semantic.el.upstream,v
retrieving revision 1.1
diff -u -r1.1 semantic.el.upstream
--- xemacs-packages/semantic/semantic.el.upstream 2001/02/20 03:23:46 1.1
+++ xemacs-packages/semantic/semantic.el.upstream 2001/08/15 05:28:23
@@ -3,10 +3,12 @@
;;; Copyright (C) 1999, 2000, 2001 Eric M. Ludlam
;; Author: Eric M. Ludlam <zappo(a)gnu.org>
-;; Version: 1.3.3
;; Keywords: syntax
-;; X-RCS: $Id: semantic.el.upstream,v 1.1 2001/02/20 03:23:46 youngs Exp $
+;; X-RCS: $Id: semantic.el,v 1.107 2001/07/13 15:39:35 zappo Exp $
+(defvar semantic-version "1.4beta8"
+ "Current version of Semantic.")
+
;; This file is not part of GNU Emacs.
;; Semantic is free software; you can redistribute it and/or modify
@@ -32,192 +34,14 @@
;; The output of a semantic bovine parse is parse tree. While it is
;; possible to assign actions in the bovine-table in a similar fashion
;; to bison, this is not it's end goal.
-;;
-;; Bovine Table Tips & Tricks:
-;; ---------------------------
-;;
-;; Many of the tricks needed to create rules in bison or yacc can be
-;; used here. The exceptions to this rule are that there is no need to
-;; declare bison tokens, and you cannot put "code" in the middle of a
-;; match rule. In addition, you should avoid empty matching rules as
-;; I haven't quite gotten those to be reliable yet.
-;;
-;; The top-level bovine table is an association list of all the rules
-;; needed to parse your language, or language segment. It is easiest
-;; to create one master rule file, and call the semantic bovinator on
-;; subsections passing down the nonterminal rule you want to match.
-;;
-;; Thus, every entry in the bovine table is of the form:
-;; ( NONTERMINAL-SYMBOL MATCH-LIST )
-;;
-;; The nonterminal symbol is equivalent to the bison RESULT, and the
-;; MATCH-LIST is equivalent to the bison COMPONENTS. Thus, the bison
-;; rule:
-;; expseq: expseq1
-;; | expseq2
-;; ;
-;; becomes:
-;; ( expseq ( expseq1 ) ( expseq2 ) )
-;; which defines RESULT expseq which can be either COMPONENT expseq1
-;; or expseq2. These two table entries also use nonterminal results,
-;; and also use the DEFAULT RESULT LAMBDA (see below for details on
-;; the RESULT LAMBDA).
-;;
-;; You can also have recursive rules, as in bison. For example the
-;; bison rule:
-;; expseq1: exp
-;; | expseq1 ',' exp
-;; ;
-;; becomes:
-;; (expseq1 (exp)
-;; (expseq1 punctuation "," exp
-;; (lambda (val start end)
-;; ( -generator code- ))))
-;;
-;; This time, the second rule uses it's own RESULT LAMBDA.
-;;
-;; Lastly, you can also have STRING LITERALS in your rules, though
-;; these are different from Bison. As can be seen above, a literal is
-;; a constant lexed symbol, such as `punctuation', followed by a string
-;; which is a *regular expression* which must match, or this rule will
-;; fail.
-;;
-;; In BISON, a given rule can have inline ACTIONS. In the semantic
-;; bovinator, there can be only one ACTION which I will refer to here
-;; as the RESULT LAMBDA. There are two default RESULT LAMBDAs which
-;; can be used which cover the default case. The RESULT LAMBDA must
-;; return a valid nonterminal token. A nonterminal token is always of the
-;; form ( NAME TOKEN VALUE1 VALUE2 ... START END). NAME is the name
-;; to use for this token. It is first so that a list of tokens is
-;; also an alist, or completion table. Token should be the same
-;; symbol as the nonterminal token generated, though it does not have to
-;; be. The values can be anything you want, including other tokens.
-;; START and END indicate where in the buffer this token is, and is
-;; easily derived from the START and END parameter passed down.
-;;
-;; A RESULT LAMBDA must take three parameters, VALS, START and END.
-;; VALS is the list of literals derived during the bovination of the
-;; match list, including punctuation, parens, and explicit
-;; matches. other elements
-;;
-;; Here are some example match lists and their code:
-;;
-;; (expression (lambda (vals start end)
-;; (append (car vals) (list start end))))
-;;
-;; In this RESULT LAMBDA, VALS will be of length one, and it's first
-;; element will contain the nonterminal expression result. It is
-;; likely to use a rule like this when there is a top level nonterminal
-;; symbol whose contents are several other single nonterminal rules.
-;; Because of this, we want to result that value with our START and END
-;; appended.
-;;
-;; NOTE: nonterminal values passed in as VALS always have their
-;; START/END parts stripped!
-;;
-;; This example lambda is also one of the DEFAULT lambdas for the case
-;; of a single nonterminal result. Thus, the above rule could also be
-;; written as (expression).
-;;
-;; A more complex example uses more flex elements. Lets match this:
-;;
-;; (defun myfunction (arguments) "docstring" ...)
-;;
-;; If we assume a flex depth of 1, we can write it this way:
-;;
-;; (open-paren "(" symbol "defun" symbol semantic-list string
-;; (lambda (vals start end)
-;; (list (nth 2 vals) 'function nil (nth 3 vals)
-;; (nth 4 vals) start end)))
-;;
-;; The above will create a function token, whose format is
-;; predefined. (See the symbol `semantic-toplevel-bovine-table' for
-;; details on some default symbols that should be provided.)
-;;
-;; From this we can see that VALS will have the value:
-;; ( "(" "defun" "myfunction" "(arguments)"
"docstring")
-;;
-;; If we also want to return a list of arguments in our function
-;; token, we can replace `semantic-list' with the following recursive
-;; nonterminal rule.
-;;
-;; ( arg-list (semantic-list
-;; (lambda (vals start end)
-;; (semantic-bovinate-from-nonterminal start end 'argsyms))))
-;; ( argsyms
-;; (open-paren argsyms (lambda (vals start end)
-;; (append (car (cdr vals)) (list start end))))
-;; (symbol argsyms (lambda (vals start end)
-;; (append (cons (car vals) (car (cdr vals)))
-;; (list start end))))
-;; (symbol close-paren (lambda (vals start end)
-;; (list (car vals) start end))))
-;;
-;; This recursive rule can find a parenthetic list with any number of
-;; symbols in it.
-;;
-;; Here we also see a new function, `semantic-bovinate-from-nonterminal'.
-;; This function takes START END and a nonterminal result symbol to
-;; match. This will return a complete token, including START and
-;; END. This function should ONLY BE USED IN A RESULT LAMBDA. It
-;; uses knowledge of that scope to reduce the number of parameters
-;; that need to be passed in. This is useful for decomposing complex
-;; syntactic elements, such as semantic-list.
-;;
-;; Token's and the VALS argument
-;; -----------------------------
-;;
-;; Not all syntactic tokens are represented by strings in the VALS argument
-;; to the match-list lambda expression. Some are a dotted pair (START . END).
-;; The following are represented as strings:
-;; 1) symbols
-;; 2) punctuation
-;; 3) open/close-paren
-;; 4) charquote
-;; 5) strings
-;; The following are represented as a dotted-pair.
-;; 1) semantic-list
-;; 2) comments
-;; Nonterminals are always lists which are generated in the lambda
-;; expression.
-;;
-;; Semantic Bovine Table Debugger
-;; ------------------------------
-;;
-;; The bovinator also includes a primitive debugger. This debugger
-;; walks through the parsing process and see how it's being
-;; interpretted. There are two steps in debuggin a bovine table.
-;;
-;; First, place the cursor in the source code where the table is
-;; defined. Execute the command `semantic-bovinate-debug-set-table'.
-;; This tells the debugger where you table is.
-;;
-;; Next, place the cursor in a buffer you which to run the bovinator
-;; on, and execute the command `semantic-bovinate-buffer-debug'. This
-;; will parse the table, and highlight the relevant areas and walk
-;; through the match list with the cursor, displaying the current list
-;; of values (which is always backwards.)
-;;
-;; DESIGN ISSUES:
-;; -------------
-;;
-;; At the moment, the only thing I really dislike is the RESULT
-;; LAMBDA format. While having some good defaults is nice, the use
-;; of append and list in the lambda seems unnecessarily complex.
-;;
-;; Also of issue, I am still not sure I like the idea of stripping
-;; BEGIN/END off of nonterminal tokens passed down in VALS. While they
-;; are often unnecessary, I can imagine that they could prove useful.
-;; Only time will tell.
;;; History:
;;
(require 'working)
-(require 'semantic-util)
(defgroup semantic nil
- "File and tag browser frame."
+ "Parser Generator/Parser."
)
;;; Code:
@@ -243,6 +67,14 @@
(defalias 'semantic-overlay-lists
(lambda () (list (extent-list))))
(defalias 'semantic-overlay-p 'extentp)
+ (defun semantic-read-event ()
+ (let ((event (next-command-event)))
+ (if (key-press-event-p event)
+ (let ((c (event-to-character event)))
+ (if (char-equal c (quit-char))
+ (keyboard-quit)
+ c)))
+ event))
)
(defalias 'semantic-overlay-live-p 'overlay-buffer)
(defalias 'semantic-make-overlay 'make-overlay)
@@ -258,6 +90,7 @@
(defalias 'semantic-overlay-previous-change 'previous-overlay-change)
(defalias 'semantic-overlay-lists 'overlay-lists)
(defalias 'semantic-overlay-p 'overlayp)
+ (defalias 'semantic-read-event 'read-event)
)
(defvar semantic-edebug nil
@@ -317,7 +150,7 @@
Bovine table entry return elements are up to the table author. It is
recommended, however, that the following format be used.
- (\"NAME\" type-symbol [\"TYPE\"] ... \"DOCSTRING\"
OVERLAY)
+ (\"NAME\" type-symbol [\"TYPE\"] ... \"DOCSTRING\"
PROPERTIES OVERLAY)
Where type-symbol is the type of return token found, and NAME is it's
name. If there is any typing information needed to describe this
@@ -327,10 +160,18 @@
Emacs Lisp. It could be the text of a comment appearing just before a
function call, or in line with a variable.
-The last element must be OVERLAY.
-The OVERLAY is automatically created by semantic from an input that
-consists of START and END. When building a parser table, use START
-and END as positions in the buffer.
+PROPERTIES is a list of additional properties for this token.
+PRORPERTIES is not for details of the token. It is used for
+additional tags needed by tools using the parse stream. For example,
+the `dirty' property is used when a given token needs to be reparsed.
+
+PROPERTIES are automatically added to the token by the system when
+using BNF, or `semantic-lambda' in the table.
+
+The last element must be OVERLAY. The OVERLAY is automatically
+created by the parsing system. When programming with BNF, or using
+`semantic-lambda', no extra work needs to be done. If you are
+building the parse table yourself, use START and END.
It may seem odd to place NAME in slot 0, and the type-symbol in slot
1, but this turns the returned elements into a list which can be used
@@ -348,53 +189,83 @@
TOP-LEVEL ENTRIES:
- (\"NAME\" variable \"TYPE\" CONST DEFAULT-VALUE MODIFIERS
[OPTSUFFIX]
- \"DOCSTRING\" OVERLAY)
+ (\"NAME\" variable \"TYPE\" DEFAULT-VALUE EXTRA-SPEC
+ \"DOCSTRING\" PROPERTIES OVERLAY)
The definition of a variable, or constant.
- CONST is a boolean representing if this variable is considered a constant.
DEFAULT-VALUE can be something apropriate such a a string,
or list of parsed elements.
- MODIFIERS are details about a variable that are not covered in the TYPE.
- OPTSUFFIX is an optional field specifying trailing modifiers such as
- array dimentions or bit fields.
+ EXTRA-SPEC are details about a variable that are not covered in the TYPE.
+ See detail on EXTRA-SPEC after entries section.
DOCSTRING is optional.
- (\"NAME\" function \"TYPE\" ( ARG-LIST ) MODIFIERS [THROWS]
- \"DOCSTRING\" OVERLAY)
+ (\"NAME\" function \"TYPE\" ( ARG-LIST ) EXTRA-SPEC
+ \"DOCSTRING\" PROPERTIES OVERLAY)
A function/procedure definition.
ARG-LIST is a list of variable definitions.
- THROWS is an optional argument for functions or methods in languages
- that support typed signal throwing.
DOCSTRING is optional.
- (\"NAME\" type \"TYPE\" ( PART-LIST ) ( PARENTS ) MODIFIERS
- \"DOCSTRING\" OVERLAY)
+ (\"NAME\" type \"TYPE\" ( PART-LIST ) ( PARENTS ) EXTRA-SPEC
+ \"DOCSTRING\" PROPERTIES OVERLAY)
A type definition.
TYPE of a type could be anything, such as (in C) struct, union, typedef,
- or class.
+ or class.
PART-LIST is only useful for structs that have multiple individual parts.
(It is recommended that these be variables, functions or types).
PARENTS is strictly for classes where there is inheritance.
-
+ See `semantic-token-parent' for a description of this value.
- (\"FILE\" include SYSTEM \"DOCSTRING\" OVERLAY)
+ (\"FILE\" include SYSTEM \"DOCSTRING\" PROPERTIES OVERLAY)
In C, an #include statement. In elisp, a require statement.
Indicates additional locations of sources or definitions.
SYSTEM is true if this include is part of a set of system includes.
- (\"NAME\" package DETAIL \"DOCSTRING\" OVERLAY)
+ (\"NAME\" package DETAIL \"DOCSTRING\" PROPERTIES OVERLAY)
In Emacs Lisp, a `provide' statement. DETAIL might be an
- associated file name.
+ associated file name. In Java, this is a package statement.
+
+EXTRA-SPEC:
+
+ The EXTRA-SPEC section of variables, functions, and types provide a
+location to place language specific details which are not accounted
+for by the base token type. Because there is an arbitrary number of
+things that could be associated in the EXTRA-SPEC section, this should
+be formatted as an association list.
+
+ Here are some typed extra specifiers that may exist. Any arbitrary
+number of extra specifiers may be created, and specifiers not
+documented here are allowed.
-OTHER ENTRIES:")
+ (parent . \"text\") - Name of a parent type/class. C++ and CLOS allow
+ the creation of a function outside the body of that type/class.
+
+ (dereference . INT) - Number of levels of dereference. In C, the number
+ of `*' characters indicating pointers.
+
+ (typemodifiers . \"text\") - Keyword modifiers for a type. In C, such
+ words would include `register', and `volatile'.
+
+ (suffix . \"text\") - Suffix information for a variable.
+
+ (const . t) - This exists if the variable or return value is constant.
+
+ (throws . \"text\") - For functions or methods in languages that support
+ typed signal throwing.
+
+ (user-visible . t) - For functions in interpreted languages such as Emacs Lisp,
+ this signals that a function or variable is user visible. In Emacs Lisp,
+ this means a function is `interactive'.")
(make-variable-buffer-local 'semantic-toplevel-bovine-table)
+(defvar semantic-toplevel-bovine-table-source nil
+ "The .bnf source file the current table was created from.")
+(make-variable-buffer-local 'semantic-toplevel-bovine-table-source)
+
(defvar semantic-symbol->name-assoc-list
'((variable . "Variables")
(function . "Functions")
- (type . "Types")
- (include . "Dependencies")
- (package . "Provides"))
+ (type . "Types")
+ (include . "Dependencies")
+ (package . "Provides"))
"Association between symbols returned, and a string.
The string is used to represent a group of objects of the given type.
It is sometimes useful for a language to use a different string
@@ -419,55 +290,136 @@
(make-variable-buffer-local 'semantic-ignore-comments)
(defvar semantic-expand-nonterminal nil
- "Function to call for each returned Non-terminal.
+ "Function to call for each nonterminal production.
Return a list of non-terminals derived from the first argument, or nil
-if it does not need to be expanded.")
+if it does not need to be expanded.
+Languages with compound definitions should use this function to expand
+from one compound symbol into several. For example, in C the definition
+ int a, b;
+is easily parsed into one token. This function should take this
+compound token and turn it into two tokens, one for A, and the other for B.")
(make-variable-buffer-local 'semantic-expand-nonterminal)
(defvar semantic-toplevel-bovine-cache nil
"A cached copy of a recent bovination, plus state.
If no significant changes have been made (based on the state) then
-this is returned instead of re-parsing the buffer.")
+this is returned instead of re-parsing the buffer.
+
+ DO NOT USE THIS VARIABLE IN PROGRAMS.
+
+If you need a token list, use `semantic-bovinate-toplevel'. If you
+need the cached values for some reason, chances are you can, add a
+hook to `semantic-after-toplevel-cache-change-hook'.")
(make-variable-buffer-local 'semantic-toplevel-bovine-cache)
+(defvar semantic-edits-are-safe nil
+ "When non-nil, modifications do not require a reparse.
+This prevents tokens from being marked dirty, and it
+prevents top level edits from causing a cache check.
+Use this when writing programs that could cause a full
+reparse, but will not change the tag structure, such
+as adding or updating top-level comments.")
+
(defvar semantic-toplevel-bovine-cache-check nil
"Non nil if the bovine cache is out of date.
This is tracked with `semantic-change-function'.")
(make-variable-buffer-local 'semantic-toplevel-bovine-cache-check)
+
+(defvar semantic-toplevel-bovine-force-reparse nil
+ "Non nil if the next token request forces a reparse.")
+(make-variable-buffer-local 'semantic-toplevel-bovine-force-reparse)
+
+(defvar semantic-dirty-tokens nil
+ "List of tokens in the current buffer which are dirty.
+Dirty functions can then be reparsed, and spliced back into the main list.")
+(make-variable-buffer-local 'semantic-dirty-tokens)
+
+(defvar semantic-bovinate-nonterminal-check-obarray nil
+ "Obarray of streams already parsed for nonterminal symbols.")
+(make-variable-buffer-local 'semantic-bovinate-nonterminal-check-obarray)
+
+(defvar semantic-dirty-token-hooks nil
+ "Hooks run after when a token is marked as dirty (edited by the user).
+The functions must take TOKEN, START, and END as a parameters.
+This hook will only be called once when a token is first made dirty,
+subsequent edits will not cause this to run a second time unless that
+token is first cleaned. Any token marked as dirty will
+also be called with `semantic-clean-token-hooks', unless a full
+reprase is done instead.")
+
+(defvar semantic-clean-token-hooks nil
+ "Hooks run after a token is marked as clean (reparsed after user edits.)
+The functions must take a TOKEN as a parameter.
+Any token sent to this hook will have first been called with
+`semantic-dirty-token-hooks'. This hook is not called for tokens
+marked dirty if the buffer is completely reparsed. In that case, use
+`semantic-after-toplevel-bovinate-hook'.")
+
+(defvar semantic-change-hooks nil
+ "Hooks run when semantic detects a change in a buffer.
+Each hook function must take three arguments, identical to the
+common hook `after-change-function'.")
-(defvar semantic-toplevel-bovinate-override nil
+(defvar semantic-bovinate-toplevel-override nil
"Local variable set by major modes which provide their own bovination.
This function should behave as the function `semantic-bovinate-toplevel'.")
-(make-variable-buffer-local 'semantic-toplevel-bovinate-override)
+(make-variable-buffer-local 'semantic-bovinate-toplevel-override)
(defvar semantic-after-toplevel-bovinate-hook nil
"Hooks run after a toplevel token parse.
It is not run if the toplevel parse command is called, and buffer does
-not need to be reparsed.
+not need to be fully reparsed.
For language specific hooks, make sure you define this as a local hook.")
+(defvar semantic-after-toplevel-cache-change-hook nil
+ "Hooks run after the buffer token list has changed.
+This list will change when a buffer is reparsed, or when the token
+list in a buffer is cleared. It is *NOT* called if the current token
+list partially reparsed.
+
+Hook functions must take one argument, which is the new list of
+tokens associated with this buffer.
+
+For language specific hooks, make sure you define this as a local hook.")
+
(defvar semantic-before-toplevel-cache-flush-hook nil
"Hooks run before the toplevel nonterminal cache is flushed.
-For language specific hooks, make sure you define this as a local hook.")
+For language specific hooks, make sure you define this as a local hook.
+This hook is called before a corresponding
+`semantic-after-toplevel-bovinate-hook' which is also called during a
+flush when the cache is given a new value of nil.")
(defvar semantic-reparse-needed-change-hook nil
"Hooks run when a user edit is detected as needing a reparse.
-For language specific hooks, make sure you define this as a local hook.")
+For language specific hooks, make sure you define this as a local
+hook.
+Not used yet; part of the next generation reparse mechanism")
(defvar semantic-no-reparse-needed-change-hook nil
"Hooks run when a user edit is detected as not needing a reparse.
If the hook returns non-nil, then declare that a reparse is needed.
-For language specific hooks, make sure you define this as a local hook.")
+For language specific hooks, make sure you define this as a local
+hook.
+Not used yet; part of the next generation reparse mechanism.")
-;;; Utility API functions
+;;; Primitive Token access system:
;;
-;; These functions use the flex and bovination engines to perform some
-;; simple tasks useful to other programs. These are just the most
-;; critical entries.
-;;
-;; See semantic-util for a wider range of utility functions and macros.
-;;
+;; These are token level APIs (similar to some APIs in semantic-util)
+;; which are required for parsing operations. Semantic.el should have
+;; no dependencies on other semantic files.
+;;
+;; TFE = Token From End
+
+(defconst semantic-tfe-overlay 1
+ "Amount to subtract from the length of the token to get the overlay.")
+(defconst semantic-tfe-properties 2
+ "Amount to subtract from the length of the token to get the property
list.")
+(defconst semantic-tfe-docstring 3
+ "Amount to subtract from the length of the token to get the doc string.")
+(defconst semantic-tfe-number 2
+ "The number of required end elements.")
+
(defmacro semantic-token-token (token)
"Retrieve from TOKEN the token identifier.
ie, the symbol 'variable, 'function, 'type, or other."
@@ -481,41 +433,92 @@
"Retrieve the documentation of TOKEN.
Optional argument BUFFER indicates where to get the text from.
If not provided, then only the POSITION can be provided."
- (let ((p (nth (- (length token) 2) token)))
+ (let ((p (nth (- (length token) semantic-tfe-docstring) token)))
(if (and p buffer)
(save-excursion
(set-buffer buffer)
(semantic-flex-text (car (semantic-flex p (1+ p)))))
p)))
+(defmacro semantic-token-properties (token)
+ "Retrieve the PROPERTIES part of TOKEN.
+The returned item is an ALIST of (KEY . VALUE) pairs."
+ `(nth (- (length ,token) semantic-tfe-properties) ,token))
+
+(defmacro semantic-token-properties-cdr (token)
+ "Retrieve the cons cell for the PROPERTIES part of TOKEN."
+ `(nthcdr (- (length ,token) semantic-tfe-properties) ,token))
+
+(defun semantic-token-put (token key value)
+ "For TOKEN, put the property KEY on it with VALUE.
+If VALUE is nil, then remove the property from TOKEN."
+ (let* ((c (semantic-token-properties-cdr token))
+ (al (car c))
+ (a (assoc key (car c))))
+ (if a
+ (if value
+ (setcdr a value)
+ (adelete 'al key)
+ (setcar c al))
+ (if value
+ (setcar c (cons (cons key value) (car c)))))
+ ))
+
+(defun semantic-token-get (token key)
+ "For TOKEN, get the value for property KEY."
+ (cdr (assoc key (semantic-token-properties token))))
+
(defmacro semantic-token-overlay (token)
- "Retrieve the OVERLAY part of TOKEN."
- `(nth (- (length ,token) 1) ,token))
+ "Retrieve the OVERLAY part of TOKEN.
+The returned item may be an overlay or an unloaded buffer representation."
+ `(nth (- (length ,token) semantic-tfe-overlay) ,token))
+
+(defmacro semantic-token-overlay-cdr (token)
+ "Retrieve the cons cell containing the OVERLAY part of TOKEN."
+ `(nthcdr (- (length ,token) semantic-tfe-overlay) ,token))
(defmacro semantic-token-extent (token)
"Retrieve the extent (START END) of TOKEN."
- `(let ((over (semantic-token-overlay ,token)))
- (list (semantic-overlay-start over) (semantic-overlay-end over))))
+ `(let ((o (semantic-token-overlay ,token)))
+ (if (semantic-overlay-p o)
+ (list (semantic-overlay-start o) (semantic-overlay-end o))
+ (list (aref o 0) (aref o 1)))))
-(defmacro semantic-token-start (token)
+(defun semantic-token-start (token)
"Retrieve the start location of TOKEN."
- `(semantic-overlay-start (semantic-token-overlay ,token)))
+ (let ((o (semantic-token-overlay token)))
+ (if (semantic-overlay-p o) (semantic-overlay-start o) (aref o 0))))
-(defmacro semantic-token-end (token)
+(defun semantic-token-end (token)
"Retrieve the end location of TOKEN."
- `(semantic-overlay-end (semantic-token-overlay ,token)))
+ (let ((o (semantic-token-overlay token)))
+ (if (semantic-overlay-p o) (semantic-overlay-end o) (aref o 1))))
-(defmacro semantic-token-buffer (token)
+(defun semantic-token-buffer (token)
"Retrieve the buffer TOKEN resides in."
- `(semantic-overlay-buffer (semantic-token-overlay ,token)))
+ (let ((o (semantic-token-overlay token)))
+ (if (semantic-overlay-p o) (semantic-overlay-buffer o)
+ ;; We have no buffer for this token (It's not in Emacs right now.)
+ nil)))
(defun semantic-token-p (token)
"Return non-nil if TOKEN is most likely a semantic token."
(and (listp token)
(stringp (car token))
+ (car (cdr token))
(symbolp (car (cdr token)))))
-;;; Parsing functions
+(defun semantic-token-with-position-p (token)
+ "Return non-nil if TOKEN is a semantic token with positional information."
+ (and (listp token)
+ (stringp (car token))
+ (symbolp (car (cdr token)))
+ (let ((o (semantic-token-overlay token)))
+ (or (semantic-overlay-p o)
+ (arrayp o)))))
+
+
+;;; Overlay and error stacks.
;;
(defvar semantic-overlay-error-recovery-stack nil
"List of overlays used during error recovery.")
@@ -539,8 +542,98 @@
(if (semantic-overlay-get overlay 'semantic)
(semantic-overlay-delete overlay)))
+;;; Interfacing with the system
+;;
+(defvar semantic-init-hooks nil
+ "*Hooks run when a buffer is initialized with a parsing table.")
+
+(defun semantic-active-p ()
+ "Return non-nil if the current buffer was set up for parsing."
+ (or semantic-toplevel-bovine-table
+ semantic-bovinate-toplevel-override))
+
+(defun semantic-new-buffer-fcn ()
+ "Setup Semantic in the current buffer.
+Runs `semantic-init-hook' if the major mode is setup to use Semantic."
+ (when (semantic-active-p)
+ (semantic-clear-toplevel-cache)
+ (setq semantic-toplevel-bovine-force-reparse t)
+ (run-hooks 'semantic-init-hooks)))
+
+(defvar semantic-changed-mode-buffers nil
+ "List of buffers whose `major-mode' has changed recently.")
+
+(defun semantic-post-change-major-mode-function ()
+ "`post-command-hook' run when there is a `major-mode' change.
+This makes sure semantic-init type stuff can occur."
+ (remove-hook 'post-command-hook
+ 'semantic-post-change-major-mode-function)
+ (let (buf)
+ (while semantic-changed-mode-buffers
+ (setq buf (car semantic-changed-mode-buffers)
+ semantic-changed-mode-buffers
+ (cdr semantic-changed-mode-buffers))
+ (and (buffer-live-p buf)
+ (buffer-file-name buf)
+ (with-current-buffer buf
+ (semantic-new-buffer-fcn))))))
+
+(defun semantic-change-major-mode-hook-function ()
+ "Function called in `change-major-mode-hook'."
+ (add-to-list 'semantic-changed-mode-buffers (current-buffer))
+ (add-hook 'post-command-hook 'semantic-post-change-major-mode-function))
+
+(add-hook 'find-file-hooks
+ 'semantic-post-change-major-mode-function)
+(add-hook 'change-major-mode-hook
+ 'semantic-change-major-mode-hook-function)
+
+;; Test the above hook.
+;;(add-hook 'semantic-init-hooks (lambda () (message "init for
semantic")))
+
+(defun semantic-rebovinate-quickly-hook ()
+ "For use in a hook. When only a partial reparse is needed, reparse."
+ (condition-case nil
+ (if (semantic-bovine-toplevel-partial-reparse-needed-p nil)
+ (semantic-bovinate-toplevel))
+ (error nil)))
+
+(if (boundp 'eval-defun-hooks)
+ (add-hook 'eval-defun-hooks 'semantic-rebovinate-quickly-hook))
+
+;;; Parsing Commands
+;;
+(eval-when-compile
+ (condition-case nil (require 'pp) (error nil)))
+
+(defun bovinate (&optional clear)
+ "Bovinate the current buffer. Show output in a temp buffer.
+Optional argument CLEAR will clear the cache before bovinating."
+ (interactive "P")
+ (if clear (semantic-clear-toplevel-cache))
+ (let ((out (semantic-bovinate-toplevel t)))
+ (pop-to-buffer "*BOVINATE*")
+ (require 'pp)
+ (erase-buffer)
+ (insert (pp-to-string out))
+ (goto-char (point-min))))
+
+(defun bovinate-debug ()
+ "Bovinate the current buffer and run in debug mode."
+ (interactive)
+ (let ((semantic-edebug t)
+ (out (semantic-bovinate-debug-buffer)))
+ (pop-to-buffer "*BOVINATE*")
+ (require 'pp)
+ (erase-buffer)
+ (insert (pp-to-string out))))
+
+;;; Parsing functions
+;;
(defun semantic-clear-toplevel-cache ()
- "Clear the toplevel bovin cache for the current buffer."
+ "Clear the toplevel bovin cache for the current buffer.
+Clearing the cache will force a complete reparse next time a token
+stream is requested."
(interactive)
(run-hooks 'semantic-before-toplevel-cache-flush-hook)
(setq semantic-toplevel-bovine-cache nil)
@@ -550,94 +643,241 @@
(mapcar 'semantic-delete-overlay-maybe (car l))
(mapcar 'semantic-delete-overlay-maybe (cdr l))
)
+ ;; Clear the dirty tokens... no longer relevant
+ (setq semantic-dirty-tokens nil)
+ (setq semantic-toplevel-bovine-force-reparse t)
;; Remove this hook which tracks if a buffer is up to date or not.
(remove-hook 'after-change-functions 'semantic-change-function t)
+ ;; Old model. Delete someday.
+ ;;(run-hooks 'semantic-after-toplevel-bovinate-hook)
+ (run-hook-with-args 'semantic-after-toplevel-cache-change-hook
+ semantic-toplevel-bovine-cache)
)
-(add-hook 'change-major-mode-hook 'semantic-clear-toplevel-cache)
+
+(defvar semantic-bovination-working-type 'percent
+ "*The type of working message to use when bovinating.
+'percent means we are doing a linear parse through the buffer.
+'dynamic means we are rebovinating specific tokens.")
+
+(defun semantic-bovine-toplevel-full-reparse-needed-p (&optional checkcache)
+ "Return non-nil if the current buffer needs a full reparse.
+Optional argument CHECKCACHE indicates if the cache check should be made."
+ (or semantic-toplevel-bovine-force-reparse
+ (and
+ checkcache
+ semantic-toplevel-bovine-cache-check)))
+
+(defun semantic-bovine-toplevel-partial-reparse-needed-p (&optional checkcache)
+ "Return non-nil if the current buffer needs a partial reparse.
+This only returns non-nil if `semantic-bovine-toplevel-full-reparse-needed-p'
+returns nil.
+Optional argument CHECKCACHE indicates if the cache check should be made
+when checking `semantic-bovine-toplevel-full-reparse-needed-p'."
+ (and semantic-toplevel-bovine-cache
+ semantic-dirty-tokens
+ (not (semantic-bovine-toplevel-full-reparse-needed-p checkcache))))
;;;###autoload
(defun semantic-bovinate-toplevel (&optional checkcache)
"Bovinate the entire current buffer.
-If the optional argument CHECKCACHE is non-nil, then flush the cache iff
-there has been a size change."
- (if (and semantic-toplevel-bovine-cache
- checkcache
- semantic-toplevel-bovine-cache-check)
- (semantic-clear-toplevel-cache))
- (prog1
- (cond
- (semantic-toplevel-bovinate-override
- (funcall semantic-toplevel-bovinate-override checkcache))
- ((and semantic-toplevel-bovine-cache
- (car semantic-toplevel-bovine-cache)
- ;; Add a rule that knows how to see if there have
- ;; been "big chagnes"
- )
- (car semantic-toplevel-bovine-cache))
- (t
- (let ((ss (semantic-flex (point-min) (point-max)))
- (res nil)
- (semantic-overlay-error-recovery-stack nil))
- ;; Init a dump
- (if semantic-dump-parse (semantic-dump-buffer-init))
- ;; Parse!
- (working-status-forms (buffer-name) "done"
- (setq res
- (semantic-bovinate-nonterminals
- ss 'bovine-toplevel semantic-flex-depth))
- (working-status t))
- (setq semantic-toplevel-bovine-cache
- (list (nreverse res) (point-max))
- semantic-toplevel-bovine-cache-check nil)
- (add-hook 'after-change-functions 'semantic-change-function nil t)
- (run-hooks 'semantic-after-toplevel-bovinate-hook)
- (car semantic-toplevel-bovine-cache))))
- ))
+If the optional argument CHECKCACHE is non-nil, then make sure the
+cached token list is up to date. If a partial reparse is possible, do
+that, otherwise, do a full reparse."
+ (cond
+ ((and semantic-bovinate-toplevel-override
+ ;; We cannot predict partial reparsing for these parsers. Let them
+ ;; fend for themselves. We can, however, handle the main cache for them.
+ (or (semantic-bovine-toplevel-partial-reparse-needed-p checkcache)
+ (semantic-bovine-toplevel-full-reparse-needed-p checkcache)))
+ (semantic-clear-toplevel-cache)
+ ;; Call a custom function
+ (let ((res (funcall semantic-bovinate-toplevel-override checkcache)))
+ (semantic-set-toplevel-bovine-cache res))
+ ;; Check: The below is not needed because of the -set- command above?
+ ;;(run-hooks 'semantic-after-toplevel-bovinate-hook)
+ semantic-toplevel-bovine-cache
+ )
+ ((semantic-bovine-toplevel-partial-reparse-needed-p checkcache)
+ ;; We have a cache, and some dirty tokens
+ (let ((semantic-bovination-working-type 'dynamic))
+ (working-status-forms (buffer-name) "done"
+ (while (and semantic-dirty-tokens
+ (not (semantic-bovine-toplevel-full-reparse-needed-p
+ checkcache)))
+ (semantic-rebovinate-token (car semantic-dirty-tokens))
+ (setq semantic-dirty-tokens (cdr semantic-dirty-tokens))
+ (working-dynamic-status))
+ (working-dynamic-status t))
+ (setq semantic-dirty-tokens nil)
+ )
+ (if (semantic-bovine-toplevel-full-reparse-needed-p checkcache)
+ ;; If the partial reparse fails, jump to a full reparse.
+ (semantic-bovinate-toplevel checkcache)
+ semantic-toplevel-bovine-cache)
+ )
+ ((semantic-bovine-toplevel-full-reparse-needed-p checkcache)
+ (semantic-clear-toplevel-cache)
+ ;; Reparse the whole system
+ (let ((ss (semantic-flex (point-min) (point-max)))
+ (res nil)
+ (semantic-overlay-error-recovery-stack nil))
+ ;; Init a dump
+ (if semantic-dump-parse (semantic-dump-buffer-init))
+ ;; Parse!
+ (working-status-forms (buffer-name) "done"
+ (setq res
+ (semantic-bovinate-nonterminals
+ ss 'bovine-toplevel semantic-flex-depth))
+ (working-status t))
+ (semantic-set-toplevel-bovine-cache (nreverse res))
+ semantic-toplevel-bovine-cache))
+ (t
+ ;; We have a cache with stuff in it, so return it
+ semantic-toplevel-bovine-cache
+ )))
+
+(defun semantic-set-toplevel-bovine-cache (tokenlist)
+ "Set the toplevel bovine cache to TOKENLIST."
+ (setq semantic-toplevel-bovine-cache tokenlist
+ semantic-toplevel-bovine-cache-check nil
+ semantic-toplevel-bovine-force-reparse nil
+ semantic-bovinate-nonterminal-check-obarray nil)
+ (add-hook 'after-change-functions 'semantic-change-function nil t)
+ (run-hook-with-args 'semantic-after-toplevel-cache-change-hook
+ semantic-toplevel-bovine-cache)
+ ;; Old Semantic 1.3 hook API. Maybe useful forever?
+ (run-hooks 'semantic-after-toplevel-bovinate-hook)
+ )
(defun semantic-change-function (start end length)
- "Run whenever a buffer controlled by `semantic-mode' change.
-Tracks when and how the buffer is re-parsed.
+ "Provide a mechanism for semantic token management.
Argument START, END, and LENGTH specify the bounds of the change."
- (when (not semantic-toplevel-bovine-cache-check)
- (let ((tl (condition-case nil
- (semantic-find-nonterminal-by-overlay-in-region
- (1- start) (1+ end))
- (error nil))))
- (if tl
- ;; Loop over the token list
- (while tl
- (cond
- ;; If we are completely enclosed in this overlay, throw away.
- ((and (> start (semantic-token-start (car tl)))
- (< end (semantic-token-end (car tl))))
- (if (and (eq (semantic-token-token (car tl)) 'type)
- (not (cdr tl))
- (semantic-token-type-parts (car tl)))
- (progn
- ;; This is between two items in a type with
- ;; stuff in it.
- (setq semantic-toplevel-bovine-cache-check t)
- (run-hooks 'semantic-reparse-needed-change-hook))
- ;; This is might be ok, chuck it.
- (if (run-hooks 'semantic-no-reparse-needed-change-hook)
- (progn
- ;; The hook says so, so flush it.
- (setq semantic-toplevel-bovine-cache-check t)
- (run-hooks 'semantic-reparse-needed-change-hook))
- nil)))
- ;; If we cover the beginning or end of this item, we must
- ;; reparse this object.
- (t
- (setq semantic-toplevel-bovine-cache-check t)
- (run-hooks 'semantic-reparse-needed-change-hook)))
- ;; next
- (setq tl (cdr tl)))
- ;; There was no hit, perhaps we need to reparse this intermediate area.
- (setq semantic-toplevel-bovine-cache-check t)
- )
- (if semantic-toplevel-bovine-cache-check
- (message "Reparse needed...")))))
+ (run-hook-with-args 'semantic-change-hooks start end length))
+
+;;; Force token lists in and out of overlay mode.
+;;
+(defun semantic-deoverlay-token (token)
+ "Convert TOKEN from using an overlay to using an overlay proxy."
+ (when (semantic-token-p token)
+ (let ((c (semantic-token-overlay-cdr token))
+ a)
+ (when (and c (semantic-overlay-p (car c)))
+ (setq a (vector (semantic-overlay-start (car c))
+ (semantic-overlay-end (car c))))
+ (semantic-overlay-delete (car c))
+ (setcar c a)
+ ;; Fix the children of this token.
+ ;; Semantic-util is required and the end of semantic, so this will
+ ;; throw a warning
+ (semantic-deoverlay-list (semantic-nonterminal-children token)))
+ )))
+
+(defun semantic-overlay-token (token)
+ "Convert TOKEN from using an overlay proxy to using an overlay."
+ (when (semantic-token-p token)
+ (let ((c (semantic-token-overlay-cdr token))
+ o)
+ (when (and c (vectorp (car c)) (= (length (car c)) 2))
+ (setq o (semantic-make-overlay (aref (car c) 0)
+ (aref (car c) 1)
+ (current-buffer)))
+ (setcar c o)
+ (semantic-overlay-put o 'semantic token)
+ ;; Fix overlays in children of this token
+ ;; Semantic-util is required and the end of semantic, so this will
+ ;; throw a warning
+ (semantic-overlay-list (semantic-nonterminal-children token))
+ ))))
+
+(defun semantic-deoverlay-list (l)
+ "Remove overlays from the list L."
+ (mapcar 'semantic-deoverlay-token l))
+
+(defun semantic-overlay-list (l)
+ "Convert numbers to overlays from the list L."
+ (mapcar 'semantic-overlay-token l))
+
+(defun semantic-deoverlay-cache ()
+ "Convert all tokens in the current cache to use overlay proxies."
+ (semantic-deoverlay-list (semantic-bovinate-toplevel)))
+(defun semantic-overlay-cache ()
+ "Convert all tokens in the current cache to use overlays."
+ (condition-case nil
+ ;; In this unique case, we cannot call the usual toplevel fn.
+ ;; because we don't want a reparse, we want the old overlays.
+ (semantic-overlay-list semantic-toplevel-bovine-cache)
+ ;; Recover when there is an error restoring the cache.
+ (error (message "Error recovering token list.")
+ (semantic-clear-toplevel-cache)
+ nil)))
+
+;;; Token parsing utilities
+;;
+(defun semantic-raw-to-cooked-token (token)
+ "Convert TOKEN from a raw state to a cooked state.
+The parser returns raw tokens with positional data START/END.
+We convert it from that to a cooked state with a property list and an overlay.
+Change the token with side effects and returns TOKEN."
+ (let* ((result nil)
+ (expandedtokens nil)
+ (ncdr (- (length token) 2))
+ (propcdr (if (natnump ncdr) (nthcdr ncdr token)))
+ (overcdr (cdr propcdr))
+ ;; propcdr is the CDR containing the START from the token.
+ ;; overcdr is the CDR containing the END from the token.
+ ;; PROPCDR will contain the property list after cooking.
+ ;; OVERCDR will contain the overlay after cooking.
+ (o (condition-case nil
+ (semantic-make-overlay (car propcdr)
+ (car overcdr)
+ (current-buffer)
+ ;; Examin start/rear
+ ;; advance flags.
+ )
+ (error (debug token)
+ nil))))
+ ;; Convert START/END into PROPERTIES/OVERLAY.
+ (setcar overcdr o)
+ (setcar propcdr nil)
+ (semantic-overlay-put o 'semantic token)
+ ;; Expand based on local configuration
+ (if (not semantic-expand-nonterminal)
+ ;; no expanders
+ (setq result (cons token result))
+ ;; Glom generated tokens
+ (setq expandedtokens (funcall semantic-expand-nonterminal token))
+ (if (not expandedtokens)
+ (progn (setq result (cons token result))
+ (semantic-overlay-stack-add o))
+ ;; Fixup all overlays, start by deleting the old one
+ (let ((tokenloop expandedtokens) o start end)
+ (while tokenloop
+ (setq propcdr (nthcdr (- (length (car tokenloop)) 2)
+ (car tokenloop))
+ overcdr (nthcdr (- (length (car tokenloop)) 1)
+ (car tokenloop))
+ ;; this will support new overlays created by
+ ;; the special function, or recycles
+ start (if (semantic-overlay-live-p (car overcdr))
+ (semantic-overlay-start (car overcdr))
+ start)
+ end (if (semantic-overlay-live-p (car overcdr))
+ (semantic-overlay-end (car overcdr))
+ end)
+ o (semantic-make-overlay start end
+ (current-buffer)))
+ (if (semantic-overlay-live-p (car overcdr))
+ (semantic-overlay-delete (semantic-token-overlay
+ (car tokenloop))))
+ (semantic-overlay-stack-add o)
+ (setcar propcdr nil)
+ (setcar overcdr o)
+ (semantic-overlay-put o 'semantic (car tokenloop))
+ (setq tokenloop (cdr tokenloop))))
+ (setq result (append expandedtokens result))))
+ result))
+
(defun semantic-bovinate-nonterminals (stream nonterm &optional
depth returnonerror)
"Bovinate the entire stream STREAM starting with NONTERM.
@@ -651,71 +891,129 @@
(semantic-bovinate-nonterminal
stream semantic-toplevel-bovine-table nonterm))
(stream-overlays (car (cdr (cdr nontermsym))))
- (tmpet nil)
- (token (car (cdr nontermsym)))
- (ncdr (- (length token) 2))
- (startcdr (if (natnump ncdr) (nthcdr ncdr token))))
+ (token (car (cdr nontermsym))))
(if (not nontermsym)
(error "Parse error @ %d" (car (cdr (car stream)))))
(semantic-overlay-stack-add stream-overlays)
(if token
- (let ((o (condition-case nil
- (semantic-make-overlay (car startcdr)
- (car (cdr startcdr))
- (current-buffer)
- ;; Examin start/rear
- ;; advance flags.
- )
- (error (debug token)
- nil))))
- ;; Convert START/END into an overlay.
- (setcdr startcdr nil)
- (setcar startcdr o)
- (semantic-overlay-put o 'semantic token)
- ;; Expand based on local configuration
- (if (not semantic-expand-nonterminal)
- ;; no expanders
- (setq result (cons token result))
- ;; Glom generated tokens
- (setq tmpet (funcall semantic-expand-nonterminal token))
- (if (not tmpet)
- (progn (setq result (cons token result))
- (semantic-overlay-stack-add o))
- ;; Fixup all overlays, start by deleting the old one
- (let ((motok tmpet) o start end)
- (while motok
- (setq startcdr (nthcdr (- (length (car motok)) 1)
- (car motok))
- ;; this will support new overlays created by
- ;; the special function, or recycles
- start (if (semantic-overlay-live-p (car startcdr))
- (semantic-overlay-start (car startcdr))
- start)
- end (if (semantic-overlay-live-p (car startcdr))
- (semantic-overlay-end (car startcdr))
- end)
- o (semantic-make-overlay start end
- (current-buffer)))
- (if (semantic-overlay-live-p (car startcdr))
- (semantic-overlay-delete (semantic-token-overlay
- (car motok))))
- (semantic-overlay-stack-add o)
- (setcdr startcdr nil)
- (setcar startcdr o)
- (semantic-overlay-put o 'semantic (car motok))
- (setq motok (cdr motok))))
- (setq result (append tmpet result)))))
+ (if (car token)
+ (progn
+ (setq result (append (semantic-raw-to-cooked-token token)
+ result))
+ ;; Place the nonterm into the token.
+ (if (not (eq nonterm 'bovine-toplevel))
+ (semantic-token-put token 'reparse-symbol nonterm)))
+ ;; No error in this case, a purposeful nil means don't store
+ ;; anything.
+ )
(if returnonerror (setq stream nil))
;;(error "Parse error")
)
;; Designated to ignore.
(setq stream (car nontermsym)))
(if stream
- (working-status (floor
- (* 100.0 (/ (float (car (cdr (car stream))))
- (float (point-max))))))))
+ (if (eq semantic-bovination-working-type 'percent)
+ (working-status (floor
+ (* 100.0 (/ (float (car (cdr (car stream))))
+ (float (point-max))))))
+ (working-dynamic-status))))
result))
+(defun semantic-remove-dirty-children-internal (token dirties)
+ "Remove TOKEN children from DIRTIES.
+Return the new value of DIRTIES."
+ (if dirties
+ (let ((children (semantic-nonterminal-children token t))
+ child)
+ (while (and children dirties)
+ (setq child (car children)
+ children (cdr children)
+ dirties (semantic-remove-dirty-children-internal
+ child (delq child dirties))))))
+ dirties)
+
+(defun semantic-remove-dirty-children (token)
+ "Remove TOKEN children from the list of dirty tokens.
+This must be done before deoverlaying TOKEN. At this point (when
+called by `semantic-rebovinate-token') TOKEN is the first element of
+`semantic-dirty-tokens' so only the rest of `semantic-dirty-tokens' is
+considered."
+ (setq semantic-dirty-tokens
+ (cons (car semantic-dirty-tokens)
+ (semantic-remove-dirty-children-internal
+ token (cdr semantic-dirty-tokens)))))
+
+(defun semantic-rebovinate-token (token)
+ "Use TOKEN for extents, and reparse it, splicing it back into the cache."
+ (let* ((flexbits (semantic-flex (semantic-token-start token)
+ (semantic-token-end token)))
+ ;; For embeded tokens (type parts, for example) we need a
+ ;; different symbol. Come up with a plan to solve this.
+ (nonterminal (or (semantic-token-get token 'reparse-symbol)
+ 'bovine-toplevel))
+ (new (condition-case nil
+ (semantic-bovinate-nonterminal
+ flexbits
+ semantic-toplevel-bovine-table
+ nonterminal)
+ ;; Trap `read' errors which may temporarily occurs
+ ;; when re-parsing a dirty Elisp token.
+ (end-of-file 'delay)
+ (invalid-read-syntax 'delay)))
+ (cooked nil)
+ )
+ (if (eq new 'delay)
+ ;; If a `read' error occured during re-parsing of an Elisp
+ ;; token just delay rebovination. Thus features like Semantic
+ ;; completion could continue to work until a clean syntax
+ ;; state is reached and re-parse succeeds.
+ nil
+ (setq new (car (cdr new)))
+ (if (not new)
+ ;; Clever reparse failed, queuing full reparse.
+ (setq semantic-toplevel-bovine-cache-check t)
+ (setq cooked (semantic-raw-to-cooked-token new))
+ (if (not (eq new (car cooked)))
+ (if (= (length cooked) 1)
+ ;; Cooking did a 1 to 1 replacement. Use it.
+ (setq new (car cooked))
+ ;; If cooking results in multiple things, do a full reparse.
+ (setq semantic-toplevel-bovine-cache-check t))))
+ ;; Don't do much if we have to do a full recheck.
+ (if semantic-toplevel-bovine-cache-check
+ nil
+ (let ((oo (semantic-token-overlay token))
+ (o (semantic-token-overlay new)))
+ ;; Copy all properties of the old overlay here.
+ ;; I think I can use plists in emacs, but not in XEmacs.
+ ;; Ack!
+ (semantic-overlay-put o 'face (semantic-overlay-get oo 'face))
+ (semantic-overlay-put o 'old-face (semantic-overlay-get oo
'old-face))
+ (semantic-overlay-put o 'intangible (semantic-overlay-get oo
'intangible))
+ (semantic-overlay-put o 'invisible (semantic-overlay-get oo
'invisible))
+ ;; Remove TOKEN children from `semantic-dirty-tokens'
+ (semantic-remove-dirty-children token)
+ ;; Free the old overlay(s)
+ (semantic-deoverlay-token token)
+ ;; Recover properties
+ (let ((p (semantic-token-properties token)))
+ (while p
+ (semantic-token-put new (car (car p)) (cdr (car p)))
+ (setq p (cdr p))))
+ (if (not (eq nonterminal 'bovine-toplevel))
+ (semantic-token-put new 'reparse-symbol nonterminal))
+ (semantic-token-put new 'dirty nil)
+ ;; Splice into the main list.
+ (setcdr token (cdr new))
+ (setcar token (car new))
+ ;; This important bit is because the CONS cell representing TOKEN
+ ;; is what we need here, even though the whole thing is the same.
+ (semantic-overlay-put o 'semantic token)
+ ;; Hooks
+ (run-hook-with-args 'semantic-clean-token-hooks token)
+ )
+ ))))
+
;;; Semantic Bovination
;;
@@ -723,159 +1021,254 @@
;; The bovinator takes a state table, and converts the token stream
;; into a new semantic stream defined by the bovination table.
;;
-(defun semantic-bovinate-nonterminal (stream table &optional nonterminal)
- "Bovinate STREAM based on the TABLE of nonterminal symbols.
-Optional argument NONTERMINAL is the nonterminal symbol to start with.
-Use `bovine-toplevel' if it is not provided."
- (if (not nonterminal) (setq nonterminal 'bovine-toplevel))
- (let ((ml (assq nonterminal table)))
- (semantic-bovinate-stream stream (cdr ml) table)))
-
(defsubst semantic-bovinate-symbol-nonterminal-p (sym table)
"Return non-nil if SYM is in TABLE, indicating it is NONTERMINAL."
;; sym is always a sym, so assq should be ok.
(if (assq sym table) t nil))
-(defun semantic-bovinate-stream (stream matchlist table)
- "Bovinate STREAM using MATCHLIST resolving nonterminals with TABLE.
+(defmacro semantic-bovinate-nonterminal-db-nt ()
+ "Return the current nonterminal symbol.
+Part of the BNF source debugger. Depends on the existing environment
+of `semantic-bovinate-nonterminal'."
+ `(if nt-stack
+ (car (aref (car nt-stack) 2))
+ nonterminal))
+
+(defun semantic-bovinate-nonterminal-check (stream nonterminal)
+ "Check if STREAM not already parsed for NONTERMINAL.
+If so abort because an infinite recursive parse is suspected."
+ (or (vectorp semantic-bovinate-nonterminal-check-obarray)
+ (setq semantic-bovinate-nonterminal-check-obarray
+ (make-vector 13 nil)))
+ (let* ((nt (symbol-name nonterminal))
+ (vs (symbol-value
+ (intern-soft
+ nt semantic-bovinate-nonterminal-check-obarray))))
+ (if (memq stream vs)
+ ;; Always enter debugger to see the backtrace
+ (let ((debug-on-signal t)
+ (debug-on-error t))
+ (setq semantic-bovinate-nonterminal-check-obarray nil)
+ (error "Infinite recursive parse suspected on %s" nt))
+ (set (intern nt semantic-bovinate-nonterminal-check-obarray)
+ (cons stream vs)))))
+
+(defun semantic-bovinate-nonterminal (stream table &optional nonterminal)
+ "Bovinate STREAM based on the TABLE of nonterminal symbols.
+Optional argument NONTERMINAL is the nonterminal symbol to start with.
+Use `bovine-toplevel' if it is not provided.
This is the core routine for converting a stream into a table.
-See the variable `semantic-toplevel-bovine-table' for details on the
-format of MATCHLIST.
Return the list (STREAM SEMANTIC-STREAM OVERLAYS) where STREAM are those
elements of STREAM that have not been used. SEMANTIC-STREAM is the
list of semantic tokens found. OVERLAYS is the list of overlays found
so far, to be used in the error recovery stack."
- (let ((s nil) ;Temp Stream Tracker
- (lse nil) ;Local Semantic Element
- (lte nil) ;Local matchlist element
- (tev nil) ;Matchlist entry values from buffer
- (val nil) ;Value found in buffer.
- (cvl nil) ;collected values list.
- (out nil) ;Output
- (ov nil) ;Overlay
- (s-stack nil) ;rollback stream stack
- (start nil) ;the beginning and end.
- (end nil)
- (db-mlen (length matchlist))
- (db-tlen 0)
- (semantic-overlay-error-recovery-stack nil) ;part of error recovery
- )
- ;; prime the rollback stack
- (setq s-stack (cons stream s-stack)
- start (car (cdr (car stream)))
- end (cdr (cdr (car stream))))
- (while matchlist
- (setq s (car s-stack) ;init s from the stack.
- cvl nil ;re-init the collected value list.
- lte (car matchlist) ;Get the local matchlist entry.
- db-tlen (length lte)) ;length of the local match.
- (if (or (byte-code-function-p (car lte))
- (listp (car lte)))
- ;; In this case, we have an EMPTY match! Make stuff up.
- (setq cvl (list nil)))
- (while (and lte (not (or (byte-code-function-p (car lte))
- (listp (car lte)))))
- ;; debugging!
- (if (and lte semantic-edebug)
- ;; The below reference to nonterminal is a hack and the byte
- ;; compiler will complain about it.
- (let ((r (semantic-bovinate-show (car s) nonterminal
- (- db-mlen (length matchlist))
- (- db-tlen (length lte))
- cvl)))
- (cond ((eq r 'fail)
- (setq lte '(trash 0 . 0)))
- (t nil))))
- (cond
- ;; We have a nonterminal symbol. Recurse inline.
- ((semantic-bovinate-symbol-nonterminal-p (car lte) table)
- (let ((nontermout (semantic-bovinate-nonterminal s table (car lte))))
- (setq s (car nontermout)
- val (car (cdr nontermout))
- ov (car (cdr (cdr nontermout))))
- (if ov (semantic-overlay-stack-add ov))
- (if val
- (let ((len (length val))
- (strip (nreverse (cdr (cdr (reverse val))))))
- (if semantic-dump-parse
- (semantic-dump-detail (cdr nontermout)
- (car lte)
- ""
- "NonTerm Match"))
- (setq end (nth (1- len) val) ;reset end to the end of exp
- cvl (cons strip cvl) ;prepend value of exp
- lte (cdr lte)) ;update the local table entry
- )
- ;; No value means that we need to terminate this match.
- (semantic-overlay-stack-clear)
- (setq lte nil cvl nil)) ;No match, exit
- ))
- ;; Default case
- (t
- (setq lse (car s) ;Get the local stream element
- s (cdr s)) ;update stream.
- ;; Do the compare
- (if (eq (car lte) (car lse)) ;syntactic match
- (let ((valdot (cdr lse)))
- (setq val (semantic-flex-text lse))
- ;; DEBUG SECTION
- (if semantic-dump-parse
- (semantic-dump-detail
- (if (stringp (car (cdr lte)))
- (list (car (cdr lte)) (car lte))
- (list (car lte)))
- nonterminal val
- (if (stringp (car (cdr lte)))
- (if (string-match (car (cdr lte)) val)
- "Term Match" "Term Fail")
- "Term Type=")))
- ;; END DEBUG SECTION
- (setq lte (cdr lte))
- (if (stringp (car lte))
- (progn
- (setq tev (car lte)
- lte (cdr lte))
- (if (string-match tev val)
- (setq cvl (cons val cvl)) ;append this value
- (semantic-overlay-stack-clear)
- (setq lte nil cvl nil))) ;clear the entry (exit)
- (setq cvl (cons
- (if (member (car lse)
- '(comment semantic-list))
- valdot val) cvl))) ;append unchecked value.
- (setq end (cdr (cdr lse)))
- )
- (if (and semantic-dump-parse nil)
- (semantic-dump-detail (car lte)
- nonterminal (semantic-flex-text lse)
- "Term Type Fail"))
- (semantic-overlay-stack-clear)
- (setq lte nil cvl nil)) ;No more matches, exit
- )))
- (if (not cvl) ;lte=nil; there was no match.
- (setq matchlist (cdr matchlist)) ;Move to next matchlist entry
- (setq out (if (car lte)
-; REMOVE THIS TO USE THE REFERENCE/COMPARE CODE
-; (let ((o (apply (car lte) ;call matchlist fn on values
-; (nreverse cvl) start (list end))))
-; (if semantic-bovinate-create-reference (semantic-bovinate-add-reference o))
-; (if semantic-bovinate-compare-reference (semantic-bovinate-compare-against-reference
o))
-; o
-; )
- (funcall (car lte) ;call matchlist fn on values
- (nreverse cvl) start end)
- (cond ((and (= (length cvl) 1)
- (listp (car cvl))
- (not (numberp (car (car cvl)))) )
- (append (car cvl) (list start end)))
- (t
- (append (nreverse cvl) (list start end))))
- )
- matchlist nil) ;generate exit condition
- (if (not end) (setq out nil))
- ;; Nothin?
- ))
- (list s out semantic-overlay-error-recovery-stack)))
+ (if (not nonterminal)
+ (setq nonterminal 'bovine-toplevel))
+
+ ;; Try to detect infinite recursive parse when doing a full reparse.
+ (or semantic-toplevel-bovine-cache
+ (semantic-bovinate-nonterminal-check stream nonterminal))
+
+ (let ((matchlist (cdr (assq nonterminal table)))
+ (starting-stream stream)
+ (nt-loop t) ;non-terminal loop condition
+ nt-popup ;non-nil if return from nt recursion
+ nt-stack ;non-terminal recursion stack
+ s ;Temp Stream Tracker
+ lse ;Local Semantic Element
+ lte ;Local matchlist element
+ tev ;Matchlist entry values from buffer
+ val ;Value found in buffer.
+ cvl ;collected values list.
+ out ;Output
+ end ;End of match
+ result
+ semantic-overlay-error-recovery-stack ;part of error recovery
+ )
+ (while nt-loop
+ (catch 'push-non-terminal
+ (setq semantic-overlay-error-recovery-stack nil
+ nt-popup nil
+ end (cdr (cdr (car stream))))
+ (while (or nt-loop nt-popup)
+ (setq nt-loop nil
+ out nil)
+ (while (or nt-popup matchlist)
+ (if nt-popup
+ ;; End of a non-terminal recursion
+ (setq nt-popup nil)
+ ;; New matching process
+ (setq s stream ;init s from stream.
+ cvl nil ;re-init the collected value list.
+ lte (car matchlist) ;Get the local matchlist entry.
+ )
+ (if (or (byte-code-function-p (car lte))
+ (listp (car lte)))
+ ;; In this case, we have an EMPTY match! Make stuff
+ ;; up.
+ (setq cvl (list nil))))
+
+ (while (and lte
+ (not (byte-code-function-p (car lte)))
+ (not (listp (car lte))))
+
+ ;; BNF SOURCE DEBUGGING!
+ (if semantic-edebug
+ (let* ((db-nt (semantic-bovinate-nonterminal-db-nt))
+ (db-ml (cdr (assq db-nt table)))
+ (db-mlen (length db-ml))
+ (db-midx (- db-mlen (length matchlist)))
+ (db-tlen (length (nth db-midx db-ml)))
+ (db-tidx (- db-tlen (length lte))))
+ (if (eq 'fail
+ (semantic-bovinate-show
+ (car s) db-nt db-midx db-tidx cvl))
+ (setq lte '(trash 0 . 0)))))
+ ;; END BNF SOURCE DEBUGGING!
+
+ (cond
+ ;; We have a nonterminal symbol. Recurse inline.
+ ((setq nt-loop (assq (car lte) table))
+
+ (setq
+ ;; push state into the nt-stack
+ nt-stack (cons (vector matchlist cvl lte stream end
+ ;; error recovery
+ semantic-overlay-error-recovery-stack
+ )
+ nt-stack)
+ ;; new non-terminal matchlist
+ matchlist (cdr nt-loop)
+ ;; new non-terminal stream
+ stream s)
+
+ (throw 'push-non-terminal t)
+
+ )
+ ;; Default case
+ (t
+ (setq lse (car s) ;Get the local stream element
+ s (cdr s)) ;update stream.
+ ;; Do the compare
+ (if (eq (car lte) (car lse)) ;syntactic match
+ (let ((valdot (cdr lse)))
+ (setq val (semantic-flex-text lse))
+ ;; DEBUG SECTION
+ (if semantic-dump-parse
+ (semantic-dump-detail
+ (if (stringp (car (cdr lte)))
+ (list (car (cdr lte)) (car lte))
+ (list (car lte)))
+ (semantic-bovinate-nonterminal-db-nt)
+ val
+ (if (stringp (car (cdr lte)))
+ (if (string-match (car (cdr lte)) val)
+ "Term Match" "Term Fail")
+ "Term Type=")))
+ ;; END DEBUG SECTION
+ (setq lte (cdr lte))
+ (if (stringp (car lte))
+ (progn
+ (setq tev (car lte)
+ lte (cdr lte))
+ (if (string-match tev val)
+ (setq cvl (cons
+ (if (memq (car lse)
+ '(comment semantic-list))
+ valdot val)
+ cvl)) ;append this value
+ (semantic-overlay-stack-clear)
+ (setq lte nil cvl nil))) ;clear the entry (exit)
+ (setq cvl (cons
+ (if (memq (car lse)
+ '(comment semantic-list))
+ valdot val) cvl))) ;append unchecked value.
+ (setq end (cdr (cdr lse)))
+ )
+ (if (and semantic-dump-parse nil)
+ (semantic-dump-detail (car lte)
+ (semantic-bovinate-nonterminal-db-nt)
+ (semantic-flex-text lse)
+ "Term Type Fail"))
+ (semantic-overlay-stack-clear)
+ (setq lte nil cvl nil)) ;No more matches, exit
+ )))
+ (if (not cvl) ;lte=nil; there was no match.
+ (setq matchlist (cdr matchlist)) ;Move to next matchlist entry
+ (let ((start (car (cdr (car stream)))))
+ (setq out (cond
+ ((car lte)
+
+ ;; REMOVE THIS TO USE THE REFERENCE/COMPARE CODE
+ ;;(let ((o (apply (car lte) ;call matchlist fn on values
+ ;; (nreverse cvl) start (list end))))
+ ;; (if semantic-bovinate-create-reference
+ ;; (semantic-bovinate-add-reference o))
+ ;; (if semantic-bovinate-compare-reference
+ ;; (semantic-bovinate-compare-against-reference o))
+ ;; o
+ ;; )
+
+ (funcall (car lte) ;call matchlist fn on values
+ (nreverse cvl) start end))
+ ((and (= (length cvl) 1)
+ (listp (car cvl))
+ (not (numberp (car (car cvl)))))
+ (append (car cvl) (list start end)))
+ (t
+ ;;(append (nreverse cvl) (list start end))))
+ ;; MAYBE THE FOLLOWING NEEDS LESS CONS
+ ;; CELLS THAN THE ABOVE?
+ (nreverse (cons end (cons start cvl)))))
+ matchlist nil) ;;generate exit condition
+ (if (not end)
+ (setq out nil)))
+ ;; Nothin?
+ ))
+ (setq result
+ (if (eq s starting-stream)
+ (list (cdr s) nil
+ semantic-overlay-error-recovery-stack)
+ (list s out
+ semantic-overlay-error-recovery-stack)))
+ (if nt-stack
+ ;; pop previous state from the nt-stack
+ (let ((state (car nt-stack))
+ (ov semantic-overlay-error-recovery-stack))
+
+ (setq nt-popup t
+ ;; pop actual parser state
+ matchlist (aref state 0)
+ cvl (aref state 1)
+ lte (aref state 2)
+ stream (aref state 3)
+ end (aref state 4)
+ ;; pop error recovery state
+ semantic-overlay-error-recovery-stack (aref state 5)
+ ;; update the stack
+ nt-stack (cdr nt-stack))
+
+ (if ov
+ (semantic-overlay-stack-add ov))
+
+ (if out
+ (let ((len (length out))
+ (strip (nreverse (cdr (cdr (reverse out))))))
+ (if semantic-dump-parse
+ (semantic-dump-detail (cdr result)
+ (car lte)
+ ""
+ "NonTerm Match"))
+ (setq end (nth (1- len) out) ;reset end to the end of exp
+ cvl (cons strip cvl) ;prepend value of exp
+ lte (cdr lte)) ;update the local table entry
+ )
+ ;; No value means that we need to terminate this
+ ;; match.
+ (semantic-overlay-stack-clear)
+ (setq lte nil cvl nil)) ;No match, exit
+ )))))
+ result))
;;; Bovine table functions
@@ -918,22 +1311,38 @@
nonterm
depth)))
-(defun semantic-bovinate-block-until-header (start end nonterm &optional depth)
+(defun semantic-bovinate-region-until-error (start end nonterm &optional depth)
"Bovinate between START and END starting with NONTERM.
-If NONTERM is nil, start with `bovine-block-toplevel'.
Optinal DEPTH specifies how many levels of parenthesis to enter.
This command will parse until an error is encountered, and return
the list of everything found until that moment.
This is meant for finding variable definitions at the beginning of
-code blocks in methods. If `bovine-block-toplevel' can also support
+code blocks in methods. If `bovine-inner-scope' can also support
commands, use `semantic-bovinate-from-nonterminal-full'."
(nreverse
- (semantic-bovinate-nonterminals (semantic-flex start end (or depth 1))
+ (semantic-bovinate-nonterminals (semantic-flex start end depth)
nonterm
depth
;; This says stop on an error.
t)))
+(defun semantic-bovinate-make-assoc-list (&rest args)
+ "Create an association list with ARGS.
+Args are of the form (KEY1 VALUE1 ... KEYN VALUEN).
+The return value will be of the form: ((KEY1 . VALUE1) ... (KEYN . VALUEN))
+Where KEY is a symbol, and VALUE is the value for that symbol.
+If VALUE is nil, then KEY is excluded from the return association list."
+ (let ((ret nil))
+ (while args
+ (let ((value (car-safe (cdr args))))
+ (if (and value
+ (or (not (stringp value))
+ (not (string= value "")))
+ (or (not (numberp value))
+ (not (= value 0))))
+ (setq ret (cons (cons (car args) (car (cdr args))) ret)))
+ (setq args (cdr (cdr args)))))
+ (nreverse ret)))
;;; Debugging in bovine tables
;;
@@ -971,18 +1380,27 @@
(beginning-of-defun)
(setq semantic-bovinate-debug-table (point-marker)))
+;; We will get warnings in here about semantic-bnf-* fns.
+;; We cannot require semantic-bnf due to compile eerrors.
(defun semantic-bovinate-debug-buffer ()
"Bovinate the current buffer in debug mode."
(interactive)
- (if (not semantic-bovinate-debug-table)
+ (if (and (not semantic-toplevel-bovine-table-source)
+ (not semantic-bovinate-debug-table))
(error
"Call `semantic-bovinate-debug-set-table' from your semantic
table"))
+ (delete-other-windows)
+ (split-window-vertically)
+ (if semantic-bovinate-debug-table
+ (switch-to-buffer (marker-buffer semantic-bovinate-debug-table))
+ (if (not semantic-toplevel-bovine-table-source)
+ (error "No debuggable BNF source found"))
+ (require 'semantic-bnf)
+ (switch-to-buffer (semantic-bnf-find-source-on-load-path
+ semantic-toplevel-bovine-table-source)))
+ (other-window 1)
+ (semantic-clear-toplevel-cache)
(let ((semantic-edebug t))
- (delete-other-windows)
- (split-window-vertically)
- (switch-to-buffer (marker-buffer semantic-bovinate-debug-table))
- (other-window 1)
- (semantic-clear-toplevel-cache)
(semantic-bovinate-toplevel)))
(defun semantic-bovinate-show (lse nonterminal matchlen tokenlen collection)
@@ -993,7 +1411,10 @@
MATCHLEN is the number of match lists tried.
TOKENLEN is the number of match tokens tried.
COLLECTION is the list of things collected so far."
- (let ((ol1 nil) (ol2 nil) (ret nil))
+ (let* ((semantic-edebug nil)
+ (ol1 nil) (ol2 nil) (ret nil)
+ (bnf-buffer (semantic-bnf-find-source-on-load-path
+ semantic-toplevel-bovine-table-source)))
(unwind-protect
(progn
(goto-char (car (cdr lse)))
@@ -1002,20 +1423,37 @@
(goto-char (car (cdr lse)))
(if window-system nil (sit-for 1))
(other-window 1)
- (set-buffer (marker-buffer semantic-bovinate-debug-table))
- (goto-char semantic-bovinate-debug-table)
- (re-search-forward
- (concat "^\\s-*\\((\\|['`]((\\)\\(" (symbol-name nonterminal)
- "\\)[ \t\n]+(")
- nil t)
- (setq ol2 (semantic-make-overlay (match-beginning 2) (match-end 2)))
- (semantic-overlay-put ol2 'face 'highlight)
- (forward-char -2)
- (forward-list matchlen)
- (skip-chars-forward " \t\n(")
- (forward-sexp tokenlen)
+ (let (s e)
+ (if semantic-bovinate-debug-table
+ (progn
+ (set-buffer (marker-buffer semantic-bovinate-debug-table))
+ (goto-char semantic-bovinate-debug-table)
+ (re-search-forward
+ (concat "^\\s-*\\((\\|['`]((\\)\\(" (symbol-name nonterminal)
+ "\\)[ \t\n]+(")
+ nil t)
+ (setq s (match-beginning 2)
+ e (match-end 2))
+ (forward-char -2)
+ (forward-list matchlen)
+ (skip-chars-forward " \t\n(")
+ (forward-sexp tokenlen)
+ )
+ ;; The user didn't specify a lisp level table.
+ ;; go to the source...
+ (set-buffer bnf-buffer)
+ (semantic-bnf-find-state-position
+ nonterminal matchlen tokenlen)
+ (save-excursion
+ (goto-char (semantic-token-start (semantic-current-nonterminal)))
+ (setq s (point)
+ e (progn (forward-sexp 1) (point))))
+ )
+ (setq ol2 (semantic-make-overlay s e))
+ (semantic-overlay-put ol2 'face 'highlight)
+ )
(message "%s: %S" lse collection)
- (let ((e (read-event)))
+ (let ((e (semantic-read-event)))
(cond ((eq e ?f) ;force a failure on this symbol.
(setq ret 'fail))
(t nil)))
@@ -1114,18 +1552,92 @@
))
+;;; Keyword Table Handling.
+;;
+(defvar semantic-flex-keywords-obarray nil
+ "Buffer local keyword obarray for the lexical analyzer.
+These keywords are matched explicitly, and converted into special symbols.")
+(make-variable-buffer-local 'semantic-flex-keywords-obarray)
+
+(defun semantic-flex-make-keyword-table (keywords &optional propertyalist)
+ "Convert a list of KEYWORDS into an obarray.
+Save the obarry into `semantic-flex-keywords-obarray'.
+If optional argument PROPERTYALIST is non nil, then interpret it, and
+apply those properties"
+ ;; Create the symbol hash table
+ (let ((obarray (make-vector 13 nil)))
+ ;; fill it with stuff
+ (while keywords
+ (set (intern (car (car keywords)) obarray)
+ (cdr (car keywords)))
+ (setq keywords (cdr keywords)))
+ ;; Apply all properties
+ (let ((semantic-flex-keywords-obarray obarray))
+ (while propertyalist
+ (semantic-flex-keyword-put (car (car propertyalist))
+ (nth 1 (car propertyalist))
+ (nth 2 (car propertyalist)))
+ (setq propertyalist (cdr propertyalist))))
+ obarray))
+
+(defun semantic-flex-keyword-p (text)
+ "Return a symbol if TEXT is a keyword in the keyword table.
+Return nil if TEXT is not in the symbol table."
+ (let ((sym (intern-soft text semantic-flex-keywords-obarray)))
+ (if sym (symbol-value sym))))
+
+(defun semantic-flex-keyword-put (text property value)
+ "For keyword TEXT, set PROPERTY to have VALUE."
+ (let ((sym (intern-soft text semantic-flex-keywords-obarray)))
+ (if (not sym) (signal 'wrong-type-argument (list text 'keyword)))
+ (put sym property value)))
+
+(defun semantic-flex-keyword-get (text property)
+ "For keyword TEXT, get the value of PROPERTY."
+ (let ((sym (intern-soft text semantic-flex-keywords-obarray)))
+ (if (not sym) (signal 'wrong-type-argument (list text 'keyword)))
+ (get sym property)))
+
+;; David Ponce
+(defun semantic-flex-map-keywords (fun &optional property)
+ "Call function FUN on every semantic keyword.
+If optional PROPERTY is non-nil call FUN only on every keyword which
+have a PROPERTY value. FUN receives a semantic keyword as argument."
+ (if (arrayp semantic-flex-keywords-obarray)
+ (mapatoms
+ (function
+ (lambda (keyword)
+ (and keyword
+ (or (null property) (get keyword property))
+ (funcall fun keyword))))
+ semantic-flex-keywords-obarray)))
+
+;; David Ponce
+(defun semantic-flex-keywords (&optional property)
+ "Return a list of semantic keywords.
+If optional PROPERTY is non-nil return only keyword which have a
+PROPERTY value."
+ (let (keywords)
+ (semantic-flex-map-keywords
+ (function
+ (lambda (keyword)
+ (setq keywords (cons keyword keywords))))
+ property)
+ keywords))
+
+;;; Lexical Analysis
+;;
(defvar semantic-flex-extensions nil
"Buffer local extensions to the lexical analyzer.
This should contain an alist with a key of a regex and a data element of
a function. The function should both move point, and return a lexical
-token of the form ( TYPE START . END). nil is also a valid return.")
+token of the form:
+ ( TYPE START . END)
+nil is also a valid return.
+TYPE can be any type of symbol, as long as it doesn't occur as a
+nonterminal in the language definition.")
(make-variable-buffer-local 'semantic-flex-extensions)
-(defvar semantic-flex-keywords-obarray nil
- "Buffer local keyword obarray for the lexical analyzer.
-These keywords are matched explicitly, and converted into special symbols.")
-(make-variable-buffer-local 'semantic-flex-keywords-obarray)
-
(defvar semantic-flex-syntax-modifications nil
"Updates to the syntax table for this buffer.
These changes are active only while this file is being flexed.
@@ -1142,23 +1654,6 @@
Only set this on a per mode basis, not globally.")
(make-variable-buffer-local 'semantic-flex-enable-newlines)
-(defun semantic-flex-make-keyword-table (keywords)
- "Convert a list of KEYWORDS into an obarray.
-Save the obarry into `semantic-flex-keywords-obarray'."
- ;; Create the symbol hash table
- (let ((obarray (make-vector 13 nil)))
- ;; fill it with stuff
- (while keywords
- (set (intern (car (car keywords)) obarray)
- (cdr (car keywords)))
- (setq keywords (cdr keywords)))
- obarray))
-
-(defun semantic-flex-is-keyword (text)
- "Return a symbol if TEXT is a keyword."
- (let ((sym (intern-soft text semantic-flex-keywords-obarray)))
- (if sym (symbol-value sym))))
-
(defun semantic-flex-buffer (&optional depth)
"Sematically flex the current buffer.
Optional argument DEPTH is the depth to scan into lists."
@@ -1200,9 +1695,10 @@
(while (and (< (point) end) (or (not length) (<= (length ts) length)))
(cond (;; catch newlines when needed
(and semantic-flex-enable-newlines
- (looking-at "\n"))
- (setq ts (cons (cons 'newline
- (cons (match-beginning 0) (match-end 0)))
+ (looking-at "\\s-*\\(\n\\)"))
+ (setq ep (match-end 1)
+ ts (cons (cons 'newline
+ (cons (match-beginning 1) ep))
ts)))
;; special extentions, sometimes includes some whitespace.
((and semantic-flex-extensions
@@ -1223,7 +1719,7 @@
((looking-at "\\(\\sw\\|\\s_\\)+")
(setq ts (cons (cons
;; Get info on if this is a keyword or not
- (or (semantic-flex-is-keyword (match-string 0))
+ (or (semantic-flex-keyword-p (match-string 0))
'symbol)
(cons (match-beginning 0) (match-end 0)))
ts)))
@@ -1248,7 +1744,7 @@
(forward-list 1)
;; This case makes flex robust
;; to broken lists.
- (error (goto-char (point-max))))
+ (error (goto-char end)))
(setq ep (point)))))
ts))))
;; Close parens
@@ -1270,8 +1766,21 @@
(if semantic-ignore-comments
;; If the language doesn't deal with comments,
;; ignore them here.
- (progn (forward-comment 1)
- (setq ep (point)))
+ (let ((comment-start-point (point)))
+ (forward-comment 1)
+ (if (eq (point) comment-start-point)
+ ;; In this case our start-skip string failed
+ ;; to work properly. Lets try and move over
+ ;; whatever white space we matched to begin
+ ;; with.
+ (skip-syntax-forward "-.'"
+ (save-excursion
+ (end-of-line)
+ (point)))
+ (forward-comment 1))
+ (if (eq (point) comment-start-point)
+ (error "Strange comment syntax prevents lexical analysis"))
+ (setq ep (point)))
;; Language wants comments, link them together.
(if (eq (car (car ts)) 'comment)
(setcdr (cdr (car ts)) (save-excursion
@@ -1314,13 +1823,15 @@
;;
(autoload 'semantic-create-imenu-index "semantic-imenu"
"Create an imenu index for any buffer which supports Semantic.")
-(autoload 'bovinate "semantic-util"
- "Bovinate the current buffer. Show output in a temp buffer.
-Optional argument CLEAR will clear the cache before bovinating." t)
-(autoload 'bovinate-debug "semantic-util"
- "Bovinate the current buffer and run in debug mode." t)
+(autoload 'senator-minor-mode "senator"
+ "Minor mode for the SEmantic NAvigaTOR." t)
+(autoload 'global-semanticdb-minor-mode "semanticdb"
+ "Mode saving token lists between sessions." t)
(provide 'semantic)
;;; semantic.el ends here
+;; Semantic-util is a part of the semantic API. Include it last
+;; because it depends on semantic.
+(require 'semantic-util)
Index: xemacs-packages/semantic/semantic.texi
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/semantic/semantic.texi,v
retrieving revision 1.5
diff -u -r1.5 semantic.texi
--- xemacs-packages/semantic/semantic.texi 2001/02/20 03:23:43 1.5
+++ xemacs-packages/semantic/semantic.texi 2001/08/15 05:28:25
@@ -1,9 +1,9 @@
\input texinfo @c -*-texinfo-*-
@c
-@c $Id: semantic.texi,v 1.5 2001/02/20 03:23:43 youngs Exp $
+@c $Id: semantic.texi,v 1.40 2001/06/11 18:38:41 zappo Exp $
@c
@setfilename semantic.info
-@settitle Semantic parsing for Emacs
+@settitle Semantic Bovinator: Parser generation for Emacs
@ifinfo
@format
@@ -17,7 +17,7 @@
@sp 10
@center @titlefont{Semantic}
@vskip 0pt plus 1 fill
-Copyright @copyright{} 1999, 2000 Eric M. Ludlam
+Copyright @copyright{} 1999, 2000, 2001 Eric M. Ludlam
@end titlepage
@node Top, Install, (dir), (dir)
@@ -32,25 +32,23 @@
rich as these tools, it uses the term ``bovine'' for cow, a lesser
cousin of the yak and bison.
-In it's current state, the bovinator is both fast (because it uses emacs
+In it's current state, the bovinator is both fast (because it uses Emacs
tricks) and slow (it is recursive, and not table (array) based). If you
have experience with compiler compilers (bison, yacc, etc) your help to
make these updates would be greatly appreciated.
-Because the bovinator is recursive, you may need to add the following to
-your .emacs file:
-@code{(setq max-specpdl-size 1000)}
-
@menu
-* Install:: Installing semantic.
+* Install:: Installing semantic.
* Lexing:: Setting up the lexer for your language.
* Bovinating:: Setting up the parser for your language.
* BNF conversion:: Using the BNF converter to make tables.
* Compiling:: Running the bovinator on a source file.
-* Debugging:: Using the bovine table debugger.
-* Non-Terminals:: How to use the nonterminal stream.
-* Utilities:: Utilities for querying the nonterminal stream.
+* Debugging:: Debugging bovine tables
+* Utilities:: How to use the nonterminal stream.
+* Current Context:: How to get the current code context.
+* Tools:: User Tools which use semantic.
+* Index::
@end menu
@node Install, Lexing, Top, Top
@@ -62,16 +60,13 @@
@file{site-lisp/site-start.el}.
@example
-(add-to-list 'load-path "/path/to/semantic")
-
-(require 'semantic-c)
-(require 'semantic-el)
-(require 'semantic-make)
-(add-hook 'speedbar-load-hook (lambda () (require 'semantic-sb)))
-(autoload 'semantic-bnf-mode "semantic-bnf" "Mode for Bovine Normal
Form." t)
-(add-to-list 'auto-mode-alist '("\\.bnf$" . semantic-bnf-mode))
+(setq semantic-load-turn-everything-on t)
+(load-file "/path/to/semantic/semantic-load.el")
@end example
+If you would like to turn individual tools on or off in your init
+file, skip the first line.
+
@node Lexing, Bovinating, Install, Top
@chapter Preparing your language for Lexing
@@ -79,25 +74,25 @@
converted into a token stream. Tokens are syntactic elements such as
whitespace, symbols, strings, lists, and punctuation.
-The lexer uses the major-mode's syntax table for conversion. As long as
-that is set up correctly (along with the important
-@code{comment-start-skip} variable) the lexer should already work for
-your language.
+The lexer uses the major-mode's syntax table for conversion. As long
+as that is set up correctly (along with the important
+@code{comment-start} and @code{comment-start-skip} variable) the lexer
+should already work for your language.
-There are three ways to extend the flexer.
+There are three ways to extend the lexer.
@defvar semantic-flex-extensions
-For a given language buffer, this is an associatoin list. The key is a
-regular expression used to match text in the buffer. The data element
-is a function which will be called when that text is encountered.
+Buffer local extensions to the lexical analyzer.
+This should contain an alist with a key of a regex and a data element of
+a function. The function should both move point, and return a lexical
+token of the form:
-The function should return a list of the form:
@example
-(TYPE START . END)
+( TYPE START . END)
@end example
-nil is also valid in case the text does not satisfy some other criterion.
-TYPE can be any type of symbol, as long as it doesn't occur as a
+@code{nil} is also a valid return.
+@var{TYPE} can be any type of symbol, as long as it doesn't occur as a
nonterminal in the language definition.
@end defvar
@@ -106,7 +101,7 @@
These changes are active only while this file is being flexed.
This is a list where each element is of the form:
@example
- (CHAR CLASS)
+(CHAR CLASS)
@end example
Where CHAR is the char passed to `modify-syntax-entry',
@@ -114,7 +109,7 @@
what class of syntax CHAR is.
@example
- (setq semantic-flex-syntax-modifications '((?. "_"))
+(setq semantic-flex-syntax-modifications '((?. "_"))
@end example
Will convert the period @asis{.} to be a symbol constituant. (ie, if
@@ -122,10 +117,54 @@
@end defvar
@defvar semantic-flex-enable-newlines
-When flexing, report 'newlines as syntactic elements.
+When flexing, report @code{'newlines} as syntactic elements.
Useful for languages where the newline is a special case terminator.
+Only set this on a per mode basis, not globally.
@end defvar
+@section Keywords
+
+Another important piece of the lexer is the keyword table. @ref{Settings}.
+You language will want to set up a keyword table for fast conversion of
+symbol strings to language terminals.
+
+The keywords table can also be used to store additional information
+about those keywords. The following programming functions can be useful
+when examining text in a language buffer.
+
+@defun semantic-flex-keyword-p text
+Return a symbol if @var{TEXT} is a keyword in the keyword table.
+@end defun
+
+@defun semantic-flex-keyword-put text property value
+For keyword @var{TEXT}, set @var{PROPERTY} to have @var{VALUE}.
+@end defun
+
+@defun semantic-flex-keyword-get text property
+For the keyword found as @var{text}, get the value of @var{property}.
+@end defun
+
+@defun semantic-flex-map-keywords fun &optional property
+Call function @var{FUN} on every semantic keyword.
+If optional @var{PROPERTY} is non-nil call @var{FUN} only on every
+keyword which have a @var{PROPERTY} value.
+@var{FUN} receives a semantic keyword as argument.
+@end defun
+
+@defun semantic-flex-keywords &optional property
+Return a list of semantic keywords.
+If optional @var{PROPERTY} is non-nil return only keyword which have a
+PROPERTY value.
+@end defun
+
+Keyword properties can be set up in a BNF file for ease of maintenance.
+While examining the text in a language buffer, this can provide an easy
+and quick way of storing details about text in the buffer.
+
+@section Standard Keyword Properties
+
+Add known properties here when they are known.
+
@node Bovinating, BNF conversion, Lexing, Top
@chapter Preparing a bovine table for your language
@@ -138,7 +177,7 @@
likely you will want to use the BNF converter. @xref{BNF conversion}.
This is an easier method for specifying your rules. You will still need
to specify a variable in your language for the table, however. A good
-rule of thumb is to call it @code{langauge-toplevel-bovine-table} if it
+rule of thumb is to call it @code{language-toplevel-bovine-table} if it
part of the language, or @code{semantic-toplevel-language-bovine-table}
if you donate it to the semantic package.
@@ -147,14 +186,13 @@
language table. @code{semantic-toplevel-bovine-table} is always buffer
local.
-Since it is important to know the format of the table when debugging
-@xref{Debugging}, you should still attempt to understand the basics of
-the table.
+Since it is important to know the format of the table when debugging ,
+you should still attempt to understand the basics of the table.
Please see the documentation for the variable
@code{semantic-toplevel-bovine-table} for details on it's format.
-* fix this *
+* add more doc here *
@node BNF conversion, Compiling, Bovinating, Top
@chapter Using the BNF converter to make bovine tables
@@ -162,11 +200,12 @@
The BNF converter takes a file in "Bovine Normal Form" which is similar
to "Backus-Naur Form". If you have ever used yacc or bison, you will
find it similar. The BNF form used by semantic, however, does not
-include token precedence rules.
+include token precedence rules, and several other features needed to make
+real parser generators.
It is important to have an Emacs Lisp file with a variable ready to take
the output of your table @xref{Bovinating}. Also, make sure that the
-file @file{semantic-bnf} is loaded. Give your language file the
+file @file{semantic-bnf.el} is loaded. Give your language file the
extension @file{.bnf} and you are ready.
The comment character is @asis{#}.
@@ -174,11 +213,12 @@
When you want to test your file, use the keyboard shortcut @kbd{C-c C-c}
to parse the file, generate the variable, and load the new definition
in. It will then use the settings specified above to determine what to
-do.
+do. Use the shortcut @kbd{C-c c} to do the same thing, but spend
+extra time indenting the table nicely.
Make sure that you create the variable specified in the
@code{%parsetable} token before trying to convert the bnf file. A
-simple definition like this should be sufficient.
+simple definition like this is sufficient.
@example
(defvar semantic-toplevel-lang-bovine-table
@@ -186,14 +226,26 @@
"Table for use with semantic for parsing LANG.")
@end example
+If you use tokens (created with the @code{%token} specifier), also
+make sure you have a keyword table available, like this:
+
+@example
+(defvar semantic-lang-keyword-table
+ nil
+ "Table for use with semantic for keywords.")
+@end example
+
+Specify the name of the keyword table with the @code{%keywordtable}
+specifier.
+
The BNF file has two sections. The first is the settings section, and
the second is the language definition, or list of semantic rules.
@menu
-* Settings::
-* Rules::
-* Optional Lambda Expression::
-* Examples::
+* Settings::
+* Rules::
+* Optional Lambda Expression::
+* Examples::
@end menu
@node Settings, Rules, BNF conversion, BNF conversion
@@ -207,8 +259,9 @@
@table @code
@item %start <nonterminal>
-Will let you specify an alternative to @code{bovine-toplevel}. (See
-below)
+Specify an alternative to @code{bovine-toplevel}. (See below)
+@item %scopestart <nonterminal>
+Specify an alternitive to @code{bovine-inner-scope}.
@item %outputfile <filename>
Required. Specifies the file into which this files output is stored.
@item %parsetable <lisp-variable-name>
@@ -227,7 +280,14 @@
lexical token of type @var{TYPE}. @var{TEXT} is a string which will be
matched explicitly. @var{NAME} can be used in match rules as though they were
flex tokens, but are converted back to @var{TYPE} "text" internally.
+@item %put <NAME> symbol <VALUE>
+@itemx %put <NAME> ( symbol1 <VALUE1> symbol2 <VALUE2> ... )
+@itemx %put ( <NAME1> <NAME2>...) symbol <VALUE>
+Tokens created without a type are considered keywords, and placed in a
+keyword table. Use @code{%put} to apply properties to that keyword.
+@ref{Lexing}.
@item %languagemode <lisp-function-name>
+@itemx %languagemode ( <lisp-function-name1> <lisp-function-name2> ... )
Optional. Specifies the Emacs major mode associated with the language
being specified. When the language is converted, all buffers of this
mode will get the new table installed.
@@ -247,7 +307,7 @@
probably want to set variables that tell Semantic and related tools how
the language works.
-Here are some variable that control how different programs will work
+Here are some variables that control how different programs will work
with your language.
@defvar semantic-flex-depth
@@ -259,28 +319,37 @@
Buffer local extensions to the lexical analyzer.
This should contain an alist with a key of a regex and a data element of
a function. The function should both move point, and return a lexical
-token of the form ( TYPE START . END). nil is also a valid return.
+token of the form:
+@example
+( TYPE START . END)
+@end example
+
+@code{nil} is also a valid return.
+@var{TYPE} can be any type of symbol, as long as it doesn't occur as a
+nonterminal in the language definition.
@end defvar
@defvar semantic-flex-syntax-modifications
Updates to the syntax table for this buffer.
These changes are active only while this file is being flexed.
This is a list where each element is of the form:
- (CHAR CLASS)
-Where CHAR is the char passed to `modify-syntax-entry',
-and CLASS is the string also passed to `modify-syntax-entry' to define
-what class of syntax CHAR is.
+@example
+(CHAR CLASS)
+@end example
+Where @var{CHAR} is the char passed to @dfn{modify-syntax-entry},
+and @var{CLASS} is the string also passed to @dfn{modify-syntax-entry} to define
+what class of syntax @var{CHAR} is.
@end defvar
@defvar semantic-flex-enable-newlines
-When flexing, report 'newlines as syntactic elements.
+When flexing, report @code{'newlines} as syntactic elements.
Useful for languages where the newline is a special case terminator.
Only set this on a per mode basis, not globally.
@end defvar
@defvar semantic-ignore-comments
Default comment handling.
-t means to strip comments when flexing. Nil means to keep comments
+@code{t} means to strip comments when flexing. @code{Nil} means to keep comments
as part of the token stream.
@end defvar
@@ -290,17 +359,40 @@
It is sometimes useful for a language to use a different string
in place of the default, even though that language will still
return a symbol. For example, Java return's includes, but the
-string can be replaced with `Imports'.
+string can be replaced with @code{Imports}.
@end defvar
@defvar semantic-case-fold
-Value for `case-fold-search' when parsing.
+Value for @code{case-fold-search} when parsing.
@end defvar
@defvar semantic-expand-nonterminal
-Function to call for each returned Non-terminal.
-Return a list of non-terminals derived from the first argument, or nil
+Function to call for each nonterminal production.
+Return a list of non-terminals derived from the first argument, or @code{nil}
if it does not need to be expanded.
+Languages with compound definitions should use this function to expand
+from one compound symbol into several. For example, in @var{C} the
+definition
+@example
+int a, b;
+@end example
+is easily parsed into one token, but represents multiple variables. A
+functions should be written which takes this compound token and turns
+it into two tokens, one for @var{A}, and the other for @var{B}.
+
+Within the language definition (the @file{.bnf} sources), it is often
+useful to set the NAME slot of a token with a list of items that
+distinguish each element in the compound definition.
+
+This list can then be detected by the function set in
+@code{semantic-expand-nonterminal} to create multiple tokens.
+This function has one additional duty of managing the overlays created
+by semantic. It is possible to use the single overlay in the compound
+token for all your tokens, but this can pose problems identifying
+all tokens covering a given definition.
+
+Please see @file{semantic-java.el} for an example of managing overlays
+when expanding a token into multiple definitions.
@end defvar
@defvar semantic-override-table
@@ -320,11 +412,32 @@
@item find-nonterminal @tab (token & parent) @tab Find token in buffer.
@item find-documentation @tab (token & nosnarf) @tab Find doc comments.
@item abbreviate-nonterminal @tab (token & parent) @tab Return summery string.
-@item summerize-nonterminal @tab (token & parent) @tab Return summery string.
+@item summarize-nonterminal @tab (token & parent) @tab Return summery string.
@item prototype-nonterminal @tab (token) @tab Return a prototype string.
@item prototype-file @tab (buffer) @tab Return a file in which
prototypes are placed
+@item nonterminal-children @tab (token) @tab Return first rate children.
These are children which may contain overlays.
+@item nonterminal-protection @tab (token & parent) @tab Return protection as a
symbol.
+@item beginning-of-context @tab (& point) @tab Move to the beginning of
the
+ current context.
+@item end-of-context @tab (& point) @tab Move to the end of the
+ current context.
+@item up-context @tab (& point) @tab Move up one context level.
+@item get-local-variables @tab (& point) @tab Get local variables.
+@item get-all-local-variables@tab (& point) @tab Get all local variables.
+@item get-local-arguments @tab (& point) @tab Get arguments to this
function.
+
+@item end-of-command @tab @tab Move to the end of the current
+ command
+@item beginning-of-command @tab @tab Move to the beginning of the
+ current command
+@item ctxt-current-symbol @tab (& point) @tab List of related symbols.
+@item ctxt-current-assignment@tab (& point) @tab Variable being assigned
to.
+@item ctxt-current-function @tab (& point) @tab Function being called at
point.
+@item ctxt-current-argument @tab (& point) @tab The index to the argument
of
+ the current function the
cursor
+ is in.
@end multitable
-
+
Parameters mean:
@table @code
@@ -341,6 +454,16 @@
@end defvar
+@defvar semantic-type-relation-separator-character
+Character strings used to separation a parent/child relationship.
+This list of strings are used for displaying or finding separators
+in variable field dereferencing. The first character will be used for
+display. In @var{C}, a type field is separated like this: ``type.field''
+thus, the character is a ``.''. In @var{C}, and additional value of
``->''
+would be in the list, so that ``type->field'' could be found.
+@end defvar
+
+
@defvar semantic-dependency-include-path
Defines the include path used when searching for files.
This should be a list of directories to search which is specific to
@@ -350,6 +473,8 @@
string, and it should return the full path to that file, or nil.
@end defvar
+This configures Imenu to use semantic parsing.
+
@defvar imenu-create-index-function
The function to use for creating a buffer index.
@@ -415,7 +540,7 @@
combination:
@example
- symbol "moose"
+symbol "moose"
@end example
means that a symbol must first be encountered, and then it must
@@ -423,7 +548,7 @@
string is a regular expression. The code:
@example
- punctuation "."
+punctuation "."
@end example
will match any punctuation.
@@ -443,8 +568,8 @@
;
@end example
-will match "moose" explicitly, unlike the previous example where moose
-need only appear in the symbol. This is because "moose" will be
+will match ``moose'' explicitly, unlike the previous example where moose
+need only appear in the symbol. This is because ``moose'' will be
converted to @var{MOOSE} in the lexical analysis stage. Thus the symbol
@var{MOOSE} won't be available any other way.
@@ -461,6 +586,17 @@
do so at the lexical level, allowing use of the text "moose" in other
forms of regular expressions.
+Non symbol tokens are also alowed. For example:
+
+@example
+%token PERIOD punctuation "."
+
+filename : symbol PERIOD symbol
+ ;
+@end example
+
+will explicitly match one period when used in the above rule.
+
@node Optional Lambda Expression, Examples, Rules, BNF conversion
@section Optional Lambda Expressions
@@ -469,7 +605,7 @@
reading the emacs bnf definition. An OLE like this:
@example
- ( $1 )
+( $1 )
@end example
results in a lambda return which consists entirely of the string
@@ -520,6 +656,14 @@
parser iterates over @code{bovine-toplevel}. This lets you have
much simpler rules in this specific case, and also lets you have
positional information in the returned tokens, and error skipping.
+@item (ASSOC symbol1 value1 symbol2 value2 ... )
+This is used for creating an association list. Each @var{SYMBOL} is
+included in the list if the associated @var{VALUE} is non-nil. While
+the items are all listed explicitly, the created structure is an
+association list of the form:
+@example
+( ( symbol1 . value1) (symbol2 . value2) ... )
+@end example
@end table
If the symbol @code{%quotemode backquote} is specified, then use
@@ -527,7 +671,7 @@
This lets you send @code{$1} as a symbol into a list instead of having
it expanded inline.
-@node Examples, , Optional Lambda Expression, BNF conversion
+@node Examples, , Optional Lambda Expression, BNF conversion
@section Examples
The rule:
@@ -594,155 +738,98 @@
additional optional argument of NONTERMINAL which is the nonterminal in
your table it is to start parsing with.
-@deffn Command bovinate
-As a user, you can use @code{bovinate} which runs the
-previously mentioned command, and displays the returned tokens in a
-buffer. This is a great tool for testing tables as you develop them.
+@deffn Command bovinate &optional clear
+Bovinate the current buffer. Show output in a temp buffer.
+Optional argument @var{CLEAR} will clear the cache before bovinating.
@end deffn
@deffn Command semantic-clear-toplevel-cache
-When a buffer is parsed, the results are cached in a local variable in
-the parsed buffer. This command will clear the cache so that the parser
-is called a second time.
+Clear the toplevel bovin cache for the current buffer.
+Clearing the cache will force a complete reparse next time a token
+stream is requested.
@end deffn
-@node Debugging, Non-Terminals, Compiling, Top
-@chapter Debugging a bovine table.
+@defun semantic-bovinate-toplevel &optional checkcache
+Bovinate the entire current buffer.
+If the optional argument @var{CHECKCACHE} is non-@code{nil}, then flush the cache iff
+there has been a size change.
+@end defun
-To debug a language is a two step process. The first tells emacs where
-to find the source code to the bovine table. The second is to run the
-debugger from a language file that uses the table.
+@node Debugging, Utilities, Compiling, Top
+@comment node-name, next, previous, up
+@chapter Debugging
-@deffn Command semantic-bovinate-debug-set-table
-Finds a variable definition under point. Sets this to be the table used
-when debugging a language definition.
-@end deffn
+Writing language files using BNF is significantly easier than writing
+then using regular expressions in a functional manner. Debugging
+them, however, can still prove challenging.
+
+There are two ways to debug a language definition if it is not
+behaving as expected. One way is to debug against the source @file{.bnf}
+file. The second is to debug against the lisp table created from the
+(a)file{.bnf} source, or perhaps written by hand.
-@deffn Command bovinate-debug
-Start parsing the current buffer in debug mode. Uses the definition set
-with @code{semantic-bovinate-debug-set-table}. Use space to move to the
-next definition. It will hightlight the current semantic token in the
-source buffer, and the current match symbol.
+If your language definition was written in BNF notation, debugging is
+quite easy. The command @code{bovinate-debug} will start you off.
-@key{C-g} halts the debugger.
+@deffn Command bovinate-debug
+Bovinate the current buffer and run in debug mode.
@end deffn
-@deffn Command bovinate-create-reference
-Create a reference parse table. A reference table can be used to
-identify differences between parsing runs.
-@end deffn
+If you prefer debugging against the Lisp table, find the table in a
+buffer, place the cursor in it, and use the command
+@code{semantic-bovinate-debug-set-table} in it.
-@deffn Command bovinate-reference-compare
-Bovinates the current buffer with a reference list.
-Throws an error for the first difference, with details as to what was
-broken.
+@deffn Command semantic-bovinate-debug-set-table
+Set the table for the next debug to be here.
@end deffn
-
-@node Non-Terminals, Utilities, Debugging, Top
-@chapter Using the Non-Termianal Stream
-The list of nontermianls returned from the parser is always language
-dependent, but should follow some simple conventions. A generic entry
-in the stream should be of the form
+After the table is set, the @code{bovinate-debug} command can be run
+at any time for the given language.
-@example
-("NAME" type-symbol ["TYPE"] ... "DOCSTRING" OVERLAY)
-@end example
-
-In this case, @var{NAME} is the identifier being declared.
-@var{type-symbol} is a symbol representing the type of identifier being
-declared. @var{TYPE} is a string containing the text of the type of
-this identifier, or nil if there is no typing information.
-@refill
-
-Additional information follows TYPE which is specific to the type of
-identifier being created. The last two entries are @var{docstring},
-some documentation associated with this class, and @var{overlay}, which
-describe the bounds of this definition. @var{overlay} is an overlay
-object in Emacs, and an extent in XEmacs.
-@refill
+While debugging, two windows are visible. One window shows the file
+being parse, and the syntactic token being tested is highlighted. The
+second window shows the table being used (either in the BNF source, or
+the Lisp table.) with the current rule highlighted. The cursor will
+sit on the specific match rule being tested against.
+
+In the minibuffer, a brief summary of the current situation is
+listed. The first element is the syntactic token which is a list of
+the form:
-Some predefined nonterminals that can be used are:
-
@example
-("NAME" variable "TYPE" CONST DEFAULT-VALUE MODIFIERS [OPTSUFFIX]
- "DOCSTRING" OVERLAY)
-@end example
-
-The definition of a variable, or constant. @var{CONST} is a boolean
-representing if this variable is considered a constant.
-@var{DEFAULT-VALUE} can be something apropriate such a a string, or list
-of parsed elements. @var{MODIFIERS} are details about a variable that
-are not covered in the @var{TYPE} field. @var{OPTSUFFIX} is an optional
-field specifying traling modifiers such as array dimentions or bit
-fields. @var{DOCSTRING} is optional.
-@refill
-
-@example
-("NAME" function "TYPE" ( ARG-LIST ) MODIFIERS [THROWS]
- "DOCSTRING" OVERLAY)
-@end example
-
-A function/procedure definition.
-@var{ARG-LIST} is a list of variable definitions.
-@var{THROWS} is an optional argument for functions or methods in languages
-that support typed signal throwing.
-@var{DOCSTRING} is optional.
-
-@example
-("NAME" type "TYPE" ( PART-LIST ) ( PARENTS ) MODIFIERS
"DOCSTRING" OVERLAY)
-@end example
-
-A type definition.
-@var{TYPE} of a type could be anything, such as (in C) struct, union, typedef,
-or class.
-@var{PART-LIST} is only useful for structs that have multiple individual parts.
- (It is recommended that these be variables, functions or types).
-@var{PARENTS} is strictly for classes where there is inheritance.
-
-@example
-("FILE" include SYSTEM "DOCSTRING" OVERLAY)
+(TYPE START . END)
@end example
-
-In C, an #include statement. In elisp, a require statement.
-Indicates additional locations of sources or definitions.
-@var{SYSTEM} is true if this include is part of a set of system includes.
-@example
-("NAME" package DETAIL "DOCSTRING" OVERLAY)
-@end example
+The rest of the display is a list of all strings collected for the
+currently tested rule. Each time a new rule is entered, the list is
+restarted. Upon returning from a rule into a previous match list, the
+previous match list is restored, with the production of the dependent
+rule in the list.
-In Emacs Lisp, a `provide' statement. @var{DETAIL} might be an associated
-file name.
-@refill
+Use @kbd{C-g} to stop debugging. There are no commands for any
+fancier types of debugging.
-@node Utilities, , Non-Terminals, Top
+@node Utilities, Current Context, Debugging, Top
+@comment node-name, next, previous, up
@chapter Utilities
-There are many utilities which can be used in programs that use the
-nonterminal stream generated by the bovinator. These utilities
-generally require that the current buffer belongs to the stream being
-analyzied.
+Once a source file has been parsed, the follwing APIs can be used to
+write programs that use the token stream most effectivly.
-Some of these utils will use EDE if it is available. EDE is a tool that
-tracks how program language files relate to eachother.
-
@menu
-* Nonterminal queryies:: Get info about one nonterminal token.
-* Nonterminal streams:: Get info from a stream of nonterminals.
-* Nonterminal completion:: Read nonterminal names in the minibuffer.
-* Override methods:: Methods that are more language specific.
+* Token Queries:: Getting info about a parsed token (nonterminal).
+* Nonterminal Streams:: Working with streams of nonterminals
+* Nonterminal Completion:: Completing read functions.
+* Override Methods:: Language dependent functions.
+* Parser Hooks:: How to know when tags change.
@end menu
-
-@node Nonterminal queryies, Nonterminal streams, Utilities, Utilities
-@section Nonterminal queryies
-These functions all take a single nonterminal (a list), and return some
-element from that list.
+@node Token Queries, Nonterminal Streams, Utilities, Utilities
+@comment node-name, next, previous, up
+@section Token Queries
-@defun semantic-token-p token
-Return non-@code{nil} if @var{TOKEN} is most likely a semantic token.
-@end defun
+When writing programs that use the bovinator, the following functions
+are needed to find get details out of a nonterminal.
@defun semantic-token-token token
Retrieve from @var{TOKEN} the token identifier.
@@ -760,8 +847,8 @@
@end defun
@defun semantic-token-overlay token
-Retrieve the overlay associated with @var{TOKEN}. The overlay is used
-to store the extent of TOKEN.
+Retrieve the @var{OVERLAY} part of @var{TOKEN}.
+The returned item may be an overlay or an unloaded buffer representation.
@end defun
@defun semantic-token-extent token
@@ -780,31 +867,83 @@
Retrieve the type of @var{TOKEN}.
@end defun
+@defun semantic-token-put token property value
+On @var{token}, set @var{property} to @var{value}.
+@end defun
+
+@defun semantic-token-get token property
+For @var{token} get the value of @var{property}.
+@end defun
+
+@defun semantic-token-extra-spec token spec
+Retrieve a specifier for the variable @var{TOKEN}.
+@var{SPC} is the symbol whose modifier value to get.
+This function can get specifiers from any type of @var{TOKEN}.
+Do not use this function if you know what type of token you are dereferencing.
+Instead, use the function specific to that token type. It will be faster.
+@end defun
+
@defun semantic-token-type-parts token
Retrieve the parts of the type @var{TOKEN}.
@end defun
@defun semantic-token-type-parent token
Retrieve the parent of the type @var{TOKEN}.
+The return value is a list. @var{A} value of @code{nil} means no parents.
+The @dfn{car} of the list is either the parent class, or a list
+of parent classes. The @dfn{cdr} of the list is the list of
+interfaces, or abstract classes which are parents of @var{TOKEN}.
+@end defun
+
+@defun semantic-token-type-parent-superclass token
+Retrieve the parent superclasses of type type @var{TOKEN}.
@end defun
+@defun semantic-token-type-parent-implement token
+Retrieve the parent interfaces of type type @var{TOKEN}.
+@end defun
+
@defun semantic-token-type-modifiers token
-Retrieve the non-type modifiers of type @var{TOKEN}.
+Retrieve the type modifiers for the type @var{TOKEN}.
+@end defun
+
+@defun semantic-token-type-extra-specs token
+Retrieve the extra specifiers for the type @var{TOKEN}.
@end defun
+@defun semantic-token-type-extra-spec token spec
+Retrieve a extra specifier for the type @var{TOKEN}.
+@var{SPEC} is the symbol whose modifier value to get.
+@end defun
+
@defun semantic-token-function-args token
Retrieve the arguments of the function @var{TOKEN}.
@end defun
@defun semantic-token-function-modifiers token
-Retrieve the non-type modifiers of the function @var{TOKEN}.
+Retrieve the type modifiers of the function @var{TOKEN}.
@end defun
+@defun semantic-token-function-extra-specs token
+Retrieve the extra specifiers of the function @var{TOKEN}.
+@end defun
+
+@defun semantic-token-function-extra-spec token spec
+Retrieve a specifier for the function @var{TOKEN}.
+@var{SPEC} is a symbol whose specifier value to get.
+@end defun
+
@defun semantic-token-function-throws token
-Retrieve the throws signale of the function @var{TOKEN}.
+Retrieve the throws signal of the function @var{TOKEN}.
This is an optional field, and returns @code{nil} if it doesn't exist.
@end defun
+@defun semantic-token-function-parent token
+The parent of the function @var{TOKEN}.
+A function has a parent if it is a method of a class, and if the
+function does not appear in body of it's parent class.
+@end defun
+
@defun semantic-token-variable-const token
Retrieve the status of constantness from the variable @var{TOKEN}.
@end defun
@@ -814,54 +953,45 @@
@end defun
@defun semantic-token-variable-modifiers token
-Retrieve extra non-type modifiers for the variable @var{TOKEN}.
+Retrieve type modifiers for the variable @var{TOKEN}.
+@end defun
+
+@defun semantic-token-variable-extra-specs token
+Retrieve extra specifiers for the variable @var{TOKEN}.
+@end defun
+
+@defun semantic-token-variable-extra-spec token spec
+Retrieve a specifier value for the variable @var{TOKEN}.
+@var{SPEC} is the symbol whose specifier value to get.
@end defun
@defun semantic-token-include-system token
Retrieve the flag indicating if the include @var{TOKEN} is a sysmtem include.
@end defun
+For override methods that query a token, see @xref{Token Details}.
-@node Nonterminal streams, Nonterminal completion, Nonterminal queryies, Utilities
+@node Nonterminal Streams, Nonterminal Completion, Token Queries, Utilities
@section Nonterminal streams
These functions take some key, and returns information found inside the
nonterminal stream returned by the bovinator. Some will return one
token (the first matching item found.) Others will return a list of all
items matching a given criterion.
-
-
-@defun semantic-find-nonterminal-by-name name streamorbuffer
-Find a nonterminal @var{NAME} within @var{STREAMORBUFFER}. @var{NAME} is a string.
-@end defun
-@defun semantic-find-nonterminal-by-position position streamorbuffer &optional
nomedian
-Find a nonterminal covinging @var{POSITION} within @var{STREAMORBUFFER}.
-@var{POSITION} is a number, or marker. If @var{NOMEDIAN} is non-@code{nil}, don't
do
-the median calculation, and return nil.
-@end defun
-
-@defun semantic-find-innermost-nonterminal-by-position position streamorbuffer
&optional nomedian
-Find a list of nonterminals covering @var{POSITION} within
-@var{STREAMORBUFFER}. @var{POSITION} is a number, or marker. If
-@var{NOMEDIAN} is non-@code{nil}, don't do the median calculation, and
-return nil. This function will find the topmost item, and recurse until
-no more details are available of findable.
-@end defun
+These functions query the current buffer's overlay system for tokens.
-@defun semantic-find-nonterminal-by-overlay positionormarker buffer
+@defun semantic-find-nonterminal-by-overlay &optional positionormarker buffer
Find all nonterminals covering @var{POSITIONORMARKER} by using overlays.
-If @var{POSITIONORMARKER} is nil, use the current point. Optional
-@var{BUFFER} is used if @var{POSITIONORMARKER} is a number, otherwise
-the current buffer is used. This finds all tokens covering the
-specified position by checking for all overlays covering the current
-spot. They are then sorted from largest to smallest via the start
-location.
+If @var{POSITIONORMARKER} is @code{nil}, use the current point.
+Optional @var{BUFFER} is used if @var{POSITIONORMARKER} is a number, otherwise the
current
+buffer is used. This finds all tokens covering the specified position
+by checking for all overlays covering the current spot. They are then sorted
+from largest to smallest via the start location.
@end defun
-@defun semantic-find-nonterminal-by-overlay-in-region start end buffer
-Find all nonterminals which exist in whole or in part between
-@var{START} and @var{END}.
+@defun semantic-find-nonterminal-by-overlay-in-region start end &optional buffer
+Find all nonterminals which exist in whole or in part between @var{START} and
@var{END}.
Uses overlays to determine positin.
Optional @var{BUFFER} argument specifies the buffer to use.
@end defun
@@ -872,30 +1002,95 @@
smallest token.
@end defun
-@defun semantic-find-nonterminal-by-token token streamorbuffer
+These functions search the entire stream for tokens matches a specific
+criteria.
+
+@defun semantic-find-nonterminal-by-name name streamorbuffer &optional search-parts
search-include
+Find a nonterminal @var{NAME} within @var{STREAMORBUFFER}. @var{NAME} is a string.
+If @var{SEARCH-PARTS} is non-@code{nil}, search children of tokens.
+If @var{SEARCH-INCLUDE} is non-@code{nil}, search include files.
+@end defun
+
+@defun semantic-find-nonterminal-by-property property value streamorbuffer &optional
search-parts search-includes
+Find all nonterminals with @var{PROPERTY} equal to @var{VALUE} in @var{STREAMORBUFFER}.
+Properties can be added with @dfn{semantic-token-put}.
+Optional argument @var{SEARCH-PARTS} and @var{SEARCH-INCLUDES} are passed to
+@dfn{semantic-find-nonterminal-by-function}.
+@end defun
+
+@defun semantic-find-nonterminal-by-extra-spec spec streamorbuffer &optional
search-parts search-includes
+Find all nonterminals with a given @var{SPEC} in @var{STREAMORBUFFER}.
+@var{SPEC} is a symbol key into the modifiers association list.
+Optional argument @var{SEARCH-PARTS} and @var{SEARCH-INCLUDES} are passed to
+@dfn{semantic-find-nonterminal-by-function}.
+@end defun
+
+@defun semantic-find-nonterminal-by-extra-spec-value spec value streamorbuffer
&optional search-parts search-includes
+Find all nonterminals with a given @var{SPEC} equal to @var{VALUE} in
@var{STREAMORBUFFER}.
+@var{SPEC} is a symbol key into the modifiers association list.
+@var{VALUE} is the value that @var{SPEC} should match.
+Optional argument @var{SEARCH-PARTS} and @var{SEARCH-INCLUDES} are passed to
+@dfn{semantic-find-nonterminal-by-function}.
+@end defun
+
+@defun semantic-find-nonterminal-by-position position streamorbuffer &optional
nomedian
+Find a nonterminal covering @var{POSITION} within @var{STREAMORBUFFER}.
+@var{POSITION} is a number, or marker. If @var{NOMEDIAN} is non-@code{nil}, don't
do
+the median calculation, and return nil.
+@end defun
+
+@defun semantic-find-innermost-nonterminal-by-position position streamorbuffer
&optional nomedian
+Find a list of nonterminals covering @var{POSITION} within @var{STREAMORBUFFER}.
+@var{POSITION} is a number, or marker. If @var{NOMEDIAN} is non-@code{nil}, don't
do
+the median calculation, and return nil.
+This function will find the topmost item, and recurse until no more
+details are available of findable.
+@end defun
+
+@defun semantic-find-nonterminal-by-token token streamorbuffer &optional search-parts
search-includes
Find all nonterminals with a token @var{TOKEN} within @var{STREAMORBUFFER}.
-@var{TOKEN} is a symbol.
+@var{TOKEN} is a symbol representing the type of the tokens to find.
+Optional argument @var{SEARCH-PARTS} and @var{SEARCH-INCLUDE} are passed to
+@dfn{semantic-find-nonterminal-by-function}.
@end defun
-@defun semantic-find-nonterminal-standard streamorbuffer
+@defun semantic-find-nonterminal-standard streamorbuffer &optional search-parts
search-includes
Find all nonterminals in @var{STREAMORBUFFER} which define simple token types.
+Optional argument @var{SEARCH-PARTS} and @var{SEARCH-INCLUDE} are passed to
+@dfn{semantic-find-nonterminal-by-function}.
@end defun
-@defun semantic-find-nonterminal-by-type type streamorbuffer
+@defun semantic-find-nonterminal-by-type type streamorbuffer &optional search-parts
search-includes
Find all nonterminals with type @var{TYPE} within @var{STREAMORBUFFER}.
-@var{TYPE} is a string.
+@var{TYPE} is a string which is the name of the type of the token returned.
+Optional argument @var{SEARCH-PARTS} and @var{SEARCH-INCLUDES} are passed to
+@dfn{semantic-find-nonterminal-by-function}.
@end defun
-@defun semantic-find-nonterminal-by-function function streamorbuffer
-Find all nonterminals which @var{FUNCTION} match within @var{STREAMORBUFFER}.
+@defun semantic-find-nonterminal-by-function function streamorbuffer &optional
search-parts search-includes
+Find all nonterminals in which @var{FUNCTION} match within @var{STREAMORBUFFER}.
@var{FUNCTION} must return non-@code{nil} if an element of @var{STREAM} will be
included
in the new list.
+
+If optional argument @var{SEARCH-PARTS} is non-@code{nil}, all sub-parts of tokens
+are searched. The overloadable function @dfn{semantic-nonterminal-children} is
+used for the searching child lists. If @var{SEARCH-PARTS} is the symbol
+@code{'positiononly}, then only children that have positional information are
+searched.
+
+If @var{SEARCH-INCLUDES} is non-@code{nil}, then all include files are also
+searched for matches.
@end defun
-@defun semantic-find-nonterminal-by-function-first-match function streamorbuffer
+@defun semantic-find-nonterminal-by-function-first-match function streamorbuffer
&optional search-parts search-includes
Find the first nonterminal which @var{FUNCTION} match within @var{STREAMORBUFFER}.
@var{FUNCTION} must return non-@code{nil} if an element of @var{STREAM} will be
included
in the new list.
+If optional argument @var{SEARCH-PARTS}, all sub-parts of tokens are searched.
+The overloadable function @dfn{semantic-nonterminal-children} is used for
+searching.
+If @var{SEARCH-INCLUDES} is non-@code{nil}, then all include files are also
+searched for matches.
@end defun
@defun semantic-recursive-find-nonterminal-by-name name buffer
@@ -906,7 +1101,7 @@
@end defun
-@node Nonterminal completion, Override methods, Nonterminal streams, Utilities
+@node Nonterminal Completion, Override Methods, Nonterminal Streams, Utilities
@section Nonterminal completion
These functions provide ways reading the names of items in a buffer with
@@ -952,8 +1147,8 @@
@end defun
-@node Override methods, , Nonterminal completion, Utilities
-@section Override methods
+@node Override Methods, Parser Hooks, Nonterminal Completion, Utilities
+@section Override Methods
These functions are called `override methods' because they provide
generic behaviors, which a given language can override. For example,
@@ -962,7 +1157,141 @@
a dependency can be found by searching a generic search path which can
be passed in via a variable.
+@menu
+* Token->Text:: Converting Tokens into text strings
+* Token Details:: Arbitrary token detail fetching
+* Local Context:: Deriving information about a language specific local
+ context.
+* Making New Methods:: How to add your own methods for a tool
+@end menu
+
+@node Token->Text, Token Details, Override Methods, Override Methods
+@subsection Token->Text
+
+Any given token consists of Meta information which is best viewed in
+some textual form. This could be as simple as the token's name, or as
+a prototype to be added to header file in C. Not only are there
+several default converters from a Token into text, but there is also
+some convenient variables that can be used with them. Use these
+variables to allow options on output forms when displaying tokens in
+your programs.
+
+@defvar semantic-token->text-functions
+List of functions which convert a token to text.
+Each function must take the parameters @var{TOKEN} &optional @var{PARENT}
@var{COLOR}.
+@var{TOKEN} is the token to convert.
+@var{PARENT} is a parent token or name which refers to the structure
+or class which contains @var{TOKEN}. @var{PARENT} is @var{NOT} a class which a
@var{TOKEN}
+would claim as a parent.
+@var{COLOR} indicates that the generated text should be colored using
+@code{font-lock}.
+@end defvar
+
+@defvar semantic-token->text-custom-list
+@var{A} List used by customizeable variables to choose a token to text function.
+Use this variable in the @code{:type} field of a customizable variable.
+@end defvar
+
+Every token to text conversion function must take the same parameters,
+which are @var{TOKEN}, the token to be converted, @var{PARENT}, the
+containing parent (like a structure which contains a variable), and
+@var{COLOR}, which is a flag specifying that color should be applied
+to the returned string.
+
+When creating, or using these strings, particularly with color, use
+@dfn{concat} to build up larger strings instead of @dfn{format}. This
+will preserve text properties.
+
+@defun semantic-name-nonterminal token &optional parent color
+Return the name string describing @var{TOKEN}.
+The name is the shortest possible representation.
+Optional argument @var{PARENT} is the parent type if @var{TOKEN} is a detail.
+Optional argument @var{COLOR} means highlight the prototype with font-lock colors.
+@end defun
+@defun semantic-summarize-nonterminal token &optional parent color
+Summarize @var{TOKEN} in a reasonable way.
+Optional argument @var{PARENT} is the parent type if @var{TOKEN} is a detail.
+Optional argument @var{COLOR} means highlight the prototype with font-lock colors.
+@end defun
+
+@defun semantic-prototype-nonterminal token &optional parent color
+Return a prototype for @var{TOKEN}.
+This function should be overloaded, though it need not be used.
+This is because it can be used to create code by language independent
+tools.
+Optional argument @var{PARENT} is the parent type if @var{TOKEN} is a detail.
+Optional argument @var{COLOR} means highlight the prototype with font-lock colors.
+@end defun
+
+@defun semantic-prototype-file buffer
+Return a file in which prototypes belonging to @var{BUFFER} should be placed.
+Default behavior (if not overriden) looks for a token specifying the
+prototype file, or the existence of an @var{EDE} variable indicating which
+file prototypes belong in.
+@end defun
+
+@defun semantic-abbreviate-nonterminal token &optional parent color
+Return an abbreviated string describing @var{TOKEN}.
+The abbreviation is to be short, with possible symbols indicating
+the type of token, or other information.
+Optional argument @var{PARENT} is the parent type if @var{TOKEN} is a detail.
+Optional argument @var{COLOR} means highlight the prototype with font-lock colors.
+@end defun
+
+@defun semantic-concise-prototype-nonterminal token &optional parent color
+Return a concise prototype for @var{TOKEN}.
+Optional argument @var{PARENT} is the parent type if @var{TOKEN} is a detail.
+Optional argument @var{COLOR} means highlight the prototype with font-lock colors.
+@end defun
+
+@defun semantic-uml-abbreviate-nonterminal token &optional parent color
+Return a @var{UML} style abbreviation for @var{TOKEN}.
+Optional argument @var{PARENT} is the parent type if @var{TOKEN} is a detail.
+Optional argument @var{COLOR} means highlight the prototype with font-lock colors.
+@end defun
+
+@node Token Details, Local Context, Token->Text, Override Methods
+@subsection Token Details
+
+These functions help derive information about tokens that may not
+be obvious for non-traditional languages with their own token types.
+
+@defun semantic-nonterminal-children token &optional positionalonly
+Return the list of top level children belonging to @var{TOKEN}.
+Children are any sub-tokens which may contain overlays.
+The default behavior (if not overriden with @code{nonterminal-children}
+is to return type parts for a type, and arguments for a function.
+
+If optional argument @var{POSITIONALONLY} is non-@code{nil}, then only return valid
+children if they contain positions. Some languages may choose to create
+lists of children without position/overlay information.
+
+If this function is overriden, use @dfn{semantic-nonterminal-children-default}
+to also include the default behavior, and merely extend your own.
+
+Note for language authors:
+ If a mode defines a language that has tokens in it with overlays that
+should not be considered children, you should still return them with
+this function. If you do not, then token reparsing, and database
+saving will fail.
+@end defun
+
+@defun semantic-nonterminal-protection token &optional parent
+Return protection information about @var{TOKEN} with optional @var{PARENT}.
+This function returns on of the following symbols:
+ @code{nil} - No special protection. Language dependent.
+ @code{'public} - Anyone can access this @var{TOKEN}.
+ @code{'private} - Only methods in the local scope can access @var{TOKEN}.
+ @code{'friend} - Like private, except some outer scopes are allowed
+ access to token.
+Some languages may choose to provide additional return symbols specific
+to themselves. Use of this function should allow for this.
+
+The default behavior (if not overriden with @code{nonterminal-children}
+is to return a symbol based on type modifiers.
+@end defun
+
@defun semantic-find-dependency token
Find the filename represented from @var{TOKEN}.
@var{TOKEN} may be a stripped element, in which case @var{PARENT} specifies a
@@ -996,28 +1325,843 @@
@defun semantic-find-documentation token
Find documentation from @var{TOKEN} and return it as a clean string.
@var{TOKEN} might have @var{DOCUMENTATION} set in it already. If not, there may be
-some documentation in a comment preceeding TOKEN's definition which we
+some documentation in a comment preceding TOKEN's definition which we
cal look for. When appropriate, this can be overridden by a language specific
enhancement.
@end defun
-@defun semantic-summerize-nonterminal token &optional parent
-Summerize @var{TOKEN} in a reasonable way.
-Optional argument @var{PARENT} is the parent type if @var{TOKEN} is a detail.
+@node Local Context, Making New Methods, Token Details, Override Methods
+@subsection Local Context
+
+@defun semantic-up-context &optional point
+Move point up one context from @var{POINT}.
+Return non-@code{nil} if there are no more context levels.
+Overloaded functions using @code{up-context} take no parameters.
@end defun
-@defun semantic-prototype-nonterminal token
-Return a prototype for @var{TOKEN}.
-This functin must be overloaded, though it need not be used.
+@defun semantic-beginning-of-context &optional point
+Move @var{POINT} to the beginning of the current context.
+Return non-@code{nil} if there is no upper context.
+The default behavior uses @dfn{semantic-up-context}. It can
+be overridden with @code{beginning-of-context}.
@end defun
-@defun semantic-prototype-file buffer
-Return a file in which prototypes belonging to @var{BUFFER} should be placed.
-Default behavior (if not overriden) looks for a token specifying the
-prototype file, or the existence of an @var{EDE} variable indicating which
-file prototypes belong in.
+@defun semantic-end-of-context &optional point
+Move @var{POINT} to the end of the current context.
+Return non-@code{nil} if there is no upper context.
+Be default, this uses @dfn{semantic-up-context}, and assumes parenthetical
+block delimiters. This can be overridden with @code{end-of-context}.
+@end defun
+
+@defun semantic-get-local-variables &optional point
+Get the local variables based on POINT's context.
+Local variables are returned in Semantic token format.
+Be default, this calculates the current bounds using context blocks
+navigation, then uses the parser with @code{bovine-inner-scope} to
+parse tokens at the beginning of the context.
+This can be overriden with @code{get-local-variables}.
+@end defun
+
+@defun semantic-get-local-arguments &optional point
+Get arguments (variables) from the current context at @var{POINT}.
+Parameters are available if the point is in a function or method.
+This function returns a list of tokens. If the local token returns
+just a list of strings, then this function will convert them to tokens.
+Part of this behavior can be overridden with @code{get-local-arguments}.
@end defun
+@defun semantic-get-all-local-variables &optional point
+Get all local variables for this context, and parent contexts.
+Local variables are returned in Semantic token format.
+Be default, this gets local variables, and local arguments.
+This can be overridden with @code{get-all-local-variables}.
+Optional argument @var{POINT} is the location to start getting the variables from.
+@end defun
+
+These next set of functions handle local context parsing. This means
+looking at the code (locally) and navigating, and fetching information
+such as a the type of the parameter the cursor may be typing in.
+
+@defun semantic-end-of-command
+Move to the end of the current command.
+Be default, uses @code{semantic-command-separation-character}.
+Override with @code{end-of-command}.
+@end defun
+
+@defun semantic-beginning-of-command
+Move to the beginning of the current command.
+Be default, users @code{semantic-command-separation-character}.
+Override with @code{beginning-of-command}.
+@end defun
+
+@defun semantic-ctxt-current-symbol &optional point
+Return the current symbol the cursor is on at @var{POINT} in a list.
+This will include a list of type/field names when applicable.
+This can be overridden using @code{ctxt-current-symbol}.
+@end defun
+
+@defun semantic-ctxt-current-assignment &optional point
+Return the current assignment near the cursor at @var{POINT}.
+Return a list as per @dfn{semantic-ctxt-current-symbol}.
+Return @code{nil} if there is nothing relevant.
+Override with @code{ctxt-current-assignment}.
+@end defun
+
+@defun semantic-ctxt-current-function &optional point
+Return the current function the cursor is in at @var{POINT}.
+The function returned is the one accepting the arguments that
+the cursor is currently in.
+This can be overridden with @code{ctxt-current-function}.
+@end defun
+
+@defun semantic-ctxt-current-argument &optional point
+Return the current symbol the cursor is on at @var{POINT}.
+Override with @code{ctxt-current-argument}.
+@end defun
+
+Local Context analysis functions can look at the local context,
+and return informatin such as the type of the data that should be
+entered where the cursor is. As of this writing, these functions
+need some more work.
+
+@defun semantic-suggest-lookup-item name &optional tokentype returntype
+Find a token definition matching @var{NAME} with @var{TOKENTYPE}.
+Optional @var{RETURNTYPE} is a return value to match against also.
+@end defun
+
+@defun semantic-suggest-variable-token-hierarchy
+Analyze the current line, and return a series of tokens.
+The tokens represent a hierarchy of dereferences. For example, a
+variable name will return a list with one token representing that
+variable's declaration. If that variable is being dereferenced, then
+return a list starting with the variable declaration, followed by all
+fields being extracted.
+
+For example, in c, ``foo->bar'' would return a list (@var{VARTOKEN}
@var{FIELDTOKEN})
+where @var{VARTOKEN} is a semantic token of the variable foo's declaration.
+@var{FIELDTOKEN} is either a string, or a semantic token representing
+the field in foo's type.
+@end defun
+
+
+@node Making New Methods, , Local Context, Override Methods
+@subsection Local Context
+
+@node Parser Hooks, , Override Methods, Utilities
+@section Parser Hooks
+
+If you write a program that uses the stream of tokens in a persistent
+display or database, it is necessary to know when tokens change so
+that your displays can be updated. This is especially important as
+tokens can be replaced, changed, or deleted, and the associated
+overlays will then throw errors when you try to use them. Complete
+integration with token changes can be achieved via several very
+important hooks.
+
+One interesting way to interact with the parser is to let it know that
+changes you are going to make will not require reparsing.
+
+@defvar semantic-edits-are-safe
+When non-@code{nil}, modifications do not require a reparse.
+This prevents tokens from being marked dirty, and it
+prevents top level edits from causing a cache check.
+Use this when writing programs that could cause a full
+reparse, but will not change the tag structure, such
+as adding or updating top-level comments.
+@end defvar
+
+Next, it is sometimes useful to know what the current parsing state
+is. These function can let you know what level of reparsing may be
+needed. Careful choices on when to reparse can make your program much
+faster.
+
+@defun semantic-bovine-toplevel-full-reparse-needed-p &optional checkcache
+Return non-@code{nil} if the current buffer needs a full reparse.
+Optional argument @var{CHECKCACHE} indicates if the cache check should be made.
+@end defun
+
+@defun semantic-bovine-toplevel-partial-reparse-needed-p &optional checkcache
+Return non-@code{nil} if the current buffer needs a partial reparse.
+This only returns non-@code{nil} if
@dfn{semantic-bovine-toplevel-full-reparse-needed-p}
+returns nil.
+Optional argument @var{CHECKCACHE} indicates if the cache check should be made
+when checking @dfn{semantic-bovine-toplevel-full-reparse-needed-p}.
+@end defun
+
+If you need very close interaction with the user's editing, then these
+two hooks can be used to find out when a given tag is being changed.
+These hooks could even be used to cut down on reparsing if used correctly.
+
+For all hooks, make sure you are careful to add it as a local hook if
+you only want to effect a single buffer. Setting it globally can
+cause unwanted effects if your program is concerned with a single buffer.
+
+@defvar semantic-dirty-token-hooks
+Hooks run after when a token is marked as dirty (edited by the user).
+The functions must take @var{TOKEN}, @var{START}, and @var{END} as a parameters.
+This hook will only be called once when a token is first made dirty,
+subsequent edits will not cause this to run a second time unless that
+token is first cleaned. Any token marked as dirty will
+also be called with @code{semantic-clean-token-hooks}, unless a full
+reprase is done instead.
+@end defvar
+
+@defvar semantic-clean-token-hooks
+Hooks run after a token is marked as clean (reparsed after user edits.)
+The functions must take a @var{TOKEN} as a parameter.
+Any token sent to this hook will have first been called with
+@code{semantic-dirty-token-hooks}. This hook is not called for tokens
+marked dirty if the buffer is completely reparsed. In that case, use
+@code{semantic-after-toplevel-bovinate-hook}.
+@end defvar
+
+@defvar semantic-change-hooks
+Hooks run when semantic detects a change in a buffer.
+Each hook function must take three arguments, identical to the
+common hook @code{after-change-function}.
+@end defvar
+
+Lastly, if you just want to know when a buffer changes, use this hook.
+
+@defvar semantic-after-toplevel-bovinate-hook
+Hooks run after a toplevel token parse.
+It is not run if the toplevel parse command is called, and buffer does
+not need to be fully reparsed.
+This function is also called when the toplevel cache is flushed, and
+the cache is emptied.
+For language specific hooks, make sure you define this as a local hook.
+@end defvar
+
+@defvar semantic-before-toplevel-cache-flush-hook
+Hooks run before the toplevel nonterminal cache is flushed.
+For language specific hooks, make sure you define this as a local hook.
+This hook is called before a corresponding
+@code{semantic-after-toplevel-bovinate-hook} which is also called during a
+flush when the cache is given a new value of nil.
+@end defvar
+
+@node Current Context, Tools, Utilities, Top
+@comment node-name, next, previous, up
+@chapter Deriving the Current Context
+
+This chapter deals with how to derive the current context, and also
+how a language maintainter can get the current context API to work
+with their language.
+
+By default, the behavior will function in C like languages. This
+means languages with parenthetical blocks, and type dereferencing
+which uses a similar form.
+
+@menu
+* Blocks::
+* Local Variables:: Getting lists of local variables.
+* Derived Context:: What goes at a given location?
+* Suggestions:: Get suggestions on one goes in a derived context.
+@end menu
+
+@node Blocks, Local Variables, Current Context, Current Context
+@section Blocks and Navigation
+
+Source code is typically built up of control structures, and blocks of
+context, or lexical scope. Semantic terms these lexical scopes as a
+``context''. The following functions can be used to navigate contexts.
+Some of them are override functions. Language authors can override
+a subset of them to make them work for their language.
+
+@defun semantic-up-context &optional point
+Move point up one context from @var{POINT}.
+Return non-@code{nil} if there are no more context levels.
+Overloaded functions using @code{up-context} take no parameters.
+@end defun
+
+@defun semantic-beginning-of-context &optional point
+Move @var{POINT} to the beginning of the current context.
+Return non-@code{nil} if there is no upper context.
+The default behavior uses @code{semantic-up-context}. It can
+be overridden with @code{beginning-of-context}.
+@end defun
+
+@defun semantic-end-of-context &optional point
+Move @var{POINT} to the end of the current context.
+Return non-@code{nil} if there is no upper context.
+Be default, this uses @code{semantic-up-context}, and assumes parenthetical
+block delimiters. This can be overridden with @code{end-of-context}.
+@end defun
+
+These next set of functions can be used to navigate across commands.
+
+@defun semantic-end-of-command
+Move to the end of the current command.
+Be default, uses @code{semantic-command-separation-character}.
+Override with @code{end-of-command}.
+@end defun
+
+@defun semantic-beginning-of-command
+Move to the beginning of the current command.
+Be default, users @code{semantic-command-separation-character}.
+Override with @code{beginning-of-command}.
+@end defun
+
+@node Local Variables, Derived Context, Blocks, Current Context
+@section Deriving local variables
+
+Within a given context, or block of code, local variables are often
+defined. These functions can be used to retrieve lists of locally
+scoped variables.
+
+@defun semantic-get-local-variables &optional point
+Get the local variables based on POINT's context.
+Local variables are returned in Semantic token format.
+Be default, this calculates the current bounds using context blocks
+navigation, then uses the parser with @code{bovine-inner-scope} to
+parse tokens at the beginning of the context.
+This can be overriden with @code{get-local-variables}.
+@end defun
+
+@defun semantic-get-local-arguments &optional point
+Get arguments (variables) from the current context at @var{POINT}.
+Parameters are available if the point is in a function or method.
+This function returns a list of tokens. If the local token returns
+just a list of strings, then this function will convert them to tokens.
+Part of this behavior can be overridden with @code{get-local-arguments}.
+@end defun
+
+@defun semantic-get-all-local-variables &optional point
+Get all local variables for this context, and parent contexts.
+Local variables are returned in Semantic token format.
+Be default, this gets local variables, and local arguments.
+This can be overridden with @code{get-all-local-variables}.
+@end defun
+
+@node Derived Context, Suggestions, Local Variables, Current Context
+@section Deriving the Current Context
+
+While a context has already been used to describe blocks of code,
+other context include more local details, such as the symbol the
+cursor is on, or the fact we are assinging into some other variable.
+
+These context deriving functions can be overridden to provide language
+specific behavior. By default, it assumes a C like language.
+
+@defun semantic-ctxt-current-symbol &optional point
+Return the current symbol the cursor is on at @var{POINT} in a list.
+This will include a list of type/field names when applicable.
+This can be overridden using @code{ctxt-current-symbol}.
+@end defun
+
+@defun semantic-ctxt-current-assignment &optional point
+Return the current assignment near the cursor at @var{POINT}.
+Return a list as per @code{semantic-ctxt-current-symbol}.
+Return @code{nil} if there is nothing relevant.
+Override with @code{ctxt-current-assignment}.
+@end defun
+
+@defun semantic-ctxt-current-function &optional point
+Return the current symbol the cursor is on at @var{POINT}.
+The function returned is the one accepting the arguments that
+the cursor is currently in.
+This can be overridden with `ctxt.current-function'.
+@end defun
+
+@defun semantic-ctxt-current-argument &optional point
+Return the current symbol the cursor is on at @var{POINT}.
+Override with @code{ctxt-current-argument}.
+@end defun
+
+@node Suggestions, , Derived Context, Current Context
+@section Getting Suggestions for the Current Context
+
+The suggestion API uses all the context deriving functions to make
+intelligent guesses as to what belongs in a given location. These
+functions can be used to create smart completion mechanisms, or
+displays.
+
+Unfortunatly, they are not fully implemented in Semantic 1.4.
+
+
+@node Tools, Index, Current Context, Top
+@comment node-name, next, previous, up
+@chapter Tools
+
+Several tools come with Semantic which would not be possible without it.
+In general, these tools will work with any language supported by
+Semantic.
+
+@menu
+* speedbar:: How to use Semantic speedbar support
+* imenu:: Special support for Imenu.
+* semanticdb:: Cache your parsed buffers between sessions.
+* senator:: The Semantic Navigator
+* document:: Document generation functions
+* miscellaneous::
+@end menu
+
+@node speedbar, imenu, Tools, Tools
+@comment node-name, next, previous, up
+@section Speedbar
+
+Speedbar supports the display of tags through the Semantic parser. To
+use this utility, add a line like this to your @file{.emacs} file:
+
+@example
+(add-hook 'speedbar-load-hook (lambda () (require 'semantic-sb)))
+@end example
+
+or you can simply add:
+
+@example
+(require 'semantic-sb)
+@end example
+
+Once installed, speedbar will use semantic to find tokens, and will
+display them appropriately. Tags from semantic will have additional
+details which can be seen, such as return type, or arguments to
+functions.
+
+@node imenu, semanticdb, speedbar, Tools
+@comment node-name, next, previous, up
+@section Imenu support
+
+There is special support for creating Imenu entries using semantic.
+This is a highly customizable tool which can create specialized menu
+systems for navigating your source file.
+
+By default, each language that wants special imenu support will set
+itself up for it. To setup imenu for your buffers, use this command
+in your @file{.emacs} file:
+
+@example
+(add-hook 'semantic-init-hooks (lambda ()
+ (imenu-add-to-menubar "TOKENS")))
+@end example
+
+Also supported is @dfn{which-func-mode}. This usually uses imenu
+tags to show the current function. The semantic support for this
+function uses overlays, which is much faster.
+
+You can customize imenu with the following options:
+
+@deffn Option semantic-imenu-summary-function
+Function to use when creating items in Imenu.
+Some useful functions are:
+@dfn{semantic-abbreviate-nonterminal}
+@dfn{semantic-summarize-nonterminal}
+@dfn{semantic-prototype-nonterminal}
+@end deffn
+
+@deffn Option semantic-imenu-bucketize-file
+Non-@code{nil} if tokens in a file are to be grouped into buckets.
+@end deffn
+
+@deffn Option semantic-imenu-buckets-to-submenu
+Non-@code{nil} if buckets of tokens are to be turned into submenus.
+This option is ignored if @code{semantic-imenu-bucketize-file} is nil.
+@end deffn
+
+@deffn Option semantic-imenu-expand-type-parts
+Non-@code{nil} if types should have submenus with parts in it.
+@end deffn
+
+@deffn Option semantic-imenu-bucketize-type-parts
+Non-@code{nil} if elements of a type should be placed grouped into buckets.
+@code{Nil} means to keep them in the same order.
+Overriden to @code{nil} if @code{semantic-imenu-bucketize-file} is nil.
+@end deffn
+
+@deffn Option semantic-imenu-sort-bucket-function
+Function to use when sorting tags in the buckets of functions.
+@end deffn
+
+@deffn Option semantic-imenu-index-directory
+Non @code{nil} to index the entire directory for tags.
+Doesn't actually parse the entire directory, but displays tags for all files
+currently listed in the current Semantic database.
+This variable has no meaning if semanticdb is not active.
+@end deffn
+
+@deffn Option semantic-imenu-auto-rebuild-directory-indexes
+If non-@code{nil} automatically rebuild directory index imenus.
+That is when a directory index imenu is updated, automatically rebuild
+other buffer local ones based on the same semanticdb.
+@end deffn
+
+When adding support to a language, this variable may need to be set:
+
+@defvar semantic-imenu-expandable-token
+Tokens of this token type will be given submenu with children.
+By default, a @code{type} has interesting children. In Texinfo, however,
+a @code{section} has interesting children.
+@end defvar
+
+
+@node semanticdb, senator, imenu, Tools
+@comment node-name, next, previous, up
+@section Semantic Database
+
+Semanticdb is a utility which tracks your parsed files, and saves the
+parsed information to files. When you reload your source files,
+semanticdb automatically associates the file with the cached copy,
+saving time by not reparsing your buffer.
+
+Semanticdb also provides an API for programs to use. These functions
+will return token information without loading the source file into
+memory by checking the disk cache.
+
+To use semanticdb, add the following to your @file{.emacs} file:
+
+@example
+(require 'semanticdb)
+(global-semanticdb-minor-mode 1)
+@end example
+
+If you have a tool which optionally uses the semantic database, it may
+be important to track if the database mode is turned on or off.
+
+@deffn Option semanticdb-mode-hooks
+Hooks run whenever @dfn{global-semanticdb-minor-mode} is run.
+Use @dfn{semanticdb-minor-mode-p} to determine if the mode has been turned
+on or off.
+@end deffn
+
+@deffn Option semanticdb-persistent-path
+List of valid paths that semanticdb will cache tokens to.
+When @dfn{global-semanticdb-minor-mode} is active, token lists will
+be saved to disk when Emacs exits. Not all directories will have
+tokens that should be saved.
+The value should be a list of valid paths. @var{A} path can be a string,
+indicating a directory in which to save a variable. An element in the
+list can also be a symbol. Valid symbols are @code{never}, which will
+disable any saving anywhere, @code{always}, which enables saving
+everywhere, or @code{project}, which enables saving in any directory that
+passes a list of predicates in @code{semantic-project-predicates}.
+@end deffn
+
+@deffn Option semanticdb-project-roots
+List of directories, where each directory is the root of some project.
+All subdirectories of a root project are considered a part of one project.
+Values in this string can be overriden by project management programs
+via the @code{semanticdb-project-root-functions} variable.
+@end deffn
+
+The important difference between these two is that you may put just
+``~'' in @code{semanticdb-persistent-path}, but you may put individual
+project directories into @code{semanticdb-project-roots} so that
+different database lists don't get cross referenced incorrectly.
+
+@subsection Searching
+
+You can search for tokens in the database using the following
+functions.
+
+@defun semanticdb-find-nonterminal-by-name name &optional databases search-parts
search-includes diff-mode find-file-match
+Find all occurances of nonterminals with name @var{NAME} in databases.
+See @dfn{semanticdb-find-nonterminal-by-function} for details on @var{DATABASES},
+@var{SEARCH-PARTS}, @var{SEARCH-INCLUDES}, @var{DIFF-MODE}, and
@var{FIND-@var{FILE}-MATCH}.
+@end defun
+
+@defun semanticdb-find-nonterminal-by-name-regexp regex &optional databases
search-parts search-includes diff-mode find-file-match
+Find all occurances of nonterminals with name matching @var{REGEX} in databases.
+See @dfn{semanticdb-find-nonterminal-by-function} for details on @var{DATABASES},
+@var{SEARCH-PARTS}, @var{SEARCH-INCLUDES} @var{DIFF-MODE}, and
@var{FIND-@var{FILE}-MATCH}.
+@end defun
+
+@defun semanticdb-find-nonterminal-by-type type &optional databases search-parts
search-includes diff-mode find-file-match
+Find all nonterminals with a type of @var{TYPE} in databases.
+See @dfn{semanticdb-find-nonterminal-by-function} for details on @var{DATABASES},
+@var{SEARCH-PARTS}, @var{SEARCH-INCLUDES} @var{DIFF-MODE}, and
@var{FIND-@var{FILE}-MATCH}.
+@end defun
+
+@defun semanticdb-find-nonterminal-by-property property value &optional databases
search-parts search-includes diff-mode find-file-match
+Find all nonterminals with a @var{PROPERTY} equal to @var{VALUE} in databases.
+See @dfn{semanticdb-find-nonterminal-by-function} for details on @var{DATABASES},
+@var{SEARCH-PARTS}, @var{SEARCH-INCLUDES} @var{DIFF-MODE}, and
@var{FIND-@var{FILE}-MATCH}.
+Return a list ((@var{DB-TABLE} . @var{TOKEN-LIST}) ...).
+@end defun
+
+@defun semanticdb-find-nonterminal-by-extra-spec spec &optional databases
search-parts search-includes diff-mode find-file-match
+Find all nonterminals with a @var{SPEC} in databases.
+See @dfn{semanticdb-find-nonterminal-by-function} for details on @var{DATABASES},
+@var{SEARCH-PARTS}, @var{SEARCH-INCLUDES} @var{DIFF-MODE}, and
@var{FIND-@var{FILE}-MATCH}.
+Return a list ((@var{DB-TABLE} . @var{TOKEN-LIST}) ...).
+@end defun
+
+@defun semanticdb-find-nonterminal-by-extra-spec-value spec value &optional databases
search-parts search-includes diff-mode find-file-match
+Find all nonterminals with a @var{SPEC} equal to @var{VALUE} in databases.
+See @dfn{semanticdb-find-nonterminal-by-function} for details on @var{DATABASES},
+@var{SEARCH-PARTS}, @var{SEARCH-INCLUDES} @var{DIFF-MODE}, and
@var{FIND-@var{FILE}-MATCH}.
+Return a list ((@var{DB-TABLE} . @var{TOKEN-LIST}) ...).
+@end defun
+
+@defun semanticdb-find-nonterminal-by-function function &optional databases
search-parts search-includes diff-mode find-file-match
+Find all occurances of nonterminals which match @var{FUNCTION}.
+Search in all @var{DATABASES}. If @var{DATABASES} is @code{nil}, search a range of
+associated databases.
+When @var{SEARCH-PARTS} is non-@code{nil} the search will include children of tokens.
+When @var{SEARCH-INCLUDES} is non-@code{nil}, the search will include dependency files.
+When @var{DIFF-MODE} is non-@code{nil}, search databases which are of a different mode.
+@var{A} Mode is the @code{major-mode} that file was in when it was last parsed.
+When @var{FIND-@var{FILE}-MATCH} is non-@code{nil}, the make sure any found token's
file is
+in an Emacs buffer.
+@end defun
+
+@defun semanticdb-file-stream file
+Return a list of tokens belonging to @var{FILE}.
+If file has database tokens available in the database, return them.
+If file does not have tokens available, then load the file, and create them.
+@end defun
+
+@node senator, document, semanticdb, Tools
+@comment node-name, next, previous, up
+@section Semantic Navigator
+
+Senator stands for SEmantic NAvigaTOR and was written by David Ponce.
+
+This library defines commands and a minor mode to navigate between
+semantic language tokens in the current buffer.
+
+@subsection Commands
+
+The following user level commands are provided by Senator.
+
+@subsubsection Navigation
+
+@deffn Command senator-next-token
+Move to the next token in the current buffer.
+@end deffn
+
+@deffn Command senator-previous-token
+Move to the previous token in the current buffer.
+@end deffn
+
+@deffn Command senator-jump sym
+Jump to the semantic symbol @var{SYM}.
+If called interactively and a prefix argument is supplied jump in the
+local type's context (see function @dfn{senator-current-type-context}).
+@end deffn
+
+@subsubsection Searching
+
+Searching using senator mode restricts the search only to the
+definition text, such as the name of the functions or variables in a
+given buffer.
+
+@deffn Command senator-isearch-toggle-semantic-mode
+Toggles semantic search in isearch mode. When semantic search is
+enabled, isearch is restricted to token names.
+@end deffn
+
+@deffn Command senator-search-forward string
+@deffnx Command senator-search-backward string
+Search forward and backward for a token matching @var{string}.
+@end deffn
+
+@deffn Command re-search-forward regex
+@deffnx Command re-search-backward regex
+Search forward and backward for a token matching the regular expression
+@var{regex}.
+@end deffn
+
+@deffn Command word-search-forward word
+@deffnx word-search-backward word
+Search forward and backward for a token whose name matches @var{word}.
+@end deffn
+
+@subsubsection Completion
+
+Completion in senator scans all known definitions in the local file,
+and uses that information to provide the completion.
+
+@deffn Command senator-complete-symbol
+Complete the current symbol under point.
+@end deffn
+
+@deffn Command senator-completion-menu-keyboard-popup
+Popup a completion menu for the symbol at point.
+@end deffn
+
+@subsubsection Copy/Paste
+
+Token Copy/Paste is a high level form of the typical copy yank used by
+Emacs. Copying a token saves the meta-information related to the
+function or item the cursor is currently in. When that information is
+yanked into a new buffer, the form of the text created is based on the
+current status of the programming buffer.
+
+For example, pasting a function into a different file results in a
+function call template to be inserted. In a Texinfo file, a @@deffn
+is created with documentation for that function or command.
+
+@deffn Command senator-copy-token
+Take the current token, and place it in the token ring.
+@end deffn
+
+@deffn Command senator-kill-token
+Take the current token, place it in the token ring, and kill it.
+Killing the token removes the text for that token, and places it into
+the kill ring. Retrieve that text with @code{yank}.
+@end deffn
+
+@deffn Command senator-yank-token
+Yank a token from the token ring.
+The form the token takes is differnet depending on where it is being
+yanked to.
+@end deffn
+
+@deffn Command senator-copy-token-to-register register &optional kill-flag
+Copy the current token into @var{REGISTER}.
+Optional argument @var{KILL-FLAG} will delete the text of the token to the
+kill ring.
+@end deffn
+
+For programmers, to provide specialized pasting, created an override
+function for @code{insert-foreign-token}. @xref{Settings}.
+
+@subsubsection Minor Mode
+
+@deffn Command senator-minor-mode
+Toggle the SEmantic NAvigaTOR key bindings in the current buffer.
+
+The following default key bindings are provided when semantic minor
+mode is enabled:
+
+
+@table @key
+@item C-c , n
+senator-next-token
+@item C-c , p
+senator-previous-token
+@item C-c , i
+senator-isearch-toggle-semantic-mode
+@item C-c , j
+senator-jump
+@item C-c , TAB
+senator-complete-symbol
+@item C-c , SPC
+senator-completion-menu-keyboard-popup
+@item C-c , C-y
+senator-yank-token
+@item C-c , C-w
+senator-kill-token
+@item C-c , M-w
+senator-copy-token
+@item C-c ,
+@end table
+@end deffn
+
+@subsection Customization
+
+To enable the Senator keymap in all modes that support semantic parsing,
+use this:
+
+@example
+(add-hook 'semantic-init-hooks 'senator-minor-mode)
+@end example
+
+To customize navigation around different types of tokens, use the
+following variables:
+
+@deffn Option senator-step-at-token-ids
+List of token identifiers where to step.
+Token identifier is symbol @code{'variable}, @code{'function}, @code{'type},
or other. If
+@code{nil} navigation steps at any token found. This is a buffer local
+variable. It can be set in a mode hook to get a specific language
+navigation.
+@end deffn
+
+@deffn Option senator-step-at-start-end-token-ids
+List of token identifiers where to step at start and end.
+Token identifier is symbol @code{'variable}, @code{'function}, @code{'type},
or other. If
+@code{nil} navigation only step at beginning of tokens. If @code{t} step at start
+and end of any token where it is allowed to step. Also, stepping at
+start and end of a token prevent stepping inside its children. This
+is a buffer local variable. It can be set in a mode hook to get a
+specific language navigation.
+@end deffn
+
+To have a mode specific customization, do something like this in a hook:
+
+@example
+(add-hook 'mode-hook
+ (lambda ()
+ (setq senator-step-at-token-ids '(function variable))
+ (setq senator-step-at-start-end-token-ids '(function))
+ ))
+@end example
+
+This will cause navigation and search commands to stop only between
+functions and variables, and to step at start and end of functions
+only.
+
+@subsection Contact information for Senator
+
+Any comments, suggestions, bug reports or upgrade requests are
+welcome. Please send them to David Ponce at david@(a)dponce.com
+
+@node document, miscellaneous, senator, Tools
+@comment node-name, next, previous, up
+@section Document generation
+
+The document program uses semantic token streams to aid in the
+creation of texinfo documentation. The main entry point for the
+documentation generator are the following commands:
+
+@deffn Command document &optional resetfile
+Document the function or variable the cursor is in.
+Optional argument @var{RESETFILE} is provided w/ universal argument.
+When non-@code{nil}, query for a new documentation file.
+@end deffn
+
+@deffn Command document-inline
+Document the current function with an inline comment.
+@end deffn
+
+@deffn Command document-insert-defun-comment nonterm buffer
+Insert mode-comment documentation about @var{NONTERM} from @var{BUFFER}.
+@end deffn
+
+@deffn Command document-insert-new-file-header header
+Insert a new header file into this buffer. Add reference to @var{HEADER}.
+Used by @code{prototype} if this file doesn't have an introductory comment.
+@end deffn
+
+In addition to these base documentation commands, the texinfo semantic
+parser includes a two convenience functions when working directly with
+texinfo files.
+
+@deffn Command semantic-texi-update-doc &optional token
+Update the documentation for @var{TOKEN}.
+If the current buffer is a texinfo file, then find the source doc, and
+update it. If the current buffer is a source file, then get the
+documentation for this item, find the existing doc in the associated
+manual, and update that.
+@end deffn
+
+@deffn Command semantic-texi-goto-source &optional token
+Jump to the source for the definition in the texinfo file @var{TOKEN}.
+If @var{TOKEN} is @code{nil}, it is derived from the deffn under @var{POINT}.
+@end deffn
+
+@node miscellaneous, , document, Tools
+@comment node-name, next, previous, up
+@section Miscellaneous commands
+
+@deffn Command semantic-show-dirty-mode arg
+Toggle highlighting of dirty tokens. When optional argument @var{arg}
+is negative, disable this mode. A positive argument enables it. If
+@var{arg} is nil, toggle.
+
+When active, tokens in the current buffer marked ``dirty'' are
+highlighted. A token is considered dirty if the token was generated
+before the most recent change to that token's text.
+@end deffn
+
+
+@node Index, , Tools, Top
+@comment node-name, next, previous, up
+@chapter Index
+
+@unnumbered Function Index
+@printindex fn
@bye
Index: xemacs-packages/semantic/semanticdb.el
===================================================================
RCS file: semanticdb.el
diff -N semanticdb.el
--- /dev/null Tue Aug 14 14:29:33 2001
+++ semanticdb.el Tue Aug 14 22:28:25 2001
@@ -0,0 +1,632 @@
+;;; semanticdb.el --- Semantic token database manager
+
+;;; Copyright (C) 2000, 2001 Eric M. Ludlam
+
+;; Author: Eric M. Ludlam <zappo(a)gnu.org>
+;; Keywords: tags
+;; X-RCS: $Id: semanticdb.el,v 1.29 2001/06/03 15:23:28 zappo Exp $
+
+;; This file is not part of GNU Emacs.
+
+;; Semanticdb is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This software is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+;;
+;;; Commentary:
+;;
+;; Maintain a database of tags for a group of files and enable
+;; queries into the database.
+;;
+;; By default, assume one database per directory.
+;;
+
+(require 'eieio-base)
+(require 'semantic)
+
+;;; Variables:
+(defgroup semanticdb nil
+ "Parser Generator Persistent Database interface."
+ :group 'semantic
+ )
+
+;;;###autoload
+(defcustom semanticdb-global-mode nil
+ "*If non-nil enable the use of `semanticdb-minor-mode'."
+ :group 'semantic
+ :type 'boolean
+ :require 'semanticdb
+ :initialize 'custom-initialize-default
+ :set (lambda (sym val)
+ (global-semanticdb-minor-mode (if val 1 -1))
+ (custom-set-default sym val)))
+
+(defcustom semanticdb-default-file-name "semantic.cache"
+ "*File name of the semantic token cache."
+ :group 'semanticdb
+ :type 'string)
+
+(defcustom semanticdb-persistent-path '(project)
+ "*List of valid paths that semanticdb will cache tokens to.
+When `global-semanticdb-minor-mode' is active, token lists will
+be saved to disk when Emacs exits. Not all directories will have
+tokens that should be saved.
+The value should be a list of valid paths. A path can be a string,
+indicating a directory in which to save a variable. An element in the
+list can also be a symbol. Valid symbols are `never', which will
+disable any saving anywhere, `always', which enables saving
+everywhere, or `project', which enables saving in any directory that
+passes a list of predicates in `semantic-project-predicates'."
+ :group 'semanticdb
+ :type nil)
+
+(defcustom semanticdb-mode-hooks nil
+ "*Hooks run whenever `global-semanticdb-minor-mode' is run.
+Use `semanticdb-minor-mode-p' to determine if the mode has been turned
+on or off."
+ :group 'semanticdb
+ :type 'hook)
+
+(defcustom semanticdb-save-database-hooks nil
+ "*Hooks run after a database is saved.
+Each function is called with one argument, the object representing
+the database recently written."
+ :group 'semanticdb
+ :type 'hook)
+
+(defvar semanticdb-database-list nil
+ "List of all active databases.")
+
+(defvar semanticdb-semantic-init-hook-overload nil
+ "Semantic init hook overload.
+Tools wanting to specify the file names of the semantic database
+use this.")
+
+(defvar semanticdb-current-database nil
+ "For a given buffer, this is the currently active database.")
+(make-variable-buffer-local 'semanticdb-current-database)
+
+(defvar semanticdb-current-table nil
+ "For a given buffer, this is the currently active database table.")
+(make-variable-buffer-local 'semanticdb-current-table)
+
+;;; Classes:
+(defclass semanticdb-project-database (eieio-persistent
+ eieio-instance-tracker)
+ ((tracking-symbol :initform semanticdb-database-list)
+ (file-header-line :initform ";; SEMANTICDB Tags save file")
+ (tables :initarg :tables
+ :type list
+ :documentation "List of `semantic-db-table' objects."))
+ "Database of file tables.")
+
+(defclass semanticdb-table ()
+ ((parent-db :documentation "Database Object containing this table.")
+ (file :initarg :file
+ :documentation "File name relative to the parent database.
+This is for the file whose tags are stored in this TABLE object.")
+ (pointmax :initarg :pointmax
+ :initform nil
+ :documentation "Size of buffer when written to disk.
+Checked on retrieval to make sure the file is the same.")
+ (major-mode :initarg :major-mode
+ :initform nil
+ :documentation "Major mode this table belongs to.
+Sometimes it is important for a program to know if a given table has the
+same major mode as the current buffer.")
+ (tokens :initarg :tokens
+ :documentation "The tokens belonging to this table."))
+ "A single table of tokens belonging to a given file.")
+
+;;; Code:
+(defun semanticdb-create-database (filename)
+ "Create a semantic database in FILENAME and return it.
+If FILENAME has already been loaded, return it.
+If FILENAME exists, then load that database, and return it.
+If FILENAME doesn't exist, create a new one."
+ (let ((db (if (file-exists-p filename)
+ (or (semanticdb-file-loaded-p filename)
+ (semanticdb-load-database filename)))))
+ (if (not (semanticdb-file-loaded-p filename))
+ (setq db (semanticdb-project-database (file-name-nondirectory filename)
+ :file filename
+ :tables nil)))
+ db))
+
+(defun semanticdb-get-database (filename)
+ "Get a database for FILENAME.
+If one isn't found, create one."
+ (or (eieio-instance-tracker-find filename 'file 'semanticdb-database-list)
+ (semanticdb-create-database filename)))
+
+(defun semanticdb-load-database (filename)
+ "Load the database FILENAME."
+ (condition-case foo
+ (let* ((r (eieio-persistent-read filename))
+ (c (oref r tables)))
+ (while c
+ ;; Restore the parent-db connection
+ (oset (car c) parent-db r)
+ (setq c (cdr c)))
+ r)
+ (error (message "Cache Error: %s, Restart" foo)
+ nil)))
+
+(defun semanticdb-file-loaded-p (filename)
+ "Return the project belonging to FILENAME if it was already loaded."
+ (object-assoc filename 'file semanticdb-database-list))
+
+(defmethod semanticdb-live-p ((obj semanticdb-project-database))
+ "Return non-nil if the file associated with OBJ is live.
+Live databases are objects associated with existing directories."
+ (let ((full-dir (file-name-directory (oref obj file))))
+ (file-exists-p full-dir)))
+
+(defmethod semanticdb-file-table ((obj semanticdb-project-database) filename)
+ "From OBJ, return FILENAMEs associated table object."
+ (object-assoc (eieio-persistent-path-relative obj filename)
+ 'file (oref obj tables)))
+
+(defun semanticdb-save-db (&optional DB)
+ "Write out the database DB to its file.
+If DB is not specified, then use the current database."
+ (let ((objname (oref DB file)))
+ (when (and (semanticdb-live-p DB)
+ (semanticdb-write-directory-p DB))
+ (message "Saving token summary for %s..." objname)
+ (condition-case foo
+ (eieio-persistent-save (or DB semanticdb-current-database))
+ (file-error ; System error saving? Ignore it.
+ (message "Error saving %s" objname))
+ (error
+ (if (and (listp foo)
+ (stringp (nth 1 foo))
+ (string-match "write-protected" (nth 1 foo)))
+ (message (nth 1 foo))
+ (error "%S" foo))))
+ (run-hook-with-args 'semanticdb-save-database-hooks
+ (or DB semanticdb-current-database))
+ (message "Saving token summary for %s...done" objname))
+ ))
+
+(defun semanticdb-save-all-db ()
+ "Save all semantic token databases."
+ (interactive)
+ (message "Saving token summaries...")
+ (mapcar 'semanticdb-save-db semanticdb-database-list)
+ (message "Saving token summaries...done"))
+
+(defmethod semanticdb-full-filename ((obj semanticdb-table))
+ "Fetch the full filename that OBJ refers to."
+ (concat (file-name-directory (oref (oref obj parent-db) file))
+ (oref obj file)))
+
+(defmethod semanticdb-live-p ((obj semanticdb-table))
+ "Return non-nil if the file associated with OBJ is live.
+Live files are either buffers in Emacs, or files existing on the filesystem."
+ (let ((full-filename (semanticdb-full-filename obj)))
+ (or (get-file-buffer full-filename)
+ (file-exists-p full-filename))))
+
+(defmethod object-write ((obj semanticdb-table))
+ "When writing a table, we have to make sure we deoverlay it first.
+Restore the overlays after writting.
+Argument OBJ is the object to write."
+ (if (semanticdb-live-p obj)
+ (let ((b (get-file-buffer (semanticdb-full-filename obj))))
+ (save-excursion
+ (if b (progn (set-buffer b)
+ (condition-case nil
+ (semantic-deoverlay-cache)
+ (error
+ (condition-case nil
+ (semantic-clear-toplevel-cache)
+ (error
+ (semantic-set-toplevel-bovine-cache nil)))))
+ (oset obj pointmax (point-max)))))
+ (call-next-method)
+ (save-excursion
+ (if b (progn (set-buffer b) (semantic-overlay-cache))))
+ )))
+
+(defmethod semanticdb-set-buffer ((obj semanticdb-table))
+ "Set the current buffer to be a buffer owned by OBJ.
+If OBJ's file is not loaded, read it in first."
+ (set-buffer (find-file-noselect (semanticdb-full-filename obj))))
+
+(defmethod semanticdb-refresh-table ((obj semanticdb-table))
+ "If the token list associated with OBJ is loaded, refresh it.
+This will call `semantic-bovinate-toplevel' if that file is in memory."
+ (let ((ff (semanticdb-full-filename obj)))
+ (if (get-file-buffer ff)
+ (save-excursion
+ (semanticdb-set-buffer obj)
+ (semantic-bovinate-toplevel t)))))
+
+;;; Directory Project support
+(defvar semanticdb-project-predicates nil
+ "List of predicates to try that indicate a directory belongs to a project.
+This list is used when `semanticdb-persistent-path' contains the value
+'project. If the predicate list is nil, then presume all paths are valid.
+
+Project Management software (such as EDE and JDE) should add their own
+predicates with `add-hook' to this variable, and semanticdb will save token
+caches in directories controlled by them.")
+
+(defmethod semanticdb-write-directory-p ((obj semanticdb-project-database))
+ "Return non-nil if OBJ should be written to disk.
+Uses `semanticdb-persistent-path' to determine the return value."
+ (let ((path semanticdb-persistent-path))
+ (catch 'found
+ (while path
+ (cond ((stringp (car path))
+ (if (string= (file-name-directory (oref obj file)) (car path))
+ (throw 'found t)))
+ ((eq (car path) 'project)
+ (let ((predicates semanticdb-project-predicates))
+ (if predicates
+ (while predicates
+ (if (funcall (car predicates)
+ (file-name-directory (oref obj file)))
+ (throw 'found t))
+ (setq predicates (cdr predicates)))
+ ;; If the mode is 'project, and there are no project
+ ;; modes, then just always save the file. If users
+ ;; wish to restrict the search, modify
+ ;; `semanticdb-persistent-path' to include desired paths.
+ (if (= (length semanticdb-persistent-path) 1)
+ (throw 'found t))
+ )))
+ ((eq (car path) 'never)
+ (throw 'found nil))
+ ((eq (car path) 'always)
+ (throw 'found t))
+ (t (error "Invalid path %S" (car path))))
+ (setq path (cdr path)))
+ nil)
+ ))
+
+;;; hooks and Hats:
+(defun semanticdb-semantic-init-hook-fcn ()
+ "Function saved in `find-file-hooks'.
+Sets up the semanticdb environment."
+ (let ((cdb nil)
+ (ctbl nil))
+ (if (not (and semanticdb-semantic-init-hook-overload
+ (setq cdb (run-hooks 'semanticdb-semantic-init-hook-overload))))
+ (setq cdb
+ (semanticdb-get-database
+ (concat (file-name-directory (buffer-file-name))
+ semanticdb-default-file-name))))
+ (setq semanticdb-current-database cdb)
+ (setq ctbl (semanticdb-file-table cdb (buffer-file-name)))
+ (unless ctbl
+ (setq ctbl
+ (semanticdb-table
+ (eieio-persistent-path-relative
+ semanticdb-current-database (buffer-file-name))
+ :file (eieio-persistent-path-relative
+ semanticdb-current-database (buffer-file-name))
+ ))
+ (oset ctbl parent-db cdb)
+ (object-add-to-list semanticdb-current-database
+ 'tables
+ ctbl
+ t))
+ (setq semanticdb-current-table ctbl)
+ (oset semanticdb-current-table major-mode major-mode)
+ (if (or (not (slot-boundp ctbl 'tokens)) (not (oref ctbl tokens))
+ (/= (or (oref ctbl pointmax) 0) (point-max))
+ )
+ (progn
+ (semantic-clear-toplevel-cache)
+ (condition-case nil
+ (semantic-bovinate-toplevel t)
+ (quit (message "semanticdb: Semantic Token generation halted."))
+ (error (error "Semanticdb: bovination failed at startup"))))
+ (semantic-set-toplevel-bovine-cache (oref ctbl tokens))
+ (semantic-overlay-cache))
+ ))
+
+(defun semanticdb-post-bovination (new-table)
+ "Function run after a bovination.
+Argument NEW-TABLE is the new table of tokens."
+ (if semanticdb-current-table
+ (oset semanticdb-current-table tokens new-table)))
+
+(defun semanticdb-kill-hook ()
+ "Function run when a buffer is killed.
+If there is a semantic cache, slurp out the overlays, an store
+it in our database. If that buffer has not cache, ignore it, we'll
+handle it later if need be."
+ (if (and (semantic-active-p)
+ semantic-toplevel-bovine-cache
+ semanticdb-current-table)
+ (progn
+ (oset semanticdb-current-table pointmax (point-max))
+ (condition-case nil
+ (semantic-deoverlay-cache)
+ ;; If this messes up, just clear the system
+ (error
+ (semantic-clear-toplevel-cache)
+ (message "semanticdb: Failed to deoverlay token cache."))))
+ ))
+
+(defun semanticdb-kill-emacs-hook ()
+ "Function called when Emacs is killed.
+Save all the databases."
+ (semanticdb-save-all-db))
+
+;;; Start/Stop database use
+;;
+(defvar semanticdb-hooks
+ '((semanticdb-semantic-init-hook-fcn semantic-init-hooks)
+ (semanticdb-post-bovination semantic-after-toplevel-cache-change-hook)
+ (semanticdb-kill-hook kill-buffer-hook)
+ (semanticdb-kill-emacs-hook kill-emacs-hook)
+ )
+ "List of hooks and values to add/remove when configuring semanticdb.")
+
+(defun semanticdb-minor-mode-p ()
+ "Return non-nil if `semanticdb-minor-mode' is active."
+ (member (car (car semanticdb-hooks))
+ (symbol-value (car (cdr (car semanticdb-hooks))))))
+
+(defun global-semanticdb-minor-mode (&optional arg)
+ "Toggle the use of `semanticdb-minor-mode'.
+If ARG is positive, enable, if it is negative, disable.
+If ARG is nil, then toggle."
+ (interactive "P")
+ (if (not arg)
+ (if (semanticdb-minor-mode-p)
+ (setq arg -1)
+ (setq arg 1)))
+ (let ((fn 'add-hook)
+ (h semanticdb-hooks))
+ (if (< arg 0)
+ (setq fn 'remove-hook))
+ ;(message "ARG = %d" arg)
+ (while h
+ (funcall fn (car (cdr (car h))) (car (car h)))
+ (setq h (cdr h)))
+ ;; Call a hook
+ (run-hooks 'semanticdb-mode-hooks)
+ ))
+
+(defun semanticdb-toggle-global-mode ()
+ "Toggle use of the Semantic Database feature.
+Update the environment of Semantic enabled buffers accordingly."
+ (interactive)
+ (if (semanticdb-minor-mode-p)
+ (progn
+ ;; Update databases before disabling semanticdb.
+ (semantic-map-buffers #'semanticdb-kill-hook)
+ ;; Save the databases.
+ (semanticdb-save-all-db)))
+ ;; Toggle semanticdb minor mode.
+ (global-semanticdb-minor-mode)
+ )
+
+;;; Utilities
+;;
+;; What is the current database, are two tables of an equivalent mode,
+;; and what databases are a part of the same project.
+(defun semanticdb-current-database ()
+ "Return the currently active database."
+ (or semanticdb-current-database
+ (and default-directory
+ (semanticdb-get-database (concat default-directory
+ semanticdb-default-file-name))
+ )
+ nil))
+
+(defmethod semanticdb-equivalent-mode ((table semanticdb-table) &optional buffer)
+ "Return non-nil if TABLE's mode is equivalent to BUFFER.
+Equivalent modes are specified by by `semantic-equivalent-major-modes'
+local variable."
+ (save-excursion
+ (if buffer (set-buffer buffer))
+ (or
+ ;; nil means the same as major-mode
+ (and (not semantic-equivalent-major-modes)
+ (eq major-mode (oref table major-mode)))
+ (and semantic-equivalent-major-modes
+ (member (oref table major-mode) semantic-equivalent-major-modes)))
+ ))
+
+(defcustom semanticdb-project-roots nil
+ "*List of directories, where each directory is the root of some project.
+All subdirectories of a root project are considered a part of one project.
+Values in this string can be overriden by project management programs
+via the `semanticdb-project-root-functions' variable."
+ :group 'semanticdb
+ :type '(repeat string))
+
+(defvar semanticdb-project-root-functions nil
+ "List of functions used to determine a given directories project root.
+Functions in this variable can override `semanticdb-project-roots'.
+Functions set in the variable are given one argument (a directory) and
+must return a string, (the root directory). This variable should be used
+by project management programs like EDE or JDE.")
+
+(defun semanticdb-current-database-list ()
+ "Return a list of databases associated with the current buffer.
+If this buffer has a database, but doesn't have a project associated
+with it, return nil.
+First, it checks `semanticdb-project-root-functions', and if that
+has no results, it checks `semanticdb-project-roots'. If that fails,
+it returns the results of function `semanticdb-current-database'."
+ (let ((root nil) ; found root directory
+ (dbs nil) ; collected databases
+ (func semanticdb-project-root-functions) ;special project functions
+ (roots semanticdb-project-roots) ;all user roots
+ (adb semanticdb-database-list) ; all databases
+ )
+ (while (and func (not root))
+ (setq root (funcall (car func) default-directory)
+ func (cdr func)))
+ (while (and roots (not root))
+ (if (string-match (concat "^"
+ (regexp-quote
+ (expand-file-name (car roots))))
+ (expand-file-name default-directory))
+ (setq root (car roots)))
+ (setq roots (cdr roots)))
+ (if root
+ (let ((regexp (concat "^" (regexp-quote (expand-file-name root)))))
+ (while (and root adb)
+ (if (string-match regexp (oref (car adb) file))
+ (setq dbs (cons (car adb) dbs)))
+ (setq adb (cdr adb)))))
+ dbs))
+
+;;; Search routines
+;;
+(defun semanticdb-find-nonterminal-by-name
+ (name &optional databases search-parts search-includes diff-mode find-file-match)
+ "Find all occurances of nonterminals with name NAME in databases.
+See `semanticdb-find-nonterminal-by-function' for details on DATABASES,
+SEARCH-PARTS, SEARCH-INCLUDES, DIFF-MODE, and FIND-FILE-MATCH.
+Return a list ((DB-TABLE . TOKEN) ...)."
+ (semanticdb-find-nonterminal-by-function
+ (lambda (stream sp si)
+ (semantic-find-nonterminal-by-name name stream sp si))
+ databases search-parts search-includes diff-mode find-file-match))
+
+(defun semanticdb-find-nonterminal-by-name-regexp
+ (regex &optional databases search-parts search-includes diff-mode
find-file-match)
+ "Find all occurances of nonterminals with name matching REGEX in databases.
+See `semanticdb-find-nonterminal-by-function' for details on DATABASES,
+SEARCH-PARTS, SEARCH-INCLUDES DIFF-MODE, and FIND-FILE-MATCH.
+Return a list ((DB-TABLE . TOKEN-LIST) ...)."
+ (semanticdb-find-nonterminal-by-function
+ (lambda (stream sp si)
+ (semantic-find-nonterminal-by-name-regexp regex stream sp si))
+ databases search-parts search-includes diff-mode find-file-match))
+
+(defun semanticdb-find-nonterminal-by-type
+ (type &optional databases search-parts search-includes diff-mode find-file-match)
+ "Find all nonterminals with a type of TYPE in databases.
+See `semanticdb-find-nonterminal-by-function' for details on DATABASES,
+SEARCH-PARTS, SEARCH-INCLUDES DIFF-MODE, and FIND-FILE-MATCH.
+Return a list ((DB-TABLE . TOKEN-LIST) ...)."
+ (semanticdb-find-nonterminal-by-function
+ (lambda (stream sp si)
+ (semantic-find-nonterminal-by-type type stream sp si))
+ databases search-parts search-includes diff-mode find-file-match))
+
+(defun semanticdb-find-nonterminal-by-property
+ (property value &optional databases search-parts search-includes diff-mode
find-file-match)
+ "Find all nonterminals with a PROPERTY equal to VALUE in databases.
+See `semanticdb-find-nonterminal-by-function' for details on DATABASES,
+SEARCH-PARTS, SEARCH-INCLUDES DIFF-MODE, and FIND-FILE-MATCH.
+Return a list ((DB-TABLE . TOKEN-LIST) ...)."
+ (semanticdb-find-nonterminal-by-function
+ (lambda (stream sp si)
+ (semantic-find-nonterminal-by-property property value stream sp si))
+ databases search-parts search-includes diff-mode find-file-match))
+
+(defun semanticdb-find-nonterminal-by-extra-spec
+ (spec &optional databases search-parts search-includes diff-mode find-file-match)
+ "Find all nonterminals with a SPEC in databases.
+See `semanticdb-find-nonterminal-by-function' for details on DATABASES,
+SEARCH-PARTS, SEARCH-INCLUDES DIFF-MODE, and FIND-FILE-MATCH.
+Return a list ((DB-TABLE . TOKEN-LIST) ...)."
+ (semanticdb-find-nonterminal-by-function
+ (lambda (stream sp si)
+ (semantic-find-nonterminal-by-extra-spec spec stream sp si))
+ databases search-parts search-includes diff-mode find-file-match))
+
+(defun semanticdb-find-nonterminal-by-extra-spec-value
+ (spec value &optional databases search-parts search-includes diff-mode
find-file-match)
+ "Find all nonterminals with a SPEC equal to VALUE in databases.
+See `semanticdb-find-nonterminal-by-function' for details on DATABASES,
+SEARCH-PARTS, SEARCH-INCLUDES DIFF-MODE, and FIND-FILE-MATCH.
+Return a list ((DB-TABLE . TOKEN-LIST) ...)."
+ (semanticdb-find-nonterminal-by-function
+ (lambda (stream sp si)
+ (semantic-find-nonterminal-by-extra-spec-value spec value stream sp si))
+ databases search-parts search-includes diff-mode find-file-match))
+
+(defun semanticdb-find-nonterminal-by-function
+ (function &optional databases search-parts search-includes diff-mode
find-file-match)
+ "Find all occurances of nonterminals which match FUNCTION.
+Search in all DATABASES. If DATABASES is nil, search a range of
+associated databases.
+When SEARCH-PARTS is non-nil the search will include children of tokens.
+When SEARCH-INCLUDES is non-nil, the search will include dependency files.
+When DIFF-MODE is non-nil, search databases which are of a different mode.
+A Mode is the `major-mode' that file was in when it was last parsed.
+When FIND-FILE-MATCH is non-nil, the make sure any found token's file is
+in an Emacs buffer.
+Return a list ((DB-TABLE . TOKEN-OR-TOKEN-LIST) ...)."
+ (if (not databases)
+ ;; Calculate what database to use.
+ ;; Something simple and dumb for now.
+ (setq databases (or (semanticdb-current-database-list)
+ (list (semanticdb-current-database)))))
+ (let ((ret nil)
+ (case-fold-search semantic-case-fold))
+ (while databases
+ (let* ((files (oref (car databases) tables))
+ (found nil)
+ (orig-buffer (current-buffer)))
+ (while files
+ (when (or diff-mode
+ (semanticdb-equivalent-mode (car files) orig-buffer))
+ ;; This can cause unneeded refreshes while typing with
+ ;; senator-eldoc mode.
+ ;;(semanticdb-refresh-table (car files))
+ (setq found (funcall function
+ (oref (car files) tokens)
+ search-parts
+ search-includes
+ )))
+ (if found
+ (progn
+ ;; When something is found, make sure we read in that buffer if it had
+ ;; not already been loaded.
+ (if find-file-match
+ (save-excursion (semanticdb-set-buffer (car files))))
+ ;; In theory, the database is up-to-date with what is in the file, and
+ ;; these tokens are ready to go.
+ ;; There is a bug lurking here I don't have time to fix.
+ (setq ret (cons (cons (car files) found) ret))
+ (setq found nil)))
+ (setq files (cdr files))))
+ (setq databases (cdr databases)))
+ (nreverse ret)))
+
+(defun semanticdb-file-stream (file)
+ "Return a list of tokens belonging to FILE.
+If file has database tokens available in the database, return them.
+If file does not have tokens available, then load the file, and create them."
+ (let* ((fo (semanticdb-get-database (concat (file-name-directory file)
+ semanticdb-default-file-name)))
+ (to nil))
+ (if fo (setq to (semanticdb-file-table fo file)))
+ (if to
+ (oref to tokens) ;; get them.
+ ;; We must load the file.
+ (save-excursion
+ (set-buffer (find-file-noselect file))
+ ;; Find file should automatically do this for us.
+ (if semanticdb-current-table
+ (oref semanticdb-current-table tokens)
+ ;; if not, just do it.
+ (semantic-bovinate-toplevel t))))
+ ))
+
+(provide 'semanticdb)
+
+;;; semanticdb.el ends here
Index: xemacs-packages/semantic/senator-isearch.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/semantic/senator-isearch.el,v
retrieving revision 1.1
diff -u -r1.1 senator-isearch.el
--- xemacs-packages/semantic/senator-isearch.el 2001/02/18 16:42:30 1.1
+++ xemacs-packages/semantic/senator-isearch.el 2001/08/15 05:28:25
@@ -1,319 +0,0 @@
-;;; senator-isearch.el --- SEmantic NAvigaTOR isearch support
-
-;; Copyright (C) 2000 by David Ponce
-
-;; Author: David Ponce <david(a)dponce.com>
-;; Maintainer: David Ponce <david(a)dponce.com>
-;; Created: 04 Dec 2000
-;; Version: 1.0
-;; Keywords: tools, syntax
-;; VC: $Id: senator-isearch.el,v 1.1 2001/02/18 16:42:30 janv Exp $
-
-;; This file is not part of Emacs
-
-;; This program is free software; you can redistribute it and/or
-;; modify it under the terms of the GNU General Public License as
-;; published by the Free Software Foundation; either version 2, or (at
-;; your option) any later version.
-
-;; This program is distributed in the hope that it will be useful, but
-;; WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-;; General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program; see the file COPYING. If not, write to
-;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
-
-;;; Commentary:
-;;
-;; This library improves isearch (and ishl) to allow overriding of the
-;; basic search functions used by `isearch-search' and
-;; `isearch-lazy-highlight-search' (or `ishl-search').
-;;
-;; This feature is needed by the SEmantic NAvigaTOR library to extend
-;; isearch with an incremental semantic search mode. When isearch is
-;; switched to this mode it searches only in language tokens in the
-;; current buffer.
-
-;; THIS CODE HAS ONLY BEEN TESTED WITH GNU EMACS 20.7, 21.0 AND XEMACS
-;; 21.1. GNU EMACS 20.7 REQUIRES ISHL 1.5 TO ENABLE ISEARCH LAZY
-;; HIGHLIGHTING.
-
-;;; Change Log:
-
-;; $Log: senator-isearch.el,v $
-;; Revision 1.1 2001/02/18 16:42:30 janv
-;; Adding senator and fixing bugs tickled by jde
-;;
-;; Revision 1.3 2001/01/03 15:41:11 david_ponce
-;; Improved isearch lazy highlighting support.
-;;
-;; Revision 1.2 2000/12/08 16:18:32 david_ponce
-;; A bunch of XEmacs compatibility code!
-;;
-;; Revision 1.1 2000/12/05 11:15:14 david_ponce
-;; Initial revision needed by senator.el 1.7 (version 2.0) and above.
-;;
-
-;;; Code:
-
-;;;;
-;;;; Improvement of `isearch-search' to use a customizable core search
-;;;; function provider. This feature will probably be included in
-;;;; isearch starting with GNU Emacs 21.2.
-;;;;
-
-(defcustom isearch-search-handler-provider 'isearch-default-search-handler
- "Function providing the basic search handlers.
-The default function `isearch-default-search-handler' provides one the
-built-ins `search-forward', `search-backward', `word-search-forward',
-`word-search-backward', `re-search-forward' or `re-search-backward'
-depending on current values of variables `isearch-forward',
-`isearch-regexp' and `isearch-word'. Any other user's defined basic
-search handler that `isearch-search-handler-provider' returns must
-accept the same arguments and have the same behaviour as the above
-built-in ones."
- :group 'isearch
- :type 'function)
-
-(defun isearch-default-search-handler ()
- "Return the actual search function used by `isearch-search'.
-That is one of the built-in functions `search-forward',
-`search-backward', `word-search-forward', `word-search-backward',
-`re-search-forward' or `re-search-backward' depending on current
-values of variables `isearch-forward', `isearch-regexp' and
-`isearch-word'."
- (cond (isearch-word
- (if isearch-forward
- 'word-search-forward
- 'word-search-backward))
- (isearch-regexp
- (if isearch-forward
- 're-search-forward
- 're-search-backward))
- (t
- (if isearch-forward
- 'search-forward
- 'search-backward))))
-
-(cond ;; Compatibility between GNU Emacs and XEmacs
-
- ((featurep 'xemacs) ;; XEmacs stuff
-
- ;; Provide `isearch-update-ring' function (from 21.1.9 isearch-mode.el)
- (defun isearch-update-ring (string &optional regexp)
- "Add STRING to the beginning of the search ring.
-REGEXP says which ring to use."
- (if (> (length string) 0)
- ;; Update the ring data.
- (if regexp
- (if (not (setq regexp-search-ring-yank-pointer
- (member string regexp-search-ring)))
- (progn
- (setq regexp-search-ring
- (cons string regexp-search-ring)
- regexp-search-ring-yank-pointer regexp-search-ring)
- (if (> (length regexp-search-ring) regexp-search-ring-max)
- (setcdr (nthcdr (1- regexp-search-ring-max) regexp-search-ring)
- nil))))
- (if (not (setq search-ring-yank-pointer
- ;; really need equal test instead of eq.
- (member string search-ring)))
- (progn
- (setq search-ring (cons string search-ring)
- search-ring-yank-pointer search-ring)
- (if (> (length search-ring) search-ring-max)
- (setcdr (nthcdr (1- search-ring-max) search-ring) nil)))))))
-
- ;; `isearch-search' from 21.1.9 isearch-mode.el
- (defadvice isearch-search (around senator activate)
- ;; Do the search with the current search string.
- (isearch-message nil t)
- (isearch-fix-case)
- (condition-case lossage
- (let ((inhibit-quit nil)
- (case-fold-search isearch-case-fold-search))
- (if isearch-regexp (setq isearch-invalid-regexp nil))
- (setq isearch-success
- (funcall
- (if isearch-search-handler-provider
- (funcall isearch-search-handler-provider)
- (isearch-default-search-handler))
- isearch-string nil t))
- (setq isearch-just-started nil)
- (if isearch-success
- (setq isearch-other-end
- (if isearch-forward (match-beginning 0) (match-end 0)))))
-
- (quit (setq unread-command-event (character-to-event (quit-char)))
- (setq isearch-success nil))
-
- (invalid-regexp
- (setq isearch-invalid-regexp (car (cdr lossage)))
- (if (string-match
- "\\`Premature \\|\\`Unmatched \\|\\`Invalid "
- isearch-invalid-regexp)
- (setq isearch-invalid-regexp (gettext "incomplete input")))))
-
- (if isearch-success
- nil
-
- ;; If we're being run inside a keyboard macro, then the call to
- ;; ding will signal an error (to terminate the macro). We must
- ;; turn off isearch-mode first, so that we aren't still in isearch
- ;; mode after the macro exits. Note that isearch-recursive-edit
- ;; must not be true if a keyboard macro is executing.
- (if (and executing-kbd-macro (not defining-kbd-macro))
- (progn
- (isearch-done)
- (ding nil 'isearch-failed)))
-
- ;; Ding if failed this time after succeeding last time.
- (and (nth 3 (car isearch-cmds))
- (ding nil 'isearch-failed))
- (goto-char (nth 2 (car isearch-cmds)))))
-
- ) ;; End of XEmacs stuff
-
- (t ;; GNU Emacs stuff
-
- ;; `isearch-search' from 20.7 (not changed in 21.0) isearch.el
- (defadvice isearch-search (around senator activate)
- ;; Do the search with the current search string.
- (isearch-message nil t)
- (if (and (eq isearch-case-fold-search t) search-upper-case)
- (setq isearch-case-fold-search
- (isearch-no-upper-case-p isearch-string isearch-regexp)))
- (condition-case lossage
- (let ((inhibit-point-motion-hooks search-invisible)
- (inhibit-quit nil)
- (case-fold-search isearch-case-fold-search)
- (retry t))
- (if isearch-regexp (setq isearch-invalid-regexp nil))
- (setq isearch-within-brackets nil)
- (while retry
- (setq isearch-success
- (funcall
- (if isearch-search-handler-provider
- (funcall isearch-search-handler-provider)
- (isearch-default-search-handler))
- isearch-string nil t))
- ;; Clear RETRY unless we matched some invisible text
- ;; and we aren't supposed to do that.
- (if (or (eq search-invisible t)
- (not isearch-success)
- (bobp) (eobp)
- (= (match-beginning 0) (match-end 0))
- (not (isearch-range-invisible
- (match-beginning 0) (match-end 0))))
- (setq retry nil)))
- (setq isearch-just-started nil)
- (if isearch-success
- (setq isearch-other-end
- (if isearch-forward (match-beginning 0) (match-end 0)))))
-
- (quit (isearch-unread ?\C-g)
- (setq isearch-success nil))
-
- (invalid-regexp
- (setq isearch-invalid-regexp (car (cdr lossage)))
- (setq isearch-within-brackets (string-match "\\`Unmatched \\["
- isearch-invalid-regexp))
- (if (string-match
- "\\`Premature \\|\\`Unmatched \\|\\`Invalid "
- isearch-invalid-regexp)
- (setq isearch-invalid-regexp "incomplete input")))
- (error
- ;; stack overflow in regexp search.
- (setq isearch-invalid-regexp (car (cdr lossage)))))
-
- (setq ad-return-value
- (if isearch-success
- nil
- ;; Ding if failed this time after succeeding last time.
- (and (nth 3 (car isearch-cmds))
- (ding))
- (goto-char (nth 2 (car isearch-cmds))))))
-
- ) ;; End of GNU Emacs stuff
-
- ) ;; End of compatibility stuff
-
-;; Improvement of the isearch lazy highlighting feature to use the
-;; core search function provider. Lazy highlighting is part of isearch
-;; for GNU Emacs 21 or provided by the optional ishl.el library for
-;; Emacs 20. Not currently implemented for XEmacs (it seems that ishl
-;; does not work).
-(cond
- (;; GNU Emacs 21 lazy highlighting
- (fboundp 'isearch-lazy-highlight-search)
-
- (defadvice isearch-lazy-highlight-search (around senator activate)
- "Search ahead for the next or previous match, for lazy highlighting.
-Attempt to do the search exactly the way the pending isearch would."
- (let ((case-fold-search isearch-case-fold-search))
- (setq ad-return-value
- (funcall (if isearch-search-handler-provider
- (funcall isearch-search-handler-provider)
- (isearch-default-search-handler))
- isearch-string
- (if isearch-forward
- (if isearch-lazy-highlight-wrapped
- isearch-lazy-highlight-start
- nil)
- (if isearch-lazy-highlight-wrapped
- isearch-lazy-highlight-end
- nil))
- t))))
-
- ;; Provide this function used by senator
- (defun senator-lazy-highlight-update ()
- "Force lazy highlight update."
- (isearch-lazy-highlight-cleanup t)
- (setq isearch-lazy-highlight-last-string nil)
- (setq isearch-adjusted t)
- (isearch-update))
-
- ) ;; End of GNU Emacs 21 lazy highlighting
-
- (;; GNU Emacs 20 lazy highlighting (from ishl.el 1.5)
- (condition-case nil
- (require 'ishl)
- (error nil))
-
- (defadvice ishl-search (around senator activate)
- (let ((case-fold-search isearch-case-fold-search))
- (setq ad-return-value
- (funcall (if isearch-search-handler-provider
- (funcall isearch-search-handler-provider)
- (isearch-default-search-handler))
- isearch-string
- (if isearch-forward
- (if ishl-wrapped ishl-start nil)
- (if ishl-wrapped ishl-end nil))
- t))))
-
- ;; Provide this function used by senator
- (defun senator-lazy-highlight-update ()
- "Force lazy highlight update."
- (ishl-cleanup t)
- (setq ishl-last-string nil)
- (setq isearch-adjusted t)
- (isearch-update))
-
- ) ;; End of GNU Emacs 20 lazy highlighting
-
- (t ;; No lazy highlighting
-
- ;; Ignore this function used by senator
- (defalias 'senator-lazy-highlight-update 'ignore)
-
- )
-
- ) ;; End of isearch lazy highlight stuff
-
-(provide 'senator-isearch)
-
-;;; senator-isearch.el ends here
Index: xemacs-packages/semantic/senator.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/semantic/senator.el,v
retrieving revision 1.1
diff -u -r1.1 senator.el
--- xemacs-packages/semantic/senator.el 2001/02/18 16:42:30 1.1
+++ xemacs-packages/semantic/senator.el 2001/08/15 05:28:26
@@ -1,13 +1,12 @@
;;; senator.el --- SEmantic NAvigaTOR
-;; Copyright (C) 2000 by David Ponce
+;; Copyright (C) 2000, 2001 by David Ponce
;; Author: David Ponce <david(a)dponce.com>
;; Maintainer: David Ponce <david(a)dponce.com>
;; Created: 10 Nov 2000
-;; Version: 2.1
-;; Keywords: tools, syntax
-;; VC: $Id: senator.el,v 1.1 2001/02/18 16:42:30 janv Exp $
+;; Keywords: syntax
+;; X-RCS: $Id: senator.el,v 1.42 2001/07/13 16:07:05 zappo Exp $
;; This file is not part of Emacs
@@ -63,6 +62,12 @@
;; C-c , p `senator-previous-token'
;; C-c , j `senator-jump'
;; C-c , i `senator-isearch-toggle-semantic-mode'
+;; C-c , TAB `senator-complete-symbol'
+;; C-c , SPC `senator-completion-menu-popup'
+;; S-mouse-3 `senator-completion-menu-popup'
+;; C-c , C-y `senator-yank-token'
+;; C-c , C-w `senator-kill-token'
+;; C-c , M-w `senator-copy-token'
;;
;; To install, put this file on your Emacs-Lisp load path and add
;; (require 'senator)
@@ -93,125 +98,17 @@
;; welcome. Please send them to David Ponce at <david(a)dponce.com>
;;; History:
-
-;; $Log: senator.el,v $
-;; Revision 1.1 2001/02/18 16:42:30 janv
-;; Adding senator and fixing bugs tickled by jde
-;;
-;; Revision 1.15 2001/01/03 16:09:28 david_ponce
-;; New version 2.1.
-;;
-;; Fixed a nasty typo in `senator-minor-mode'. `run-hooks' were missing
-;; a quotation before their arguments. Thanks to "Charles Rich"
-;; <rich(a)merl.com> who has reported this bug.
-;;
-;; Added new `senator-jump' command. Thanks to "Eric M. Ludlam"
-;; <zappo(a)ultranet.com> and "T. V. Raman" <tvraman(a)almaden.ibm.com>
for
-;; their help.
-;;
-;; Added new `senator-minor-mode-name' option to customize the name
-;; displayed in the modeline when senator minor mode is on.
-;;
-;; When semantic isearch mode is on it now appends "/si" to the senator
-;; minor mode name displayed in the modeline.
-;;
-;; Added new keyboard shortcut "\C-," to toggle semantic search in
-;; isearch mode.
-;;
-;; Some code improvements.
-;;
-;; Revision 1.14 2000/12/12 11:02:16 david_ponce
-;; `senator-mark-defun' now work on XEmacs too.
-;;
-;; Revision 1.13 2000/12/12 09:21:43 david_ponce
-;; Fixed a "side effect" bug with latest `beginning-of-defun' and
-;; `end-of-defun' advices. They caused font-lock, which uses
-;; beginning/end of defun to force a reparse. Thanks to "Eric M. Ludlam"
-;; <zappo(a)ultranet.com> for pointing this.
-;;
-;; Improved consistency with standard behaviour of `beginning-of-defun'
-;; (go to the beginning of the line where the defun starts) and
-;; `end-of-defun' (go to the beginning of the line following the end of
-;; the defun).
-;;
-;; Added useful advices for `narrow-to-defun', `mark-defun' and
-;; `c-mark-function'.
-;;
-;; Advices are enabled when the functions are called interactively and
-;; `senator-minor-mode' is enabled.
-;;
-;; Revision 1.12 2000/12/11 14:05:06 david_ponce
-;; Code cleanup and optimization.
-;; `senator-next-token' and `senator-previous-token' now correctly work
-;; when not binded to keyboard shortcuts.
-;; `beginning-of-defun' and `end-of-defun' advices no more need to be
-;; called interactively. So `narrow-to-defun' can use these advices when
-;; `senator-minor-mode' is enabled.
-;;
-;; Revision 1.11 2000/12/11 07:07:09 david_ponce
-;; Applied Eric Ludlam's patch. It adds a special face for senator to
-;; use for momentary highlight (requires latest semantic-util.el). If
-;; the user cancels the parse (C-g) when `senator-minor-mode'
-;; initializes, it doesn't kill the rest of the configuration. (Useful
-;; on a slow machine.)
-;;
-;; Revision 1.10 2000/12/08 16:18:32 david_ponce
-;; A bunch of XEmacs compatibility code!
-;;
-;; Revision 1.9 2000/12/07 09:20:21 david_ponce
-;; Applied Eric Ludlam's doc fix patch.
-;;
-;; Revision 1.8 2000/12/05 15:59:07 david_ponce
-;; Improved consistency with built-in search commands.
-;; New search commands like the ones in the Emacs Search menu.
-;; Added a menu to senator minor mode.
-;; The common prefix key in senator minor mode is now "C-c ,".
-;; Updated header comments.
-;; Some code cleanup.
-;;
-;; Revision 1.7 2000/12/05 11:13:19 david_ponce
-;; New major version 2.0 with [i]search feature and a senator minor mode.
-;; Added compatibility code between GNU Emacs 20.7 and 21.
-;;
-;; Revision 1.6 2000/11/28 12:44:47 david_ponce
-;; More performance improvements.
-;; New option `senator-highlight-found' to customize token highlighting.
-;;
-;; Revision 1.5 2000/11/27 13:24:17 david_ponce
-;; Fixed a serious performance problem in `senator-next-token' and
-;; `senator-previous-token'.
-;;
-;; Before searching for a next or previous token the point was just moved
-;; to respectively the next or previous character. Thus, during
-;; navigation, the buffer was explored character by character :-(. Now
-;; `senator-next-token' and `senator-previous-token' skip whole tokens
-;; (unless they are 'type tokens which may include sub tokens).
-;;
-;; Revision 1.4 2000/11/14 17:23:21 david_ponce
-;; Minor change to `senator-next-token' and `senator-previous-token' to
-;; return the token at point. Useful when calling these commands
-;; non-interactively.
-;;
-;; Revision 1.3 2000/11/14 13:04:26 david_ponce
-;; Improved navigation in semantic token where to step at start and end.
;;
-;; - `senator-next-token' move the point to the end of token if it was at
-;; beginning or in the middle of the token.
-;;
-;; - `senator-previous-token' move the point to the beginning of token if
-;; it was at end or in the middle of the token.
-;;
-;; Revision 1.2 2000/11/10 17:11:15 david_ponce
-;; Fixed a little bug in `senator-previous-token' navigation.
-;;
-;; Revision 1.1 2000/11/10 16:04:20 david_ponce
-;; Initial revision.
-;;
;;; Code:
(require 'semantic)
-(require 'senator-isearch) ; Needed isearch advices
+(require 'semantic-ctxt)
+(require 'semantic-imenu)
+(eval-when-compile
+ (require 'semanticdb)
+ )
+;;; Customization
(defgroup senator nil
"SEmantic NAvigaTOR."
:group 'semantic)
@@ -221,13 +118,6 @@
:group 'senator
:type 'string)
-(defface senator-momentary-highlight-face '((((class color) (background dark))
- (:background "gray30"))
- (((class color) (background light))
- (:background "gray70")))
- "Face used to momentarilly highlight tokens."
- :group 'senator)
-
(defcustom senator-step-at-token-ids nil
"*List of token identifiers where to step.
Token identifier is symbol 'variable, 'function, 'type, or other. If
@@ -241,11 +131,15 @@
(defcustom senator-step-at-start-end-token-ids '(function)
"*List of token identifiers where to step at start and end.
Token identifier is symbol 'variable, 'function, 'type, or other. If
-nil navigation only step at beginning of tokens. This is a buffer
-local variable. It can be set in a mode hook to get a specific
-langage navigation."
+nil navigation only step at beginning of tokens. If t step at start
+and end of any token where it is allowed to step. Also, stepping at
+start and end of a token prevent stepping inside its children. This
+is a buffer local variable. It can be set in a mode hook to get a
+specific langage navigation."
:group 'senator
- :type '(repeat (symbol)))
+ :type '(choice :tag "Identifiers"
+ (repeat :menu-tag "Symbols" (symbol))
+ (const :tag "All" t)))
(make-variable-buffer-local 'senator-step-at-start-end-token-ids)
(defcustom senator-highlight-found t
@@ -256,62 +150,57 @@
:group 'senator
:type 'boolean)
(make-variable-buffer-local 'senator-highlight-found)
-
-(defcustom senator-separator-char ?#
- "*Character separator used to compose token full name."
- :group 'senator
- :type 'character)
-(make-variable-buffer-local 'senator-separator-char)
-;;; Compatibility
-(cond ((fboundp 'semantic-momentary-highlight-token)
- ;; semantic 1.3
- (defun senator-parse ()
- "Parse the current buffer and return the tokens where to navigate."
- (semantic-bovinate-toplevel t))
- )
- (t
- ;; semantic before 1.3
- (defun semantic-momentary-highlight-token (&rest ignore)
- "Highlight a token, removing highlighting when the user hits a key.
-Not implemented in this version of the Semantic Bovinator. IGNORE
-arguments and always return nil."
- nil)
- (defun semantic-find-nonterminal-by-overlay (&rest ignore)
- "Find all nonterminals covering a position by using overlays.
-Not implemented in this version of the Semantic Bovinator. IGNORE
-arguments and always return nil."
- nil)
- (defun senator-parse ()
- "Parse the current buffer and return the tokens where to navigate."
- (semantic-bovinate-toplevel nil nil t))
- ))
+;;; Faces
+(defface senator-momentary-highlight-face '((((class color) (background dark))
+ (:background "gray30"))
+ (((class color) (background light))
+ (:background "gray70")))
+ "Face used to momentarily highlight tokens."
+ :group 'semantic-faces)
+
+(defface senator-intangible-face '((((class color) (background light))
+ (:foreground "gray25"))
+ (((class color) (background dark))
+ (:foreground "gray75")))
+ "Face placed on intangible text."
+ :group 'semantic-faces)
+
+(defface senator-read-only-face '((((class color) (background dark))
+ (:background "#664444"))
+ (((class color) (background light))
+ (:background "#CCBBBB")))
+ "Face placed on read-only text."
+ :group 'semantic-faces)
;;;;
;;;; Common functions
;;;;
+(defsubst senator-parse ()
+ "Parse the current buffer and return the tokens where to navigate."
+ (semantic-bovinate-toplevel t))
+
+(defsubst senator-current-token ()
+ "Return the current token in the current buffer.
+Raise an error is there is no token here."
+ (or (semantic-current-nonterminal)
+ (error "No semantic tokens here")))
+
(defun senator-momentary-highlight-token (token)
"Momentary highlight TOKEN.
-Does nothing if `senator-highlight-found' is nil or semantic version
-is bellow 1.3."
+Does nothing if `senator-highlight-found' is nil."
(and senator-highlight-found
- (condition-case nil
- (semantic-momentary-highlight-token
- token 'senator-momentary-highlight-face)
- (error (semantic-momentary-highlight-token token)))))
-
-(defun senator-message (&rest args)
- "Call function `message' with ARGS without logging."
- (let (message-log-max)
- (apply 'message args)))
+ (semantic-momentary-highlight-token
+ token
+ 'senator-momentary-highlight-face)))
(defun senator-step-at-start-end-p (token)
"Return non-nil if must step at start and end of TOKEN."
- (if token
- (let ((categ (semantic-token-token token)))
- (and (not (eq categ 'type))
- (memq categ senator-step-at-start-end-token-ids)))))
+ (and token
+ (or (eq senator-step-at-start-end-token-ids t)
+ (memq (semantic-token-token token)
+ senator-step-at-start-end-token-ids))))
(defun senator-skip-p (token)
"Return non-nil if must skip TOKEN."
@@ -320,99 +209,187 @@
(not (memq (semantic-token-token token)
senator-step-at-token-ids))))
-(defun senator-find-token-before (tokens pos comp &optional prev)
- "Visit TOKENS and return the last one found at or before POS.
-COMP is the function used to compare a current visited token start
-position to POS. That is `>=' to return the token before POS or `>'
-to return the token at or before POS. PREV is the last token found or
-nil."
- (let (token)
- (while tokens
- (setq token (car tokens))
- (if (funcall comp (semantic-token-start token) pos)
- (throw 'found prev))
- (or (senator-skip-p token)
- (setq prev token))
- (if (eq (semantic-token-token token) 'type)
- (setq prev (senator-find-token-before
- (semantic-token-type-parts token) pos comp prev)))
- (setq tokens (cdr tokens)))
- prev))
-
-(defun senator-find-previous-token (tokens pos)
- "Visit TOKENS and return the token before POS."
- (catch 'found (senator-find-token-before tokens pos #'>=)))
-
-(defun senator-find-last-token (tokens pos)
- "Visit TOKENS and return the token at or before POS."
- (catch 'found (senator-find-token-before tokens pos #'>)))
-
-(defun senator-find-next-token (tokens pos)
- "Visit TOKENS and return the token after POS."
- (let (token found)
- (while (and tokens (not found))
- (setq token (car tokens))
- (if (and (not (senator-skip-p token))
- (or (and (senator-step-at-start-end-p token)
- (> (semantic-token-end token) pos))
- (> (semantic-token-start token) pos)))
- (setq found token)
- (if (eq (semantic-token-token token) 'type)
- (setq found (senator-find-next-token
- (semantic-token-type-parts token) pos))))
- (setq tokens (cdr tokens)))
- found))
-
(defun senator-middle-of-token-p (pos token)
"Return non-nil if POS is between start and end of TOKEN."
(and (> pos (semantic-token-start token))
(< pos (semantic-token-end token))))
+(defun senator-step-at-parent (token)
+ "Return TOKEN's outermost parent if must step at start/end of it.
+Return nil otherwise."
+ (if token
+ (let (parent parents)
+ (setq parents (semantic-find-nonterminal-by-overlay
+ (semantic-token-start token)))
+ (while (and parents (not parent))
+ (setq parent (car parents)
+ parents (cdr parents))
+ (if (or (eq token parent)
+ (senator-skip-p parent)
+ (not (senator-step-at-start-end-p parent)))
+ (setq parent nil)))
+ parent)))
+
+(defun senator-previous-token-or-parent (pos)
+ "Return the token before POS or one of its parent where to step."
+ (let ((token (semantic-find-nonterminal-by-overlay-prev pos)))
+ (or (senator-step-at-parent token) token)))
+
(defun senator-full-token-name (token parent)
- "Compose a full name from TOKEN name and names in its PARENT list.
-A `senator-separator-char' separates each token name. The parent list
-is in reverse order."
- (let ((sep (char-to-string senator-separator-char))
+ "Compose a full name from TOKEN name and PARENT names.
+That is append to TOKEN name PARENT names each one separated by
+`semantic-type-relation-separator-character'. The PARENT list is in
+reverse order."
+ (let ((sep (car semantic-type-relation-separator-character))
(name ""))
(while parent
- (setq name (concat (semantic-token-name (car parent))
- sep
- name)
+ (setq name (concat name sep
+ (semantic-token-name (car parent)))
parent (cdr parent)))
- (concat name (semantic-token-name token))))
+ (concat (semantic-token-name token) name)))
-(defun senator-last-name (full-name)
- "Return the last name from FULL-NAME.
-That is the name after the last `senator-separator-char' or FULL-NAME
-itself if it does not contain any separator character."
- (and (string-match (format "[%c]?\\([^%c]+\\)\\'"
- senator-separator-char
- senator-separator-char)
- full-name)
- (match-string 1 full-name)))
-
-(defun senator-completion-stream (stream parent full-name-p &optional top-level)
- "Return a useful completion list from STREAM.
-That is a flat list of all tokens available. Prepend to each token
-name the name of tokens in its PARENT list if FULL-NAME-P is non-nil.
-This helps to distinguish between tokens in multiple top level type
-declarations or in sub type declarations. If TOP-LEVEL is non-nil the
-completion list will contain only tokens at top level. Otherwise all
-sub type tokens are included too."
- (let (cs token)
+(defvar senator-completion-cache nil
+ "The latest full completion list is cached here.")
+(make-variable-buffer-local 'senator-completion-cache)
+
+(defun senator-completion-cache-flush-fcn (&optional ignore)
+ "Function called as a hook to clear the completion list cache.
+This is added to `semantic-before-toplevel-cache-flush-hook' and
+`semantic-clean-token-hooks'. IGNORE arguments."
+ (setq senator-completion-cache nil))
+
+(defun senator-completion-flatten-stream (stream parents &optional top-level)
+ "Return a flat list of all tokens available in STREAM.
+PARENTS is the list of parent tokens. Each element of the list is a
+pair (TOKEN . PARENTS) where PARENTS is the list of TOKEN parent
+tokens or nil. If TOP-LEVEL is non-nil the completion list will
+contain only tokens at top level. Otherwise all children tokens are
+included too."
+ (let (fs e token children)
(while stream
- (setq token (car stream))
- (setq stream (cdr stream))
- (setq cs (cons (cons (senator-full-token-name token parent)
- (cdr token))
- cs))
+ (setq token (car stream)
+ stream (cdr stream)
+ e (cons token parents)
+ fs (cons e fs))
(and (not top-level)
- (eq (semantic-token-token token) 'type)
- (setq cs (append cs (senator-completion-stream
- (semantic-token-type-parts token)
- (and full-name-p (cons token parent))
- t)))))
- cs))
+ ;; Not include function arguments
+ (not (eq (semantic-token-token token) 'function))
+ (setq children (semantic-nonterminal-children token t))
+ (setq fs (append fs (senator-completion-flatten-stream
+ children e)))))
+ fs))
+
+(defun senator-completion-function-args (token)
+ "Return a string of argument names from function TOKEN."
+ (mapconcat #'(lambda (arg)
+ (if (semantic-token-p arg)
+ (semantic-token-name arg)
+ (format "%s" arg)))
+ (semantic-token-function-args token)
+ semantic-function-argument-separation-character))
+
+(defun senator-completion-refine-name (elt)
+ "Refine the name part of ELT.
+ELT has the form (NAME . (TOKEN . PARENTS)). The NAME refinement is
+done in the following incremental way:
+
+- - If TOKEN is a function one append the argument name list to NAME.
+
+- - If TOKEN is a type one append \"{}\" to NAME.
+
+- - If TOKEN is an include one append \"#\" to NAME.
+
+- - If TOKEN is a package one append \"=\" to NAME.
+
+- - If TOKEN has PARENTS append the next parent name to NAME,
+ separated by the first string found in
+ `semantic-type-relation-separator-character'.
+
+- - Otherwise NAME is set to \"token-name(a)token-start-position\"."
+ (let* ((sep (car semantic-type-relation-separator-character))
+ (name (car elt))
+ (token (car (cdr elt)))
+ (parents (cdr (cdr elt)))
+ (oname (semantic-token-name token))
+ (tokt (semantic-token-token token)))
+ (cond
+ ((and (eq tokt 'function) (string-equal name oname))
+ (setq name (format "%s(%s)" name
+ (senator-completion-function-args token))))
+ ((and (eq tokt 'type) (string-equal name oname))
+ (setq name (format "%s{}" name)))
+ ((and (eq tokt 'include) (string-equal name oname))
+ (setq name (format "%s#" name)))
+ ((and (eq tokt 'package) (string-equal name oname))
+ (setq name (format "%s=" name)))
+ (parents
+ (setq name (format "%s%s%s" name
+ (if (eq (semantic-token-token (car parents))
+ 'function)
+ ")" sep)
+ (semantic-token-name (car parents)))
+ parents (cdr parents)))
+ (t
+ (setq name (format "%s@%d" oname
+ (semantic-token-start token)))))
+ (setcar elt name)
+ (setcdr elt (cons token parents))))
+
+(defun senator-completion-uniquify-names (completion-stream)
+ "Uniquify names in COMPLETION-STREAM.
+That is refine the name part of each COMPLETION-STREAM element until
+there is no duplicated names. Each element of COMPLETION-STREAM has
+the form (NAME . (TOKEN . PARENTS)). See also the function
+`senator-completion-refine-name'."
+ (let ((completion-stream (sort completion-stream
+ #'(lambda (e1 e2)
+ (string-lessp (car e1)
+ (car e2)))))
+ (dupp t)
+ clst elt dup name)
+ (while dupp
+ (setq dupp nil
+ clst completion-stream)
+ (while clst
+ (setq elt (car clst)
+ name (car elt)
+ clst (cdr clst)
+ dup (and clst
+ (string-equal name (car (car clst)))
+ elt)
+ dupp (or dupp dup))
+ (while dup
+ (senator-completion-refine-name dup)
+ (setq elt (car clst)
+ dup (and elt (string-equal name (car elt)) elt))
+ (and dup (setq clst (cdr clst))))))
+ ;; Return a usable completion alist where each element has the
+ ;; form (NAME . TOKEN).
+ (setq clst completion-stream)
+ (while clst
+ (setq elt (car clst)
+ clst (cdr clst))
+ (setcdr elt (car (cdr elt))))
+ completion-stream))
+
+(defun senator-completion-stream (stream &optional top-level)
+ "Return a useful completion list from tokens in STREAM.
+That is an alist of all (COMPLETION-NAME . TOKEN) available.
+COMPLETION-NAME is an unique token name (see also the function
+`senator-completion-uniquify-names'). If TOP-LEVEL is non-nil the
+completion list will contain only tokens at top level. Otherwise all
+sub tokens are included too."
+ (let* ((fs (senator-completion-flatten-stream stream nil top-level))
+ cs elt tok)
+ ;; Transform each FS element from (TOKEN . PARENTS)
+ ;; to (NAME . (TOKEN . PARENT)).
+ (while fs
+ (setq elt (car fs)
+ tok (car elt)
+ fs (cdr fs)
+ cs (cons (cons (semantic-token-name tok) elt) cs)))
+ ;; Return a completion list with unique COMPLETION-NAMEs.
+ (senator-completion-uniquify-names cs)))
(defun senator-current-type-context ()
"Return tokens in the type context at point or nil if not found."
@@ -424,18 +401,39 @@
(defun senator-completion-list (&optional in-context)
"Return a useful completion list from tokens in current buffer.
-That is a flat list of all tokens available. If IN-CONTEXT is not nil
-return only the top level tokens in the type context at point or the
-top level tokens in the current buffer if no type context exists at
-point."
- (let (stream full-name-p)
+If IN-CONTEXT is non-nil return only the top level tokens in the type
+context at point or the top level tokens in the current buffer if no
+type context exists at point."
+ (let (stream)
(if in-context
(setq stream (senator-current-type-context)))
(or stream (setq stream (senator-parse)))
- (setq full-name-p (and (not in-context)
- (cdr (semantic-find-nonterminal-by-token
- 'type stream))))
- (senator-completion-stream stream nil full-name-p in-context)))
+ ;; IN-CONTEXT completion doesn't use nor set the cache.
+ (or (and (not in-context) senator-completion-cache)
+ (let ((clst (senator-completion-stream stream in-context)))
+ (or in-context
+ (setq senator-completion-cache clst))
+ clst))))
+
+;;; Senator stream searching functions:
+;;
+(defun senator-find-nonterminal-by-name (name)
+ "Find a token with NAME.
+Uses `semanticdb' when available."
+ (if (and (featurep 'semanticdb) (semanticdb-minor-mode-p))
+ ;; semanticdb version returns a list of (DB-TABLE . TOKEN)
+ (semanticdb-find-nonterminal-by-name name nil t)
+ ;; for semantic version just return TOKEN
+ (semantic-find-nonterminal-by-name name (current-buffer) t)))
+
+(defun senator-find-nonterminal-by-name-regexp (regexp)
+ "Find all tokens with a name matching REGEXP.
+Uses `semanticdb' when available."
+ (if (and (featurep 'semanticdb) (semanticdb-minor-mode-p))
+ ;; semanticdb version returns a list of (DB-TABLE . TOKEN-LIST)
+ (semanticdb-find-nonterminal-by-name-regexp regexp nil t)
+ ;; for semantic version just return TOKEN-LIST
+ (semantic-find-nonterminal-by-name-regexp regexp (current-buffer) t)))
;;;;
;;;; Search functions
@@ -446,69 +444,92 @@
Set point to the end of the name, and return point. To get the
beginning of the name use (match-beginning 0)."
(let ((name (semantic-token-name token)))
+ (setq name (if (string-match "\\`\\([^[]+\\)[[]" name)
+ (match-string 1 name)
+ name))
(goto-char (semantic-token-start token))
(re-search-forward (concat
- "\\b"
- (regexp-quote
- (if (string-match "\\`\\([^[]+\\)[[]" name)
- (match-string 1 name)
- name)))
- (semantic-token-end token))))
+ ;; the token name is at the beginning of a
+ ;; word or after a whitespace or a punctuation
+ "\\(\\<\\|\\s-+\\|\\s.\\)"
+ (regexp-quote name))
+ (semantic-token-end token))
+ (goto-char (match-beginning 0))
+ (search-forward name)))
(defun senator-search-forward-raw (searcher what &optional bound noerror count)
- "Use SEARCHER to search WHAT in semantic tokens after point.
-See `search-forward' for the meaning of BOUND NOERROR and COUNT.
-BOUND and COUNT are just ignored in the current implementation."
- (let ((origin (point))
- (tokens (senator-parse))
- (senator-step-at-start-end-token-ids nil)
- token pos start limit)
- (save-excursion
- (setq token (or (senator-find-last-token tokens origin)
- (senator-find-next-token tokens origin)))
- (while (and token (not pos))
- (setq limit (senator-search-token-name token))
- (setq start (match-beginning 0))
- (if (and (> origin start) (< origin limit))
- (setq start origin))
- (goto-char start)
- (setq pos (funcall searcher what limit t))
- (if (and pos (>= (match-beginning 0) origin))
- nil
- (setq pos nil)
- (setq token (senator-find-next-token tokens (point))))))
- (if pos
- (goto-char start)
- (setq limit (point)))
- (funcall searcher what limit noerror)))
+ "Use SEARCHER to search WHAT in Semantic token names after point.
+See `search-forward' for the meaning of BOUND NOERROR and COUNT."
+ (let* ((origin (point))
+ (count (or count 1))
+ (step (cond ((= count 0) 0)
+ ((> count 0) 1)
+ (t (setq count (- count))
+ -1)))
+ found next sstart send token tstart tend)
+ (or (= step 0)
+ (while (and (not found)
+ (setq next (funcall searcher what bound t step)))
+ (setq sstart (match-beginning 0)
+ send (match-end 0)
+ token (semantic-current-nonterminal))
+ (if (= sstart send)
+ (setq found t)
+ (if token
+ (setq tend (senator-search-token-name token)
+ tstart (match-beginning 0)
+ found (and (>= sstart tstart)
+ (<= send tend)
+ (= (setq count (1- count)) 0))))
+ (goto-char next))))
+ (cond ((null found)
+ (setq next origin
+ send origin))
+ ((= step -1)
+ (setq next send
+ send sstart))
+ (t
+ (setq next sstart)))
+ (goto-char next)
+ ;; Setup the returned value and the `match-data' or maybe fail!
+ (funcall searcher what send noerror step)))
(defun senator-search-backward-raw (searcher what &optional bound noerror count)
- "Use SEARCHER to search WHAT in semantic tokens before point.
-See `search-backward' for the meaning of BOUND NOERROR and
-COUNT. BOUND and COUNT are just ignored in the current
-implementation."
- (let ((origin (point))
- (tokens (senator-parse))
- (senator-step-at-start-end-token-ids nil)
- token pos start limit)
- (save-excursion
- (setq token (senator-find-previous-token tokens origin))
- (while (and token (not pos))
- (setq start (senator-search-token-name token))
- (setq limit (match-beginning 0))
- (if (and (< origin start) (> origin limit))
- (setq start origin))
- (goto-char start)
- (setq pos (funcall searcher what limit t))
- (if (and pos (<= (match-end 0) origin))
- nil
- (setq pos nil)
- (goto-char (semantic-token-start token))
- (setq token (senator-find-previous-token tokens (point))))))
- (if pos
- (goto-char start)
- (setq limit (point)))
- (funcall searcher what limit noerror)))
+ "Use SEARCHER to search WHAT in Semantic token names before point.
+See `search-backward' for the meaning of BOUND NOERROR and COUNT."
+ (let* ((origin (point))
+ (count (or count 1))
+ (step (cond ((= count 0) 0)
+ ((> count 0) 1)
+ (t (setq count (- count))
+ -1)))
+ found next sstart send token tstart tend)
+ (or (= step 0)
+ (while (and (not found)
+ (setq next (funcall searcher what bound t step)))
+ (setq sstart (match-beginning 0)
+ send (match-end 0)
+ token (semantic-current-nonterminal))
+ (if (= sstart send)
+ (setq found t)
+ (if token
+ (setq tend (senator-search-token-name token)
+ tstart (match-beginning 0)
+ found (and (>= sstart tstart)
+ (<= send tend)
+ (= (setq count (1- count)) 0))))
+ (goto-char next))))
+ (cond ((null found)
+ (setq next origin
+ send origin))
+ ((= step 1)
+ (setq next send
+ send sstart))
+ (t
+ (setq next sstart)))
+ (goto-char next)
+ ;; Setup the returned value and the `match-data' or maybe fail!
+ (funcall searcher what send noerror step)))
;;;;
;;;; Navigation commands
@@ -516,83 +537,447 @@
;;;###autoload
(defun senator-next-token ()
- "Navigate to the next semantic token.
-Return the semantic token or nil if at end of buffer."
+ "Navigate to the next Semantic token.
+Return the token or nil if at end of buffer."
(interactive)
- (let ((pos (point))
- (tokens (senator-parse))
- found where)
- (setq found (senator-find-next-token tokens (point)))
- (if (not found)
+ (let ((pos (point))
+ (token (semantic-current-nonterminal))
+ where)
+ (if (and token
+ (not (senator-skip-p token))
+ (senator-step-at-start-end-p token)
+ (or (= pos (semantic-token-start token))
+ (senator-middle-of-token-p pos token)))
+ nil
+ (if (setq token (senator-step-at-parent token))
+ nil
+ (setq token (semantic-find-nonterminal-by-overlay-next pos))
+ (while (and token (senator-skip-p token))
+ (setq token (semantic-find-nonterminal-by-overlay-next
+ (semantic-token-start token))))))
+ (if (not token)
(progn
(goto-char (point-max))
- (senator-message "End of buffer"))
- (cond ((and (senator-step-at-start-end-p found)
- (or (= pos (semantic-token-start found))
- (senator-middle-of-token-p pos found)))
+ (working-message "End of buffer"))
+ (cond ((and (senator-step-at-start-end-p token)
+ (or (= pos (semantic-token-start token))
+ (senator-middle-of-token-p pos token)))
(setq where "end")
- (goto-char (semantic-token-end found)))
+ (goto-char (semantic-token-end token)))
(t
(setq where "start")
- (goto-char (semantic-token-start found))))
- (senator-momentary-highlight-token found)
- (senator-message "%S: %s (%s)"
- (semantic-token-token found)
- (semantic-token-name found)
+ (goto-char (semantic-token-start token))))
+ (senator-momentary-highlight-token token)
+ (working-message "%S: %s (%s)"
+ (semantic-token-token token)
+ (semantic-token-name token)
where))
- found))
+ token))
;;;###autoload
(defun senator-previous-token ()
- "Navigate to the previous semantic token.
-Return the semantic token or nil if at beginning of buffer."
+ "Navigate to the previous Semantic token.
+Return the token or nil if at beginning of buffer."
(interactive)
- (let ((pos (point))
- (tokens (senator-parse))
- found where)
- (setq found (senator-find-previous-token tokens (point)))
- (if (not found)
+ (let ((pos (point))
+ (token (semantic-current-nonterminal))
+ where)
+ (if (and token
+ (not (senator-skip-p token))
+ (senator-step-at-start-end-p token)
+ (or (= pos (semantic-token-end token))
+ (senator-middle-of-token-p pos token)))
+ nil
+ (if (setq token (senator-step-at-parent token))
+ nil
+ (setq token (senator-previous-token-or-parent pos))
+ (while (and token (senator-skip-p token))
+ (setq token (senator-previous-token-or-parent
+ (semantic-token-start token))))))
+ (if (not token)
(progn
(goto-char (point-min))
- (senator-message "Beginning of buffer"))
- (cond ((or (not (senator-step-at-start-end-p found))
- (= pos (semantic-token-end found))
- (senator-middle-of-token-p pos found))
+ (working-message "Beginning of buffer"))
+ (cond ((or (not (senator-step-at-start-end-p token))
+ (= pos (semantic-token-end token))
+ (senator-middle-of-token-p pos token))
(setq where "start")
- (goto-char (semantic-token-start found)))
+ (goto-char (semantic-token-start token)))
(t
(setq where "end")
- (goto-char (semantic-token-end found))))
- (senator-momentary-highlight-token found)
- (senator-message "%S: %s (%s)"
- (semantic-token-token found)
- (semantic-token-name found)
+ (goto-char (semantic-token-end token))))
+ (senator-momentary-highlight-token token)
+ (working-message "%S: %s (%s)"
+ (semantic-token-token token)
+ (semantic-token-name token)
where))
- found))
+ token))
+
+(defvar senator-jump-completion-list nil
+ "`senator-jump' stores here its current completion list.
+Then use `assoc' to retrieve the token associated to a symbol.")
+
+(defun senator-jump-interactive (prompt &optional in-context no-default
require-match)
+ "Called interactively to provide completion on some tag name.
+
+Use PROMPT. If optional IN-CONTEXT is non-nil jump in the local
+type's context \(see function `senator-current-type-context'). If
+optional NO-DEFAULT is non-nil do not provide a default value. If
+optional REQUIRE-MATCH is non-nil an explicit match must be made.
+
+The IN-CONTEXT and NO-DEFAULT switches are combined using the
+following prefix arguments:
+
+- - \\[universal-argument] IN-CONTEXT.
+- - \\[universal-argument] - NO-DEFAULT.
+- - \\[universal-argument] \\[universal-argument] IN-CONTEXT + NO-DEFAULT."
+ (let* ((arg (prefix-numeric-value current-prefix-arg))
+ (no-default
+ (or no-default
+ ;; The `completing-read' function provided by XEmacs
+ ;; (21.1) don't allow a default value argument :-(
+ (featurep 'xemacs)
+ (= arg -1) ; C-u -
+ (= arg 16))) ; C-u C-u
+ (in-context
+ (or in-context
+ (= arg 4) ; C-u
+ (= arg 16))) ; C-u C-u
+ (context
+ (and (not no-default)
+ (or (semantic-ctxt-current-symbol)
+ (semantic-ctxt-current-function))))
+ (completing-read-args
+ (list (if (and context (car context))
+ (concat prompt "(default: " (car context) ") ")
+ prompt)
+ (setq senator-jump-completion-list
+ (senator-completion-list in-context))
+ nil
+ require-match
+ ""
+ 'semantic-read-symbol-history)))
+ (list
+ (apply #'completing-read
+ (if (and context (car context))
+ (append completing-read-args context)
+ completing-read-args))
+ in-context no-default)))
+
+(defun senator-jump-noselect (sym &optional next-p regexp-p)
+ "Jump to the semantic symbol SYM.
+If NEXT-P is non-nil, then move the the next tag in the search
+assuming there was already one jump for the given symbol.
+If REGEXP-P is non nil, then treat SYM as a regular expression.
+Return the token jumped to.
+Note: REGEXP-P doesn't work yet. This needs to be added to get
+the etags override to be fully functional."
+ (let ((token (cdr (assoc sym senator-jump-completion-list))))
+ (when token
+ (set-buffer (semantic-token-buffer token))
+ (goto-char (semantic-token-start token))
+ token)))
;;;###autoload
-(defun senator-jump (sym)
+(defun senator-jump (sym &optional in-context no-default)
"Jump to the semantic symbol SYM.
-If called interactively and a prefix argument is supplied jump in the
-local type's context (see function `senator-current-type-context')."
- (interactive
- (list
- (completing-read "Jump to: "
- (senator-completion-list current-prefix-arg)
- nil
- t
- ""
- 'semantic-read-symbol-history)))
- (when sym
- (let ((token
- (semantic-find-nonterminal-by-name (senator-last-name sym)
- (current-buffer))))
- (goto-char (semantic-token-start token))
- (senator-momentary-highlight-token token)
- (senator-message "%S: %s "
- (semantic-token-token token)
- (semantic-token-name token)))))
+If optional IN-CONTEXT is non-nil jump in the local type's context
+\(see function `senator-current-type-context'). If optional
+NO-DEFAULT is non-nil do not provide a default value.
+
+When called interactively you can combine the IN-CONTEXT and
+NO-DEFAULT switches like this:
+
+- - \\[universal-argument] IN-CONTEXT.
+- - \\[universal-argument] - NO-DEFAULT.
+- - \\[universal-argument] \\[universal-argument] IN-CONTEXT + NO-DEFAULT."
+ (interactive (senator-jump-interactive "Jump to: " nil nil t))
+ (push-mark)
+ (let ((tok (senator-jump-noselect sym no-default)))
+ (when tok
+ (switch-to-buffer (semantic-token-buffer tok))
+ (senator-momentary-highlight-token tok)
+ (working-message "%S: %s "
+ (semantic-token-token tok)
+ (semantic-token-name tok)))))
+
+(defun senator-jump-regexp (symregex &optional in-context no-default)
+ "Jump to the semantic symbol SYMREGEX.
+SYMREGEX is treated as a regular expression.
+
+If optional IN-CONTEXT is non-nil jump in the local type's context
+\(see function `senator-current-type-context'). If optional
+NO-DEFAULT is non-nil do not provide a default value and move to the
+next match of SYMREGEX. NOTE: Doesn't actually work yet.
+
+When called interactively you can combine the IN-CONTEXT and
+NO-DEFAULT switches like this:
+
+- - \\[universal-argument] IN-CONTEXT.
+- - \\[universal-argument] - NO-DEFAULT.
+- - \\[universal-argument] \\[universal-argument] IN-CONTEXT + NO-DEFAULT."
+ (interactive (senator-jump-interactive "Jump to: "))
+ (let ((tok (senator-jump-noselect symregex no-default)))
+ (when tok
+ (switch-to-buffer (semantic-token-buffer tok))
+ (senator-momentary-highlight-token tok)
+ (working-message "%S: %s "
+ (semantic-token-token tok)
+ (semantic-token-name tok)))))
+
+(defvar senator-last-completion-stats nil
+ "The last senator completion was here.
+Of the form (BUFFER STARTPOS INDEX REGEX COMPLIST...)")
+
+(defsubst senator-current-symbol-start ()
+ "Return position of start of the current symbol under point or nil."
+ (condition-case nil
+ (save-excursion (forward-sexp -1) (point))
+ (error nil)))
+
+;;;###autoload
+(defun senator-complete-symbol (&optional cycle-once)
+ "Complete the current symbol under point.
+If optional argument CYCLE-ONCE is non-nil, only cycle through the list
+of completions once, doing nothing where there are no more matches."
+ (interactive)
+ (let ((symstart (senator-current-symbol-start))
+ regex complst)
+ (if symstart
+ ;; Get old stats if apropriate.
+ (if (and senator-last-completion-stats
+ ;; Check if completing in the same buffer
+ (eq (car senator-last-completion-stats) (current-buffer))
+ ;; Check if completing from the same point
+ (= (nth 1 senator-last-completion-stats) symstart)
+ ;; Check if completing the same symbol
+ (save-excursion
+ (goto-char symstart)
+ (looking-at (nth 3 senator-last-completion-stats))))
+
+ (setq complst (nthcdr 4 senator-last-completion-stats))
+
+ (setq regex (regexp-quote (buffer-substring symstart (point)))
+ complst (let ((found
+ (senator-find-nonterminal-by-name-regexp
+ (concat "^" regex))))
+ (if (and found (semantic-token-p (car found)))
+ found
+ (apply #'append (mapcar #'cdr found))))
+ senator-last-completion-stats (append (list (current-buffer)
+ symstart
+ 0
+ regex)
+ complst))))
+ ;; Do the completion if apropriate.
+ (if complst
+ (let ((ret t)
+ (index (nth 2 senator-last-completion-stats))
+ newtok)
+ (if (= index (length complst))
+ ;; Cycle to the first completion token.
+ (setq index 0
+ ;; Stop completion if CYCLE-ONCE is non-nil.
+ ret (not cycle-once)))
+ ;; Get the new completion token.
+ (setq newtok (nth index complst))
+ (when ret
+ ;; Move index to the next completion token.
+ (setq index (1+ index)
+ ;; Return the completion string (useful to hippie
+ ;; expand for example)
+ ret (semantic-token-name newtok))
+ ;; Replace the string.
+ (delete-region symstart (point))
+ (insert ret))
+ ;; Update the completion index.
+ (setcar (nthcdr 2 senator-last-completion-stats) index)
+ ret))))
+
+;;;;
+;;;; Completion menu
+;;;;
+
+(defcustom senator-completion-menu-summary-function
+ 'semantic-concise-prototype-nonterminal
+ "*Function to use when creating items in completion menu.
+Some useful functions are in `semantic-token->text-functions'."
+ :group 'senator
+ :type semantic-token->text-custom-list)
+(make-variable-buffer-local 'senator-completion-menu-summary-function)
+
+(defcustom senator-completion-menu-insert-function
+ 'senator-completion-menu-insert-default
+ "*Function to use to insert an item from completion menu.
+It will receive a Semantic token as argument."
+ :group 'senator
+ :type '(radio (const senator-completion-menu-insert-default)
+ (function)))
+(make-variable-buffer-local 'senator-completion-menu-insert-function)
+
+(defun senator-completion-menu-insert-default (token)
+ "Insert a text representation of TOKEN at point."
+ (insert (semantic-token-name token)))
+
+(defun senator-completion-menu-do-complete (token-array)
+ "Replace the current syntactic expression with a chosen completion.
+Argument TOKEN-ARRAY is an array of one element containting the token
+choosen from the completion menu."
+ (let ((token (aref token-array 0))
+ (symstart (senator-current-symbol-start))
+ (finsert (if (fboundp senator-completion-menu-insert-function)
+ senator-completion-menu-insert-function
+ #'senator-completion-menu-insert-default)))
+ (if symstart
+ (progn
+ (delete-region symstart (point))
+ (funcall finsert token)))))
+
+(defun senator-completion-menu-item (token)
+ "Return a completion menu item from TOKEN.
+That is a pair (MENU-ITEM-TEXT . TOKEN-ARRAY). TOKEN-ARRAY is an
+array of one element containting TOKEN. Can return nil to discard a
+menu item."
+ (if (semantic-token-p token)
+ (cons (funcall (if (fboundp senator-completion-menu-summary-function)
+ senator-completion-menu-summary-function
+ #'semantic-prototype-nonterminal) token)
+ (vector token))
+ (cons (file-name-sans-extension (oref (car token) file))
+ (delq nil
+ (mapcar #'senator-completion-menu-item
+ (cdr token))))))
+
+(defun senator-completion-menu-window-offsets (&optional window)
+ "Return offsets of WINDOW relative to WINDOW's frame.
+Return a cons cell (XOFFSET . YOFFSET) so the position (X . Y) in
+WINDOW is equal to the position ((+ X XOFFSET) . (+ Y YOFFSET)) in
+WINDOW'S frame."
+ (let* ((window (or window (selected-window)))
+ (w (window-width window))
+ (h (window-height window))
+ (e (window-edges window))
+ (left (nth 0 e))
+ (top (nth 1 e))
+ (right (nth 2 e))
+ (bottom (nth 3 e))
+ (x (+ left (/ (- right left) 2)))
+ (y (+ top (/ (- bottom top) 2)))
+ (wpos (coordinates-in-window-p (cons x y) window))
+ (xoffset 0)
+ (yoffset 0))
+ (if (consp wpos)
+ (let* ((f (window-frame window))
+ (cy (/ 1.0 (float (frame-char-height f)))))
+ (setq xoffset (- x (car wpos))
+ yoffset (float (- y (cdr wpos))))
+ ;; If Emacs 21 add to:
+ ;; - XOFFSET the WINDOW left margin width.
+ ;; - YOFFSET the height of header lines above WINDOW.
+ (if (> emacs-major-version 20)
+ (progn
+ (setq wpos (cons (+ left xoffset) 0.0)
+ bottom (float bottom))
+ (while (< (cdr wpos) bottom)
+ (if (eq (coordinates-in-window-p wpos window)
+ 'header-line)
+ (setq yoffset (+ yoffset cy)))
+ (setcdr wpos (+ (cdr wpos) cy)))
+ (setq xoffset (floor (+ xoffset
+ (or (car (window-margins window))
+ 0))))))
+ (setq yoffset (floor yoffset))))
+ (cons xoffset yoffset)))
+
+(defun senator-completion-menu-point-as-event()
+ "Returns the text cursor position as an event.
+Also move the mouse pointer to the cursor position."
+ (let* ((w (get-buffer-window (current-buffer)))
+ (x (mod (- (current-column) (window-hscroll))
+ (window-width)))
+ (y (save-excursion
+ (save-restriction
+ (widen)
+ (narrow-to-region (window-start) (point))
+ (goto-char (point-min))
+ (1+ (vertical-motion (buffer-size))))))
+ )
+ (if (featurep 'xemacs)
+ (let* ((at (progn (set-mouse-position w x (1- y))
+ (cdr (mouse-pixel-position))))
+ (x (car at))
+ (y (cdr at)))
+ (make-event 'button-press
+ (list 'button 3
+ 'modifiers nil
+ 'x x
+ 'y y)))
+ ;; Emacs
+ (let ((offsets (senator-completion-menu-window-offsets w)))
+ ;; Convert window position (x,y) to the equivalent frame
+ ;; position and move the mouse pointer to it.
+ (set-mouse-position (window-frame w)
+ (+ x (car offsets))
+ (+ y (cdr offsets)))
+ t))))
+
+;;;###autoload
+(defun senator-completion-menu-popup ()
+ "Popup a completion menu for the symbol at point.
+The popup menu displays all of the possible completions for the symbol
+it was invoked on. To automatically split large menus this function
+use `imenu--mouse-menu' to handle the popup menu."
+ (interactive)
+ (let ((symstart (senator-current-symbol-start))
+ symbol regexp complst)
+ (if symstart
+ (setq symbol (buffer-substring-no-properties symstart (point))
+ regexp (concat "^" (regexp-quote symbol))
+ complst (senator-find-nonterminal-by-name-regexp regexp)))
+ (if (not complst)
+ (error "No completions available"))
+ ;; We have a completion list, build a menu
+ (let ((index (delq nil
+ (mapcar #'senator-completion-menu-item
+ complst)))
+ title item)
+ (cond ;; Here index is a menu structure like:
+
+ ;; -1- (("menu-item1" . [token1]) ...)
+ ((vectorp (cdr (car index)))
+ ;; There are more than one item, setup the popup title.
+ (if (cdr index)
+ (setq title (format "%S completion" symbol))
+ ;; Only one item , no need to popup the menu.
+ (setq item (car index))))
+
+ ;; -2- (("menu-title1" ("menu-item1" . [token1]) ...) ...)
+ (t
+ ;; There are sub-menus.
+ (if (cdr index)
+ ;; Several sub-menus, setup the popup title.
+ (setq title (format "%S completion" symbol))
+ ;; Only one sub-menu, convert it to a main menu and add the
+ ;; sub-menu title (filename) to the popup title.
+ (setq title (format "%S completion (%s)"
+ symbol (car (car index)))
+ index (cdr (car index)))
+ ;; But...
+ (or (cdr index)
+ ;; ... If only one menu item, no need to popup the menu.
+ (setq item (car index))))))
+
+ (or item
+ (setq item ;; Delegates menu handling to imenu :-)
+ (imenu--mouse-menu
+ index
+ ;; popup at point
+ (senator-completion-menu-point-as-event)
+ title)))
+ (if item
+ (senator-completion-menu-do-complete (cdr item))))))
+
;;;;
;;;; Search commands
;;;;
@@ -602,8 +987,7 @@
"Search semantic tokens forward from point for string WHAT.
Set point to the end of the occurrence found, and return point. See
`search-forward' for details and the meaning of BOUND NOERROR and
-COUNT. BOUND and COUNT are just ignored in the current
-implementation."
+COUNT. COUNT is just ignored in the current implementation."
(interactive "sSemantic search: ")
(senator-search-forward-raw #'search-forward what bound noerror count))
@@ -612,8 +996,7 @@
"Search semantic tokens forward from point for regexp WHAT.
Set point to the end of the occurrence found, and return point. See
`re-search-forward' for details and the meaning of BOUND NOERROR and
-COUNT. BOUND and COUNT are just ignored in the current
-implementation."
+COUNT. COUNT is just ignored in the current implementation."
(interactive "sSemantic regexp search: ")
(senator-search-forward-raw #'re-search-forward what bound noerror count))
@@ -622,8 +1005,7 @@
"Search semantic tokens forward from point for word WHAT.
Set point to the end of the occurrence found, and return point. See
`word-search-forward' for details and the meaning of BOUND NOERROR and
-COUNT. BOUND and COUNT are just ignored in the current
-implementation."
+COUNT. COUNT is just ignored in the current implementation."
(interactive "sSemantic word search: ")
(senator-search-forward-raw #'word-search-forward what bound noerror count))
@@ -632,8 +1014,7 @@
"Search semantic tokens backward from point for string WHAT.
Set point to the beginning of the occurrence found, and return point.
See `search-backward' for details and the meaning of BOUND NOERROR and
-COUNT. BOUND and COUNT are just ignored in the current
-implementation."
+COUNT. COUNT is just ignored in the current implementation."
(interactive "sSemantic backward search: ")
(senator-search-backward-raw #'search-backward what bound noerror count))
@@ -642,8 +1023,7 @@
"Search semantic tokens backward from point for regexp WHAT.
Set point to the beginning of the occurrence found, and return point.
See `re-search-backward' for details and the meaning of BOUND NOERROR
-and COUNT. BOUND and COUNT are just ignored in the current
-implementation."
+and COUNT. COUNT is just ignored in the current implementation."
(interactive "sSemantic backward regexp search: ")
(senator-search-backward-raw #'re-search-backward what bound noerror count))
@@ -652,7 +1032,7 @@
"Search semantic tokens backward from point for word WHAT.
Set point to the beginning of the occurrence found, and return point.
See `word-search-backward' for details and the meaning of BOUND
-NOERROR and COUNT. BOUND and COUNT are just ignored in the current
+NOERROR and COUNT. COUNT is just ignored in the current
implementation."
(interactive "sSemantic backward word search: ")
(senator-search-backward-raw #'word-search-backward what bound noerror count))
@@ -661,6 +1041,38 @@
;;;; Others useful search commands (minor mode menu)
;;;;
+;;; Compatibility
+(or (not (featurep 'xemacs))
+ (fboundp 'isearch-update-ring)
+
+ ;; Provide `isearch-update-ring' function.
+ ;; (from XEmacs 21.1.9 isearch-mode.el)
+ (defun isearch-update-ring (string &optional regexp)
+ "Add STRING to the beginning of the search ring.
+REGEXP says which ring to use."
+ (if (> (length string) 0)
+ ;; Update the ring data.
+ (if regexp
+ (if (not (setq regexp-search-ring-yank-pointer
+ (member string regexp-search-ring)))
+ (progn
+ (setq regexp-search-ring
+ (cons string regexp-search-ring)
+ regexp-search-ring-yank-pointer regexp-search-ring)
+ (if (> (length regexp-search-ring) regexp-search-ring-max)
+ (setcdr (nthcdr (1- regexp-search-ring-max) regexp-search-ring)
+ nil))))
+ (if (not (setq search-ring-yank-pointer
+ ;; really need equal test instead of eq.
+ (member string search-ring)))
+ (progn
+ (setq search-ring (cons string search-ring)
+ search-ring-yank-pointer search-ring)
+ (if (> (length search-ring) search-ring-max)
+ (setcdr (nthcdr (1- search-ring-max) search-ring) nil)))))))
+
+ )
+
(defun senator-nonincremental-search-forward (string)
"Search for STRING nonincrementally."
(interactive "sSemantic search for string: ")
@@ -722,8 +1134,69 @@
(senator-re-search-backward (car regexp-search-ring)))
;;;;
+;;;; Token Properties
+;;;;
+
+(defun senator-toggle-read-only (&optional token)
+ "Toggle the read-only status of the current TOKEN."
+ (interactive)
+ (let* ((tok (or token (senator-current-token)))
+ (read (semantic-token-read-only-p tok)))
+ (semantic-set-token-read-only tok read)
+ (semantic-set-token-face
+ tok
+ (if read nil 'senator-read-only-face))))
+
+(defun senator-toggle-intangible (&optional token)
+ "Toggle the tangibility of the current TOKEN."
+ (interactive)
+ (let* ((tok (or token (senator-current-token)))
+ (tang (semantic-token-intangible-p tok)))
+ (semantic-set-token-intangible tok tang)
+ (semantic-set-token-face
+ tok
+ (if tang nil 'senator-intangible-face))))
+
+(defun senator-set-face (face &optional token)
+ "Set the foreground FACE of the current TOKEN."
+ (interactive (list (read-face-name
+ (if (featurep 'xemacs)
+ "Face: "
+ ;; FSF Emacs already append ": "
+ "Face"))))
+ (let ((tok (or token (senator-current-token))))
+ (semantic-set-token-face tok face)))
+
+(defun senator-set-foreground (color &optional token)
+ "Set the foreground COLOR of the current TOKEN."
+ ;; This was copied from facemenu
+ (interactive (list (facemenu-read-color "Foreground color: ")))
+ (let ((face (intern (concat "fg:" color))))
+ (or (facemenu-get-face face)
+ (error "Unknown color: %s" color))
+ (senator-set-face face)))
+
+(defun senator-set-background (color &optional token)
+ "Set the background COLOR of the current TOKEN."
+ ;; This was copied from facemenu
+ (interactive (list (facemenu-read-color "Background color: ")))
+ (let ((face (intern (concat "bg:" color))))
+ (or (facemenu-get-face face)
+ (error "Unknown color: %s" color))
+ (senator-set-face face)))
+
+(defun senator-clear-token (&optional token)
+ "Clear all properties from TOKEN."
+ (interactive)
+ (let ((tok (or token (senator-current-token))))
+ (semantic-set-token-read-only tok t)
+ (semantic-set-token-intangible tok t)
+ (semantic-set-token-face tok nil)))
+
+;;;;
;;;; Senator minor mode
;;;;
+
(defvar senator-mode nil
"Name of the minor mode, if non-nil.")
(make-variable-buffer-local 'senator-mode)
@@ -742,6 +1215,11 @@
(define-key km "j" 'senator-jump)
(define-key km "p" 'senator-previous-token)
(define-key km "n" 'senator-next-token)
+ (define-key km "\t" 'senator-complete-symbol)
+ (define-key km " " 'senator-completion-menu-popup)
+ (define-key km "\C-w" 'senator-kill-token)
+ (define-key km "\M-w" 'senator-copy-token)
+ (define-key km "\C-y" 'senator-yank-token)
km)
"Default key bindings in senator minor mode.")
@@ -751,7 +1229,7 @@
(if (featurep 'xemacs)
(let ((n (length item))
(i 0)
- l)
+ slot l)
(while (< i n)
(setq slot (aref item i))
(if (and (keywordp slot)
@@ -764,7 +1242,7 @@
(defvar senator-menu-bar
(list
- "Senator"
+ senator-minor-mode-name
(list
"Navigate"
(senator-menu-item
@@ -845,19 +1323,235 @@
:help "Toggle semantic search in isearch mode"
])
)
+ (list
+ "Token Properties"
+;;; (senator-menu-item
+;;; [ "Hide Token"
+;;; senator-make-invisible
+;;; :active t
+;;; :help "Make the current token invisible"
+;;; ])
+;;; (senator-menu-item
+;;; [ "Show Token"
+;;; senator-make-visible
+;;; :active t
+;;; :help "Make the current token invisible"
+;;; ])
+ (senator-menu-item
+ [ "Read Only"
+ senator-toggle-read-only
+ :active (semantic-current-nonterminal)
+ :style toggle
+ :selected (let ((tok (semantic-current-nonterminal)))
+ (and tok (semantic-token-read-only-p tok)))
+ :help "Make the current token read-only"
+ ])
+ (senator-menu-item
+ [ "Intangible"
+ senator-toggle-intangible
+ ;; XEmacs extent `intangible' property seems to not exists.
+ :active (and (not (featurep 'xemacs))
+ (semantic-current-nonterminal))
+ :style toggle
+ :selected (and (not (featurep 'xemacs))
+ (let ((tok (semantic-current-nonterminal)))
+ (and tok (semantic-token-intangible-p tok))))
+ :help "Make the current token intangible"
+ ])
+ (senator-menu-item
+ [ "Set Token Face"
+ senator-set-face
+ :active (semantic-current-nonterminal)
+ :help "Set the face on the current token"
+ ])
+ (senator-menu-item
+ [ "Set Token Foreground"
+ senator-set-foreground
+ :active (semantic-current-nonterminal)
+ :help "Set the foreground color on the current token"
+ ])
+ (senator-menu-item
+ [ "Set Token Background"
+ senator-set-background
+ :active (semantic-current-nonterminal)
+ :help "Set the background color on the current token"
+ ])
+ (senator-menu-item
+ [ "Remove all properties"
+ senator-clear-token
+ :active (semantic-current-nonterminal)
+ :help "Remove all special face properties on the current token "
+ ] )
+ )
+ (list
+ "Token Copy/Paste"
+ (senator-menu-item
+ [ "Copy Token"
+ senator-copy-token
+ :active (semantic-current-nonterminal)
+ :help "Copy the current token to the token ring"
+ ])
+ (senator-menu-item
+ [ "Kill Token"
+ senator-kill-token
+ :active (semantic-current-nonterminal)
+ :help "Kill token text to the kill ring, and copy the token to the token
ring"
+ ])
+ (senator-menu-item
+ [ "Yank Token"
+ senator-yank-token
+ :active (not (ring-empty-p senator-token-ring))
+ :help "Yank a token from the token ring, inserting a
summary/prototype"
+ ])
+ (senator-menu-item
+ [ "Copy Token to Register"
+ senator-copy-token-to-register
+ :active (semantic-current-nonterminal)
+ :help "Copy the current token to a register"
+ ])
+ )
"-"
+ (list
+ "Imenu Config"
+ (list
+ "Token Sorting Function"
+ (senator-menu-item
+ [ "Do not sort"
+ (setq semantic-imenu-sort-bucket-function nil)
+ :active t
+ :style radio
+ :selected (eq semantic-imenu-sort-bucket-function nil)
+ :help "Do not sort imenu items"
+ ])
+ (senator-menu-item
+ [ "Increasing by name"
+ (setq semantic-imenu-sort-bucket-function
+ 'semantic-sort-tokens-by-name-increasing)
+ :active t
+ :style radio
+ :selected (eq semantic-imenu-sort-bucket-function
+ 'semantic-sort-tokens-by-name-increasing)
+ :help "Sort tokens by name increasing"
+ ])
+ (senator-menu-item
+ [ "Decreasing by name"
+ (setq semantic-imenu-sort-bucket-function
+ 'semantic-sort-tokens-by-name-decreasing)
+ :active t
+ :style radio
+ :selected (eq semantic-imenu-sort-bucket-function
+ 'semantic-sort-tokens-by-name-decreasing)
+ :help "Sort tokens by name decreasing"
+ ])
+ (senator-menu-item
+ [ "Increasing Case Insensitive by Name"
+ (setq semantic-imenu-sort-bucket-function
+ 'semantic-sort-tokens-by-name-increasing-ci)
+ :active t
+ :style radio
+ :selected (eq semantic-imenu-sort-bucket-function
+ 'semantic-sort-tokens-by-name-increasing-ci)
+ :help "Sort tokens by name increasing and case insensitive"
+ ])
+ (senator-menu-item
+ [ "Decreasing Case Insensitive by Name"
+ (setq semantic-imenu-sort-bucket-function
+ 'semantic-sort-tokens-by-name-decreasing-ci)
+ :active t
+ :style radio
+ :selected (eq semantic-imenu-sort-bucket-function
+ 'semantic-sort-tokens-by-name-decreasing-ci)
+ :help "Sort tokens by name decreasing and case insensitive"
+ ])
+ )
+ (senator-menu-item
+ [ "Bin tokens by type"
+ (setq semantic-imenu-bucketize-file
+ (not semantic-imenu-bucketize-file))
+ :active t
+ :style toggle
+ :selected semantic-imenu-bucketize-file
+ :help "Organize tokens in bins by type of token"
+ ])
+ (senator-menu-item
+ [ "Bins are submenus"
+ (setq semantic-imenu-buckets-to-submenu
+ (not semantic-imenu-buckets-to-submenu))
+ :active t
+ :style toggle
+ :selected semantic-imenu-buckets-to-submenu
+ :help "Organize tokens into submenus by type of token"
+ ])
+ (senator-menu-item
+ [ "Bin tokens in children"
+ (setq semantic-imenu-bucketize-type-parts
+ (not semantic-imenu-bucketize-type-parts))
+ :active t
+ :style toggle
+ :selected semantic-imenu-bucketize-type-parts
+ :help "When listing tokens inside another token; bin by token type"
+ ])
+ (senator-menu-item
+ [ "List other files"
+ (setq semantic-imenu-index-directory (not semantic-imenu-index-directory))
+ :active (and (featurep 'semanticdb) (semanticdb-minor-mode-p))
+ :style toggle
+ :selected semantic-imenu-index-directory
+ :help "List all files in the current database in the Imenu menu"
+ ])
+ (senator-menu-item
+ [ "Auto-rebuild other buffers"
+ (setq semantic-imenu-auto-rebuild-directory-indexes
+ (not semantic-imenu-auto-rebuild-directory-indexes))
+ :active (and (featurep 'semanticdb) (semanticdb-minor-mode-p))
+ :style toggle
+ :selected semantic-imenu-auto-rebuild-directory-indexes
+ :help "If listing other buffers, update all buffer menus after a
parse"
+ ])
+ )
(senator-menu-item
- ["Options..."
- (customize-group "senator")
- :active t
- :help "Customize SEmantic NAvigaTOR options"
- ])
+ [ "Semantic Database"
+ semanticdb-toggle-global-mode
+ :active (featurep 'semanticdb)
+ :style toggle
+ :selected (and (featurep 'semanticdb) (semanticdb-minor-mode-p))
+ :help "Cache tokens for killed buffers and between sessions."
+ ])
+ "-"
+ (list
+ "Options"
+ (senator-menu-item
+ ["Semantic..."
+ (customize-group "semantic")
+ :active t
+ :help "Customize Semantic options"
+ ])
+ (senator-menu-item
+ ["Senator..."
+ (customize-group "senator")
+ :active t
+ :help "Customize SEmantic NAvigaTOR options"
+ ])
+ (senator-menu-item
+ ["Semantic Imenu..."
+ (customize-group "semantic-imenu")
+ :active t
+ :help "Customize Semantic Imenu options"
+ ])
+ (senator-menu-item
+ ["Semantic Database..."
+ (customize-group "semanticdb")
+ :active t
+ :help "Customize Semantic Database options"
+ ])
+ )
)
"Menu for senator minor mode.")
(defvar senator-mode-map
(let ((km (make-sparse-keymap)))
(define-key km senator-prefix-key senator-prefix-map)
+ (define-key km [(shift mouse-3)] 'senator-completion-menu-popup)
(easy-menu-define senator-minor-menu km "Senator Minor Mode Menu"
senator-menu-bar)
km)
@@ -873,135 +1567,137 @@
senator-minor-mode-name))
(force-mode-line-update))
+(defcustom senator-minor-mode-hook nil
+ "Hook run at the end of function `senator-minor-mode'."
+ :group 'senator
+ :type 'hook)
+
+(defcustom senator-minor-mode-on-hook nil
+ "Hook called when senator minor mode is turned on."
+ :group 'senator
+ :type 'hook)
+
+(defcustom senator-minor-mode-off-hook nil
+ "Hook called when senator minor mode is turned off."
+ :group 'senator
+ :type 'hook)
+
+(defvar senator-minor-mode nil
+ "Non-nil if Senator minor mode is enabled.
+Use the command `senator-minor-mode' to change this variable.")
+(make-variable-buffer-local 'senator-minor-mode)
+
(defun senator-minor-mode-setup ()
"Actually setup the senator minor mode.
-Turn off the minor mode if semantic feature is not available or
-`semantic-toplevel-bovine-table' not provided for the current buffer.
-If minor mode is enabled parse the current buffer if needed. Return
-non-nil if the minor mode is enabled."
+The minor mode can be turned on only if semantic feature is available
+and the current buffer was set up for parsing. When minor mode is
+enabled parse the current buffer if needed. Return non-nil if the
+minor mode is enabled."
(if senator-minor-mode
- (if (not (and (featurep 'semantic) semantic-toplevel-bovine-table))
+ (if (not (and (featurep 'semantic) (semantic-active-p)))
;; Disable minor mode if semantic stuff not available
(senator-minor-mode nil)
;; XEmacs needs this
(if (featurep 'xemacs)
(easy-menu-add senator-minor-menu senator-mode-map))
;; Parse the current buffer if needed
- (condition-case nil
- (senator-parse)
- (quit (message "senator-minor-mode: parsing of buffer canceled.")))
+ (condition-case nil
+ (progn
+ (senator-parse)
+ ;; Add completion hooks
+ (add-hook 'semantic-before-toplevel-cache-flush-hook
+ 'senator-completion-cache-flush-fcn nil t)
+ (add-hook 'semantic-clean-token-hooks
+ 'senator-completion-cache-flush-fcn nil t))
+ (quit (message "senator-minor-mode: parsing of buffer canceled.")))
(senator-show-status)
)
;; XEmacs needs this
(if (featurep 'xemacs)
(easy-menu-remove senator-minor-menu))
+ ;; Remove completion hooks
+ (remove-hook 'semantic-before-toplevel-cache-flush-hook
+ 'senator-completion-cache-flush-fcn)
+ (remove-hook 'semantic-clean-token-hooks
+ 'senator-completion-cache-flush-fcn)
;; Disable semantic isearch
(setq senator-isearch-semantic-mode nil))
senator-minor-mode)
-(if (fboundp 'define-minor-mode)
-
-;;; Note that `define-minor-mode' actually calls the mode-function if
-;;; the associated variable is non-nil, which requires that all needed
-;;; functions be already defined. [This is arguably a bug in d-m-m]
-;;;###autoload
- (define-minor-mode senator-minor-mode
- "Toggle senator minor mode.
+(defun senator-minor-mode (&optional arg)
+ "Toggle senator minor mode.
With prefix argument ARG, turn on if positive, otherwise off. The
-minor mode is turned on only if semantic feature is available and a
-`semantic-toplevel-bovine-table' is provided for the current buffer.
-Return non-nil if the minor mode is enabled.
+minor mode can be turned on only if semantic feature is available and
+the current buffer was set up for parsing. Return non-nil if the
+minor mode is enabled.
\\{senator-mode-map}"
- nil senator-mode senator-mode-map
- :global nil
- :group 'senator
- (senator-minor-mode-setup))
-
-;;; `define-minor-mode' is not defined
-
- (defvar senator-minor-mode nil
- "Non-nil if senator minor mode is on.")
- (make-variable-buffer-local 'senator-minor-mode)
-
- (defvar senator-minor-mode-hook nil
- "Hook called when senator minor mode is toggled")
-
- (defvar senator-minor-mode-on-hook nil
- "Hook called when senator minor mode is turned on")
-
- (defvar senator-minor-mode-off-hook nil
- "Hook called when senator minor mode is turned off")
-
-;;;###autoload
- (defun senator-minor-mode (&optional arg)
- "Toggle senator minor mode.
-With prefix argument ARG, turn on if positive, otherwise off. The
-minor mode is turned on only if semantic feature is available and a
-`semantic-toplevel-bovine-table' is provided for the current buffer.
-Return non-nil if the minor mode is enabled.
-
-\\{senator-mode-map}"
- (interactive "P")
- (let ((old-mode senator-minor-mode))
- (setq senator-minor-mode
- (if arg
- (or (listp arg) ;; C-u alone
- (> (prefix-numeric-value arg) 0))
- (not senator-minor-mode)))
- (and senator-minor-mode-hook
- (not (equal old-mode senator-minor-mode))
- (run-hooks 'senator-minor-mode-hook))
- (and senator-minor-mode-on-hook
- senator-minor-mode
- (run-hooks 'senator-minor-mode-on-hook))
- (and senator-minor-mode-off-hook
- (not senator-minor-mode)
- (run-hooks 'senator-minor-mode-off-hook)))
- (senator-minor-mode-setup)
- (senator-message "Senator minor mode %s"
- (if senator-minor-mode
- "enabled"
- "disabled"))
- senator-minor-mode)
+ (interactive
+ (list (or current-prefix-arg
+ (if senator-minor-mode 0 1))))
+ (setq senator-minor-mode
+ (if arg
+ (>
+ (prefix-numeric-value arg)
+ 0)
+ (not senator-minor-mode)))
+ (senator-minor-mode-setup)
+ (run-hooks 'senator-minor-mode-hook
+ (if senator-minor-mode
+ 'senator-minor-mode-on-hook
+ 'senator-minor-mode-off-hook))
+ (if (interactive-p)
+ (message "Senator minor mode %sabled"
+ (if senator-minor-mode "en" "dis")))
+ (force-mode-line-update)
+ senator-minor-mode)
- (if (fboundp 'add-minor-mode)
+(if (fboundp 'add-minor-mode)
- ;; XEmacs
- (add-minor-mode 'senator-minor-mode 'senator-mode senator-mode-map)
-
- ;; Emacs 20
- (or (assq 'senator-minor-mode minor-mode-alist)
- (setq minor-mode-alist
- (cons (list 'senator-minor-mode 'senator-mode)
minor-mode-alist)))
+ ;; Emacs 21 & XEmacs
+ (add-minor-mode 'senator-minor-mode
+ 'senator-mode senator-mode-map)
+
+ ;; Emacs 20
+ (or (assq 'senator-minor-mode minor-mode-alist)
+ (setq minor-mode-alist
+ (cons (list 'senator-minor-mode 'senator-mode)
+ minor-mode-alist)))
- (or (assq 'senator-minor-mode minor-mode-map-alist)
- (setq minor-mode-map-alist
- (cons (cons 'senator-minor-mode senator-mode-map)
- minor-mode-map-alist)))
+ (or (assq 'senator-minor-mode minor-mode-map-alist)
+ (setq minor-mode-map-alist
+ (cons (cons 'senator-minor-mode senator-mode-map)
+ minor-mode-map-alist)))
- ))
+ )
;;;;
;;;; Useful advices
;;;;
-(defun senator-beginning-of-defun ()
+(defun senator-beginning-of-defun (&optional arg)
"Move backward to the beginning of a defun.
-Use semantic tokens to navigate."
- (let ((senator-highlight-found nil)
- (senator-step-at-start-end-token-ids nil)
- (senator-step-at-token-ids '(function)))
- (if (senator-previous-token)
- (beginning-of-line))
- (senator-message nil)))
+Use semantic tokens to navigate.
+ARG is the number of tokens to navigate (not yet implemented)."
+ (let* ((senator-highlight-found nil)
+ ;; Step at beginning of next token with id specified in
+ ;; `senator-step-at-token-ids'.
+ (senator-step-at-start-end-token-ids t)
+ (token (senator-previous-token)))
+ (when token
+ (if (= (point) (semantic-token-end token))
+ (goto-char (semantic-token-start token)))
+ (beginning-of-line))
+ (working-message nil)))
-(defun senator-end-of-defun ()
+(defun senator-end-of-defun (&optional arg)
"Move forward to next end of defun.
-Use semantic tokens to navigate."
+Use semantic tokens to navigate.
+ARG is the number of tokens to navigate (not yet implemented)."
(let* ((senator-highlight-found nil)
- (senator-step-at-start-end-token-ids '(function))
- (senator-step-at-token-ids '(function))
+ ;; Step at end of next token with id specified in
+ ;; `senator-step-at-token-ids'.
+ (senator-step-at-start-end-token-ids t)
(token (senator-next-token)))
(when token
(if (= (point) (semantic-token-start token))
@@ -1009,7 +1705,7 @@
(skip-chars-forward " \t")
(if (looking-at "\\s<\\|\n")
(forward-line 1)))
- (senator-message nil)))
+ (working-message nil)))
(defun senator-narrow-to-defun ()
"Make text outside current defun invisible.
@@ -1029,8 +1725,8 @@
Use semantic tokens to navigate."
(interactive)
(let ((origin (point))
- (end (progn (senator-end-of-defun) (point)))
- (start (progn (senator-beginning-of-defun) (point))))
+ (end (progn (senator-end-of-defun) (point)))
+ (start (progn (senator-beginning-of-defun) (point))))
(goto-char origin)
(push-mark (point))
(goto-char end) ;; end-of-defun
@@ -1042,14 +1738,14 @@
"Move backward to the beginning of a defun.
If semantic tokens are available, use them to navigate."
(if (and senator-minor-mode (interactive-p))
- (senator-beginning-of-defun)
+ (senator-beginning-of-defun (ad-get-arg 0))
ad-do-it))
(defadvice end-of-defun (around senator activate)
"Move forward to next end of defun.
If semantic tokens are available, use them to navigate."
(if (and senator-minor-mode (interactive-p))
- (senator-end-of-defun)
+ (senator-end-of-defun (ad-get-arg 0))
ad-do-it))
(defadvice narrow-to-defun (around senator activate)
@@ -1076,33 +1772,323 @@
(senator-mark-defun)
ad-do-it))
+(defadvice add-log-current-defun (around senator activate)
+ "Return name of function definition point is in, or nil."
+ (if senator-minor-mode
+ (let ((cd (semantic-current-nonterminal)))
+ (if (member (semantic-token-token cd) '(function variable type))
+ (setq ad-return-value (semantic-token-name cd))
+ ad-do-it))
+ ad-do-it))
+
+;;;;
+;;;; Token Cut & Paste
;;;;
+
+;; To copy a token, means to put a token definition into the token
+;; ring. To kill a token, put the token into the token ring AND put
+;; the body of the token into the kill-ring.
+;;
+;; To retrieve a killed token's text, use C-y (yank), but to retrieve
+;; the token as a reference of some sort, use senator-yank-token.
+
+(defvar senator-token-ring (make-ring 20)
+ "Ring of tokens for use with cut and paste.")
+
+(defun senator-insert-foreign-token-default (token tokenfile)
+ "Insert TOKEN from a foreign buffer into the current buffer.
+This is the default behavior for `senator-insert-foreign-token'.
+Assumes the current buffer is a language file, and attempts to insert
+a prototype/function call.
+Argument TOKENFILE is the file from wence TOKEN came."
+ ;; Long term goal:
+ ;; Have a mechanism for a tempo-like template insert for the given
+ ;; token.
+ (insert (semantic-prototype-nonterminal token)))
+
+(defun senator-insert-foreign-token (token tokenfile)
+ "Insert TOKEN from a foreign buffer into the current buffer.
+TOKEN will have originated from TOKENFILE.
+This function is overridable with the symbol `insert-foreign-token'."
+ (if (or (not token) (not (semantic-token-p token)))
+ (signal 'wrong-type-argument (list token 'semantic-token-p)))
+ (let ((s (semantic-fetch-overload 'insert-foreign-token)))
+ (if s (funcall s token tokenfile)
+ (senator-insert-foreign-token-default token tokenfile))
+ (message (semantic-summarize-nonterminal token))))
+
+(defun senator-copy-token ()
+ "Take the current token, and place it in the token ring."
+ (interactive)
+ (senator-parse)
+ (let ((ct (senator-current-token)))
+ (ring-insert senator-token-ring (cons ct (buffer-file-name)))
+ (message (semantic-summarize-nonterminal ct))
+ ct))
+
+(defun senator-kill-token ()
+ "Take the current token, place it in the token ring, and kill it.
+Killing the token removes the text for that token, and places it into
+the kill ring. Retrieve that text with \\[yank\\]."
+ (interactive)
+ (let ((ct (senator-copy-token))) ;; this handles the reparse for us.
+ (kill-region (semantic-token-start ct)
+ (semantic-token-end ct))))
+
+(defun senator-yank-token ()
+ "Yank a token from the token ring.
+The form the token takes is differnet depending on where it is being
+yanked to."
+ (interactive)
+ (or (ring-empty-p senator-token-ring)
+ (let ((tok (ring-ref senator-token-ring 0)))
+ (senator-insert-foreign-token (car tok) (cdr tok)))))
+
+(defun senator-copy-token-to-register (register &optional kill-flag)
+ "Copy the current token into REGISTER.
+Optional argument KILL-FLAG will delete the text of the token to the
+kill ring."
+ (interactive "cToken to register: \nP")
+ (let ((ct (senator-current-token)))
+ (set-register register (cons ct (buffer-file-name)))
+ (if kill-flag
+ (kill-region (semantic-token-start ct)
+ (semantic-token-end ct)))))
+
+(defadvice insert-register (around senator activate)
+ "Insert contents of register REGISTER as a token.
+If senator is not active, use the original mechanism."
+ (let ((val (get-register (ad-get-arg 0))))
+ (if (and senator-minor-mode (interactive-p)
+ (listp val) (semantic-token-p (car val)))
+ (senator-insert-foreign-token (car val) (cdr val))
+ ad-do-it)))
+
+(defadvice jump-to-register (around senator activate)
+ "Insert contents of register REGISTER as a token.
+If senator is not active, use the original mechanism."
+ (let ((val (get-register (ad-get-arg 0))))
+ (if (and senator-minor-mode (interactive-p)
+ (listp val) (semantic-token-p (car val)))
+ (progn
+ (find-file (cdr val))
+ (goto-char (semantic-token-start (car val))))
+ ad-do-it)))
+
+;;;;
+;;;; Suggestion mode
+;;;;
+
+;; Since eldoc kicks butt for Emacs Lisp mode, this advice will let
+;; us do eldoc like things for other languages.
+(eval-when-compile (require 'eldoc)
+ (require 'semantic-ctxt))
+
+(defcustom senator-eldoc-use-color (or (featurep 'xemacs)
+ (>= emacs-major-version 21))
+ "*Use color for eldoc strings generated with semantic.
+Colored text can be printed with the message command with some
+versions of Emacs."
+ :group 'senator
+ :type 'boolean)
+
+(defun senator-eldoc-print-current-symbol-info-default ()
+ "Return a string message describing the current context."
+ (let ((sym (semantic-ctxt-current-symbol))
+ found)
+ (if sym
+ (progn
+ (setq found (if semanticdb-current-database
+ (cdr
+ (car (semanticdb-find-nonterminal-by-name
+ (car sym) nil t)))
+ (semantic-find-nonterminal-by-name
+ (car sym) (current-buffer) t)))
+ (and (not found)
+ (semantic-flex-keyword-p (car sym))
+ (setq found (semantic-flex-keyword-get (car sym) 'summary)))
+ ))
+ (or found
+ (progn
+ (setq sym (semantic-ctxt-current-function))
+ (if sym
+ (progn
+ (setq found (if semanticdb-current-database
+ (cdr
+ (car (semanticdb-find-nonterminal-by-name
+ (car sym) nil t)))
+ (semantic-find-nonterminal-by-name
+ (car sym) (current-buffer) t)))
+ (and (not found)
+ (semantic-flex-keyword-p (car sym))
+ (setq found (semantic-flex-keyword-get (car sym) 'summary)))
+ ))
+ ))
+ found))
+
+(defun senator-eldoc-print-current-symbol-info ()
+ "Print information using `eldoc-message' while in function `eldoc-mode'.
+You can override the info collecting part with `eldoc-current-symbol-info'."
+ (let* ((s (semantic-fetch-overload 'eldoc-current-symbol-info))
+ found)
+
+ (if s (setq found (funcall s))
+ (setq found (senator-eldoc-print-current-symbol-info-default)))
+
+ (eldoc-message
+ (cond ((stringp found)
+ found)
+ ((semantic-token-p found)
+ (semantic-summarize-nonterminal found nil senator-eldoc-use-color))
+ (t nil)
+ ))))
+
+(defadvice eldoc-print-current-symbol-info (around senator activate)
+ "Enable ELDOC in non Emacs Lisp, but semantic-enabled modes."
+ (if (eq major-mode 'emacs-lisp-mode)
+ ad-do-it
+ (if (semantic-active-p)
+ (if (eldoc-display-message-p)
+ (senator-eldoc-print-current-symbol-info))
+ (eldoc-mode -1))))
+
+;;; HIPPIE EXPAND
+;;
+;; Senator has a nice completion mechanism. Use it to add a new
+;; hippie expand try method.
+
+(eval-when-compile (require 'hippie-exp))
+
+(defadvice hippie-expand (before senator activate)
+ "Add senator completion to hippie expand try method.
+This setting is local to Semantic enabled buffers."
+ (or (not (semantic-active-p))
+ (memq #'senator-try-expand-semantic
+ hippie-expand-try-functions-list)
+ (set (make-local-variable 'hippie-expand-try-functions-list)
+ (cons #'senator-try-expand-semantic
+ (default-value 'hippie-expand-try-functions-list)))))
+
+(defun senator-try-expand-semantic (old)
+ "Attempt inline completion at the cursor.
+Use Semantic, or the semantic database to look up possible
+completions. The argument OLD has to be nil the first call of this
+function. It returns t if a unique, possibly partial, completion is
+found, nil otherwise."
+ (require 'senator)
+ (if (semantic-active-p)
+ (let (symstart)
+ ;; If the hippie says so, start over.
+ (if (not old)
+ (if (setq symstart (senator-current-symbol-start))
+ (progn
+ (he-init-string symstart (point))
+ (setq senator-last-completion-stats nil))))
+ ;; do completion with senator's mechanism.
+ (if (or old symstart)
+ (let ((ret (senator-complete-symbol t)))
+ (cond (ret
+ ;; Found a new completion, update the end marker.
+ (set-marker he-string-end (point))
+ ;; Update the tried table so other hippie expand
+ ;; try functions can see whether an expansion has
+ ;; already been tried.
+ (setq he-tried-table (cons ret he-tried-table)))
+ ;; No more completion
+ (old
+ ;; Reset the initial completed string for other
+ ;; hippie-expand try functions.
+ (he-reset-string)))
+ ret)))))
+
+;;;;
;;;; Using semantic search in isearch mode
;;;;
-(defun senator-isearch-search-handler ()
- "Return the actual search function used by `isearch-search'.
-If `senator-isearch-semantic-mode' is nil it delegates to the
-function `isearch-default-search-handler'. Otherwise it returns one
-of the functions `senator-search-forward', `senator-search-backward',
-`senator-word-search-forward', `senator-word-search-backward',
-`senator-re-search-forward' or `senator-re-search-backward' depending
-on current values of the variables `isearch-forward', `isearch-regexp'
-and `isearch-word'."
- (if senator-isearch-semantic-mode
- (cond (isearch-word
- (if isearch-forward
- 'senator-word-search-forward
- 'senator-word-search-backward))
- (isearch-regexp
- (if isearch-forward
- 'senator-re-search-forward
- 'senator-re-search-backward))
- (t
- (if isearch-forward
- 'senator-search-forward
- 'senator-search-backward)))
- (isearch-default-search-handler)))
+;;; Compatibility
+(cond
+ (;; GNU Emacs 21.0 lazy highlighting
+ (fboundp 'isearch-lazy-highlight-cleanup)
+
+ ;; Provide this function used by senator
+ (defun senator-lazy-highlight-update ()
+ "Force lazy highlight update."
+ (funcall 'isearch-lazy-highlight-cleanup t)
+ (set 'isearch-lazy-highlight-last-string nil)
+ (setq isearch-adjusted t)
+ (isearch-update))
+
+ ) ;; End of GNU Emacs 21 lazy highlighting
+
+ (;; XEmacs 21.4 lazy highlighting
+ (fboundp 'isearch-highlight-all-cleanup)
+
+ ;; Provide this function used by senator
+ (defun senator-lazy-highlight-update ()
+ "Force lazy highlight update."
+ (funcall 'isearch-highlight-all-cleanup)
+ (set 'isearch-highlight-last-string nil)
+ (setq isearch-adjusted t)
+ (isearch-update))
+
+ ) ;; End of XEmacs 21.4 lazy highlighting
+
+ (;; GNU Emacs 20 lazy highlighting via ishl
+ (fboundp 'ishl-cleanup)
+
+ ;; Provide this function used by senator
+ (defun senator-lazy-highlight-update ()
+ "Force lazy highlight update."
+ (funcall 'ishl-cleanup t)
+ (set 'ishl-last-string nil)
+ (setq isearch-adjusted t)
+ (isearch-update))
+
+ ) ;; End of GNU Emacs 20 lazy highlighting
+
+ (t ;; No lazy highlighting
+
+ ;; Ignore this function used by senator
+ (defalias 'senator-lazy-highlight-update 'ignore)
+
+ )
+
+ ) ;; End of compatibility stuff
+
+(defmacro senator-define-search-advice (searcher)
+ "Advice the built-in SEARCHER function to do semantic search.
+That is to call the Senator counterpart searcher when variables
+`isearch-mode' and `senator-isearch-semantic-mode' are non-nil."
+ (let ((senator-searcher (intern (format "senator-%s" searcher))))
+ `(defadvice ,searcher (around senator activate)
+ (if (and isearch-mode senator-isearch-semantic-mode
+ ;; The following condition ensure to do a senator
+ ;; semantic search on the `isearch-string' only!
+ (string-equal (ad-get-arg 0) isearch-string))
+ (unwind-protect
+ (progn
+ ;; Temporarily set `senator-isearch-semantic-mode' to
+ ;; nil to avoid an infinite recursive call of the
+ ;; senator semantic search function!
+ (setq senator-isearch-semantic-mode nil)
+ (setq ad-return-value
+ (funcall ',senator-searcher
+ (ad-get-arg 0) ; string
+ (ad-get-arg 1) ; bound
+ (ad-get-arg 2) ; no-error
+ (ad-get-arg 3) ; count
+ )))
+ (setq senator-isearch-semantic-mode t))
+ ad-do-it))))
+
+;; Advice the built-in search functions to do semantic search when
+;; `isearch-mode' and `senator-isearch-semantic-mode' are on.
+(senator-define-search-advice search-forward)
+(senator-define-search-advice re-search-forward)
+(senator-define-search-advice word-search-forward)
+(senator-define-search-advice search-backward)
+(senator-define-search-advice re-search-backward)
+(senator-define-search-advice word-search-backward)
(defun senator-isearch-toggle-semantic-mode ()
"Toggle semantic searching on or off in isearch mode.
@@ -1115,7 +2101,7 @@
(if isearch-mode
;; force lazy highlight update
(senator-lazy-highlight-update)
- (senator-message "Isearch semantic mode %s"
+ (working-message "Isearch semantic mode %s"
(if senator-isearch-semantic-mode
"enabled"
"disabled")))))
@@ -1125,11 +2111,12 @@
(put 'senator-isearch-toggle-semantic-mode 'isearch-command t)
;; Keyboard shortcut to toggle semantic search in isearch mode.
-(define-key isearch-mode-map [(control ?,)] 'senator-isearch-toggle-semantic-mode)
+(define-key isearch-mode-map
+ [(control ?,)]
+ 'senator-isearch-toggle-semantic-mode)
(defun senator-isearch-mode-hook ()
"Isearch mode hook to setup semantic searching."
- (setq isearch-search-handler-provider #'senator-isearch-search-handler)
(or senator-minor-mode
(setq senator-isearch-semantic-mode nil))
(senator-show-status))
Index: xemacs-packages/semantic/sformat.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/semantic/sformat.el,v
retrieving revision 1.4
diff -u -r1.4 sformat.el
--- xemacs-packages/semantic/sformat.el 2001/02/20 03:23:44 1.4
+++ xemacs-packages/semantic/sformat.el 2001/08/15 05:28:26
@@ -46,7 +46,7 @@
;; and substring) to quickly scan over plain text, and then a slower
;; character by character scan to handle tokens.
-;;; $Id: sformat.el,v 1.4 2001/02/20 03:23:44 youngs Exp $
+;;; $Id: sformat.el,v 1.3 2000/05/06 01:34:32 zappo Exp $
;;
;; History
;;
Index: xemacs-packages/semantic/working.el
===================================================================
RCS file: /usr/CVSroot/XEmacs/packages/xemacs-packages/semantic/working.el,v
retrieving revision 1.3
diff -u -r1.3 working.el
--- xemacs-packages/semantic/working.el 2000/10/19 02:59:40 1.3
+++ xemacs-packages/semantic/working.el 2001/08/15 05:28:27
@@ -1,9 +1,9 @@
;;; working --- Display a "working" message in the minibuffer.
-;;; Copyright (C) 1998, 1999, 2000 Eric M. Ludlam
+;;; Copyright (C) 1998, 1999, 2000, 2001 Eric M. Ludlam
;; Author: Eric M. Ludlam <zappo(a)gnu.org>
-;; Version: 1.3
+;; Version: 1.4
;; Keywords: status
;; This program is free software; you can redistribute it and/or modify
@@ -142,7 +142,8 @@
(const working-percent-bar-display)
(const working-bubble-display)
(const working-bubble-percent-display)
- (const working-celeron-percent-display)))
+ (const working-celeron-percent-display)
+ (const nil)))
(defcustom working-status-dynamic-type 'working-celeron-display
"*Function used to display an animation indicating progress being made.
@@ -158,8 +159,16 @@
(const working-spinner-display)
(const working-dotgrowth-display)
(const working-celeron-display)
- (const working-bounce-display)))
+ (const working-bounce-display)
+ (const nil)))
+(defcustom working-percentage-step 2
+ "*Percentage display step.
+A number representing how large a step must be taken when working a
+percentage display. A number such as `2' means `2%'."
+ :group 'working'
+ :type 'number)
+
;;; Variables used in stages
;;
(defvar working-message nil
@@ -168,16 +177,38 @@
"Done string stored when in a status loop.")
(defvar working-ref1 nil
"A reference number used in a status loop.")
+(defvar working-last-percent 0
+ "A reference number used in a status loop.")
;;; Programmer functions
;;
+(defun working-message-emacs (&rest args)
+ "Print but no log a one-line message at the bottom of the screen.
+See the function `message' for details on ARGS."
+ (let ((message-log-max nil)) ;; No logging
+ (apply 'message args)))
+
+(defun working-message-xemacs (&rest args)
+ "Print but no log a one-line message at the bottom of the screen.
+See the function `message' for details on ARGS."
+ (let ((log-message-filter-function #'ignore)) ;; No logging
+ (apply 'message args)))
+
+(eval-and-compile
+ (defalias 'working-message
+ (if (boundp 'log-message-filter-function)
+ 'working-message-xemacs
+ 'working-message-emacs))
+ )
+
(defmacro working-status-forms (message donestr &rest forms)
"Contain a block of code during which a working status is shown.
MESSAGE is the message string to use and DONESTR is the completed text
to use when the functions `working-status' is called from FORMS."
`(let ((working-message ,message)
(working-donestring ,donestr)
- (working-ref1 0))
+ (working-ref1 0)
+ (working-last-percent 0))
,@forms))
(put 'working-status-forms 'lisp-indent-function 2)
@@ -225,25 +256,28 @@
percentile.
Additional ARGS are passed to fill on % elements of MESSAGE from the
macro `working-status-forms'."
- (let* ((p (or percent
- (floor (* 100.0 (/ (float (point)) (point-max))))))
- (m1 (apply 'format working-message args))
- (m2 (funcall working-status-percentage-type (length m1) p))
- (message-log-max))
- (message "%s%s" m1 m2)))
-
+ (when working-status-percentage-type
+ (let ((p (or percent
+ (floor (* 100.0 (/ (float (point)) (point-max)))))))
+ (if (or (eq p t)
+ (> (- p working-last-percent) working-percentage-step))
+ (let* ((m1 (apply 'format working-message args))
+ (m2 (funcall working-status-percentage-type (length m1) p)))
+ (working-message "%s%s" m1 m2)
+ (setq working-last-percent p))))))
+
(defun working-dynamic-status (&optional number &rest args)
"Called within the macro `working-status-forms', show the status.
If NUMBER is nil, then increment a local NUMBER from 0 with each call.
If it is a number or float, use it as the raw percentile.
Additional ARGS are passed to fill on % elements of MESSAGE from the
macro `working-status-forms'."
- (let* ((n (or number working-ref1))
- (m1 (apply 'format working-message args))
- (m2 (funcall working-status-dynamic-type (length m1) n))
- (message-log-max))
- (message "%s%s" m1 m2)
- (setq working-ref1 (1+ working-ref1))))
+ (when working-status-dynamic-type
+ (let* ((n (or number working-ref1))
+ (m1 (apply 'format working-message args))
+ (m2 (funcall working-status-dynamic-type (length m1) n)))
+ (working-message "%s%s" m1 m2)
+ (setq working-ref1 (1+ working-ref1)))))
;;; Utilities
;;
But I don't think I have write access anymore...
andy