A GNU Emacs Browser for C++ Code Development
By Nancy Jane Yacko

Introduction

Modern software development projects often result in large and complex
bodies of software. A programmer's task often involves finding existing
parts of the system in order to reuse or modify it. In the case of
object-oriented programming, the task is often iterative, and there is a
strong emphasis on code reuse. Programmers reuse existing classes by making
instances of them and by making subclasses of them. But, the programmer
cannot use this existing code unless he is able to read and understand it.
In order to understand it, he must be able to find it.

In a recent article, Adele Goldberg states that "programs are not readable".
We read programs in order "to learn to write, we read to find information,
and we read in order to rewrite". Tools are needed for "identification,
location, access, and analysis" of the parts of software systems [1]. One
such tool is a browser.

A browser is a program that allows its user to easily find and read various
important program constructs. A browser helps the user learn about the
existing program structures and where and how they are used. Thus it aids
the programmer in developing and maintaining code. The programmer should not
have to go to the effort of remembering the names of files or explicitly
opening them to search for certain constructs. The browser should do this
for him. This thesis describes a browser for C++, an object-oriented
programming language that is rapidly growing in importance.

The C++ Programming Language

C++ is a superset of C that extends C by providing object-oriented
programming constructs [2]. The programmer defines classes as data types.
Such classes have data and operations on that data to which access is
controlled by the class. Hence, classes provide a data abstraction method.
The user may also derive a class from another class. This subclass may
inherit certain properties of the parent class or it may redefine them.  The
operations on the data within a class are done by member functions. Member
functions are declared within a class and have access to private data of the
class. Variables can be defined to be of a particular class. The member
functions of that class can then be used as operations on the objects stored
in the variables.

C++ programmers are interested in many kinds of relationships between
program components. They might want to see where a particular member
function could be called, or which member function a call might involve.
They might want to see what classes are subclasses of a given class. All
these relationships add to the complexity of building a browser.

GNU Emacs

GNU Emacs is a screen-oriented text editor developed by Richard Stallman
[3]. It is customizable by the user. The user may change or set up his own
key bindings and keyboard macros. GNU Emacs is also extensible. The user can
add new commands by writing them in Lisp. The editor runs in real-time and
allows the user to edit multiple files at once using multiple windows. Our
C++ browser is built into GNU Emacs. This makes it portable and provides a
very powerful and flexible user interface.


Investigation

Before embarking upon a design for the browser, some preliminary
investigation was necessary. Several software systems exist which have some
of the functionality desired for the browser. Most are specialized for
languages other than C++ or for program development environments other than
the UNIXtm [4] operating system.

Smalltalk

The object-oriented programming language Smalltalk-80 has a browser as part
of its development environment [5]. Smalltalk has similar constructs to
those of C++. Smalltalk has objects, classes, subclasses, and instances.
Smalltalk "methods" are equivalent to member functions.

The Smalltalk browser has many of the functions desired in a browser. It
allows the user to list classes and display the class hierarchy. The user
may view the definition of a class, instances of a class, and the methods
for a class. The Smalltalk browser has a friendly user interface which
utilizes multiple windows. The browser utilizes a cross reference in order
to locate symbols.

The problem with the Smalltalk browser is that it cannot be used with C++.
The browser is embedded in the programming environment and only works with
Smalltalk. We wanted a browser for C++ that runs in a general programming
environment.

Lynx

Lynx is described by its author as a "toolkit" [6]. It is a hypertext system
which is built into GNU Emacs. With Lynx a user creates explicit links
between chunks of text using GNU Emacs commands. A link contains the name of
a fragment (chunk of text). These links are embedded within the source
itself. When the user "follows" a link, the destination fragment is
displayed in another window.

The problem with using Lynx as the basis for a C++ browser is that since the
links are embedded in the source, building the links is a problem. Large
existing software systems may require hundreds of links. Modifying the code
is undesirable and difficult to implement cleanly.

Cscope

Cscope is a tool for browsing C code [7]. It has a friendly,
screen-oriented, interactive interface. It allows the user to locate and
view code so that the user is better able to learn about it without paging
back and forth through a paper listing. Cscope is designed to make code
maintenance easy. It is intended to be "interfaced" to a text editor so that
the user may make modifications to the code he is viewing. The tool uses a
symbol cross-reference table which is built from the source code. Cscope
provides the user with the ability to list all references to a C symbol. It
also can list all callers of a function and functions called by a function.
The user may edit the file in which a function appears by telling Cscope to
invoke an editor on the appropriate file.

The problem with using Cscope as a C++ browser is that it only works for C.
The program must be modified to work for classes and instances. Also, since
Cscope is a program which is interfaced to a text editor, one must enter and
leave the editor in order to modify the code. A closer relationship to the
editing environment is needed.

Tags

Tags is a facility provided with GNU Emacs [3]. It allows the user to find
and edit the function definitions in a program. It is especially useful when
the program spans several source files. Tags provides commands to facilitate
search or replace in a sequence of related files. The tags commands use
tables called "tags tables" which are built from the source files. One of
several languages which the tags facility supports is C. With tags, the user
specifies a function name and tags opens the appropriate C source file and
places the cursor at the function definition. It also provides the user with
the ability to display a list of all functions matching a regular
expression.

Tags is incomplete as a browser. Although it works on C code, it needs to be
modified in order to browse C++ code. The functionality of tags is limited
to finding function definitions.

Investigation Conclusions

An ideal browser for C++ would combine the power of the Smalltalk browser
with the general functionality of Cscope. It would interface with available
UNIX tools. The C++ browser has been built into GNU Emacs because it is
programmable, readily available, and widely used. Tags is not as powerful as
Cscope, but it is already built into GNU Emacs which gives it a closer
relationship to code development in the target environment. Tags tables are
built by reading the sources and not by modifying them. The
cross-referencing method provided by tags is easily expanded for the desired
C++ functionality.

Using the Browser

The goal of this browser is to allow the user to easily find certain
constructs in related source files without having to remember which file
something is in or where in the file it is located. The browser allows the
user to find function definitions and declarations, function calls and
callers, class definitions, subclasses of a class, and instances of
user-defined types.

How would this browser typically be used? A user would first create a tags
table file from his source files. The tags table file would contain
cross-reference information which could then be used by the browser within
GNU Emacs. A user could look at all instances of a class by issuing the
command to display a list of all such instances found in the current tags
table file. He then may issue the command for showing the next declaration
of an instance. The first time the command is issued, the browser looks for
the first instance from the list. The appropriate file is opened and the
cursor is placed at the instance declaration. Repeating the instance command
will find and display the next instance in the list. The user may cycle
through the whole list in this way. The browser takes care of file changes
and moving the cursor appropriately.

Most of the browser commands can be thought of as being divided into two
categories: those that build a list and those that examine the parts of the
program from the list. Lists can be made of callers of a function,
subclasses of a class, or instances of a class. Each command prompts the
user for one or more names. If the user types a carriage return at a browser
prompt, the browser will use the name located at the current cursor
position. For example, if the user is looking at a function definition and
wants to see all the functions which call this function, the user may place
the cursor at the function name and issue the list of callers command. When
the browser prompts for the name, the user should type a carriage return.

The appendix to this paper describes how to create and maintain tags table
files for a body of C++ code and how to use the browser commands.

Implementation

The GNU Emacs C++ browser was implemented by modifying the tags table
builder program "etags" and the Lisp commands in the file "tags.el". First
the browsing commands were enhanced so that the functionality became similar
to that of Cscope for finding function definitions and function callers.
Then the modifications to etags were done for these new commands. This
involved enhancing the parsing capability of etags for finding functions
calls and changing the format of the tags table file for the new
functionality. Once this was accomplished, similar commands and parsing
changes for classes, instances, and subclasses were implemented.

Tags Table Format

The new functionality for the browser required that the tags table entries
be changed. The tags facility requires a tag name (function name), the line
number, and the character position within the source file. The tag name is
separated from the line number by "^?" (control-?) because it is a character
that is not legal for a tag name in any of the languages supported by tags.
The line number and character position are separated by a comma. The file
name for the tags entries appears in the table once, at the start of the
entries for that file. This file name entry also contains the number of
characters in the tags table until the next file name entry. An example tags
table entry might look like this.
		sort_func^?100,2453

In order to accommodate the new functionality for the browser, some new
fields were added to the entry. In order to distinguish the types of
entries, the entries now contain a marker: "f" for functions, "c" for
classes, or "i" for instances. Another field was also added to each entry.
In the case of a function, the field contains the name of the calling
function. A null caller name indicates a function definition. For classes,
the field contains the name of the class from which this one is derived (the
parent class). A class which is not derived from another will have a null
entry in this field. An instance entry has the name of the user-defined type
in this field. For instances, the field should never be null. An example of
a new format tags table entry might look like this.
		sort_func^?100,2853,f,main

Etags Modifications

The program etags reads a sequence of source files and creates a tags table
file. The program parses C sources and creates an entry for each function
definition it finds. The modifications to etags for the browser included
adding a runstring argument and adding a new parsing routine. In addition to
function definitions, the new parsing routine also finds function calls,
classes, and instances and creates tags table entries in the format just
described. The following sections describe these modifications in detail.

Parsing Changes

The original version of etags used a very simple parsing routine to find
function definitions. This method is not difficult to modify to find
function calls as well. However, it does not lend itself easily to finding
class definitions or determining the class of instances. Instead, a new
parsing routine was added which is based upon the compiler generation tools
"lex" [8] and "yacc" [9].

The lexical analysis for the new parsing routine is generated by describing
the tokens of C++ to lex. Also, whenever an identifier token is recognized,
its name, line number, and character position are saved on a push down stack
for later use by the parsing routine. The token description is given to lex
as input and the result is a C source file called "lex.yy.c". Since the
browser requires the character position of each identifier, the lex output
had to be edited. It normally does not keep track of this information. Each
time a character is read, the character count must be incremented. Since lex
also assumes that the input is coming from the standard input, the input
macro in lex.yy.c was modified so that characters are read from the current
etags input file.

The parsing routine "yyparse" is generated by the compiler generation tool
yacc. The input to yacc is a grammar which describes the strings which are
to be recognized. Since the browser needs to find function definitions,
function calls, class definitions, and instances, grammar productions for
these strings are given. Also, since yacc expects all legal strings to be
described, a set of productions which describes "other" is used to ignore
everything else.

Parsing for functions and classes was not difficult to describe to yacc.
Instances, on the other hand, proved to be much more challenging. Since the
specification of an identifier as a class name may or may not be among the
files that etags is processing, it is not possible to determine which
declarations are instances of a class and which are not. Hence, etags
creates an entry in the tags table for all instances of any user-defined
type.

Another difficulty with parsing for instances is properly handling
initializers in a list of instances. A grammar which adequately describes
instances in all possible forms is complex and requires more than one token
of lookahead. A full grammar and lexical analysis to handle this is very
large and slow. In order to overcome having to essentially compile the C++
sources, a few liberties were taken. First, a set of grammar productions
which handles the most common forms of instance declaration is used. Also,
an error production is given so that other forms will not cause the parser
to quit on a syntax error but will be treated as legal constructs. Finally,
in order to keep initializers from complicating the productions, a routine
is called which skips over the initializer to either the next instance in a
list or to the end of the declaration statement, whichever is appropriate.

Whenever an entry is to be created in the tags table, the identifier
information is contained in the stack. For a function, the stack contains
the function name and the name of the calling function. For a class
definition, the stack contains the class name and the name of the parent
class if there is one. For instances, the stack contains the name of the
user-defined type and one or more instance names.

Other Etags Changes

Etags uses a tree to keep the tags table entries sorted. When a potential
entry is found by the parsing routine, a record is placed in the tree
recursively. A new routine was added to etags which places the proper
information for the new entry format in the tree. Another change was made to
etags in the routine which keeps track of the total size of the entries for
a particular source file. This information is used in the file name entry.
Since the tags table entry size changed, the total size changed also. The
routine which writes the tags table file was also modified for the new entry
format. It also does some extra checking for duplicates so that only the
first call to a function by a caller is recorded.



Browser Command Implementation

The browser commands are implemented in Lisp. The Lisp functions are based
upon those in the "tags.el" file that is distributed with GNU Emacs. The
first task of the implementation was to be able to read and understand the
existing code. This was greatly aided by refering to two sources of GNU
Emacs programming documentation, "The GNU Emacs Lisp Reference Manual" [10]
and "GNU Emacs Programming [11].

The first modifications to "tags.el" (which later became "browse.el")
involved making the existing commands handle the new tags table entry
format. These modifications were mainly in "find-tag" and "tags-apropos".
GNU Emacs editing uses a position called "point". It is the location at
which editing commands will take effect. Point is shown in a window by the
terminal cursor position. The browser commands place point at the
appropriate program component. A brief description of the implementation of
each of the commands follows.

find-tag
	The original version of this command finds a C function definition.
It takes a tag name (function name) as an argument and searches the tags
table file for a matching entry. It opens the source file and places point
at the function definition. In order for "find-tag" to work with the new
tags table format, some additional checking had to added to be sure the
entry was for a function definition. It checks for a function entry with an
empty caller field. The Lisp function was also generalized by adding an
internal argument for field type. That way, the same function may be used in
the implementation of the commands for finding classes and instances.

tags-apropos
	The original "tags-apropos" sequentially searched the tags table
file for all entries that match a regular expression. In order to accomodate
the new tags table entry format, the loop which finds matches was modified
to only pattern match in the first field. Also, the entry type for functions
is now checked before an item is added to the list.

match-tag-and-caller
	This function is used internally by the browser commands and is not
callable by the user. It sequentially searches the tags table file for an
entry which matches a particular tag name field and caller field. If an
entry is found, this function returns the tag name and sets up for a
subsequent call to "open-tag-callerline". Otherwise it returns nil.

open-tag-callerline
	This function finds and opens the source file in which the tag and
caller are located. In order to keep minor changes to the source files from
causing the browser to fail, a search for the tag name is used to position
point. If the tag name is not found in the first search (plus or minus
eighty characters), then the search is repeatedly widened until the tag name
is found or the whole file has been searched.

find-tag-at-caller
	This function finds a function call by a particular caller. It first
prompts the user for the tag name. It then prompts for the name of the
caller. If either of these arguments are defaulted (by typing return only),
the expression on or about point is found and used. The function calls
"match-tag-and-caller". If no entry is found, an error is reported. If an
appropriate entry is found, "open-tag-callerline" is called.  Once point is
placed correctly, the function ensures that subsequent search commands will
use the tag name as the search pattern. In this manner, multiple calls to a
C++ function by the same caller are easily browsed.

find-tag-next-caller
	This function finds the next caller in a list of callers to a
particular function. It first determines if there has been a last caller
recorded by a previous call to this routine. If there is no last caller,
then the appropriate entry is found by calling "match-tag-and-caller" with a
nil caller name. If there is a last caller, the entry for the tag and last
caller is found. Then a call to "match-tag-not-caller" is made. This finds
the next applicable entry in the tags table. "Open-tag-callerline" is called
to place point in the proper source file.

find-last-tag-at-caller
	This function is appropriately called after a command such as
"find-tag" or "find-tag-at-caller" which sets the value of the last tag. It
finds a call to this last function for a particluar caller. The user is
prompted for the caller name. "Match-tag-and-caller" is used to get the tags
table entry for this caller and the last tag. "Open-tag-caller-line" is
called to properly place point.

find-tag-callerlist
	This function builds and displays a list of all callers for a
function. When this function is invoked, a temporary buffer is created into
which is written the caller names from every entry in the tags table which
matches the tag name with a non-null caller field. Since the entries in the
tags table are sorted, this list appears sorted alphabetically as well.

find-class
	This function finds a class definition by locating a tags table
entry of type "class" that contains the class name. The appropriate source
file is opened and the class definition is found using an ever-widening
search in order to place point.

find-instance
	This command finds an instance declaration by finding an "instance"
entry in the tags table that contains the instance name. The appropriate
source file is opened and the instance declaration is found using an
ever-widening search in order to place point.

find-class-other-window
	This function is the same as "find-class" except that when the
source file containing the class is displayed, it is shown in a new window.

find-instance-other-window
	This function is the same as "find-instance" except that the source
file containing the instance is shown in another window.

find-class-subclasslist
	This function is similar to "find-tag-callerlist". It builds a list
of the subclasses of a class. The temporary buffer shows the parent class
name from all tags table entries which are classes with a non-null parent
class field. Since the entries in the tags table are alphabetically sorted,
the list appears sorted also.

find-class-next-subclass
	This function locates the next subclass of a given parent class. It
first determines if there has been a last subclass recorded by a previous
call to this routine. If there is no last subclass, the first class which is
a subclass of the last class is found. If there is a last subclass, then the
entry for the last class and last subclass is found. Then the next entry
which matches the last class is determined. The appropriate source file is
opened and point is placed using an ever-widening search.

find-class-instlist
	This function is similar to "find-tag-callerlist".  It builds a list
of all the instances of this class. The temporary buffer shows the instance
name from all tags table entries which are instances and match the specified
class. Since the entries in the tags table are alphabetically sorted, the
list appears sorted also.

find-class-next-instance
	This function locates the next instance in a list of the instances
of a specified class. It first determines if there has been a last instance
recorded by a previous call to this routine. If there is no last instance,
the first instance of the last class is found. If there is a last instance,
then the entry for the last class and last instance is found. Then the next
instance entry which matches the last class is determined. The appropriate
source file is opened and point is placed using an ever-widening search.

Programming in GNU Emacs

A new GNU Emacs programmer must first learn to use GNU Emacs as an editor.
The GNU Emacs Manual [3] is helpful in this regard but not entirely
adequate. Repeated hands-on experience with the editor is necessary. The
next step for a potential GNU Emacs programmer is to learn how GNU Emacs is
put together. I found that doing an installation of the program was quite
useful. This helped me to understand the various parts of GNU Emacs and
where the parts fit together.

In order to write GNU Emacs Lisp code, I began by reading the existing tags
facility commands. These Lisp functions would have been nearly impossible to
understand had there not been the "GNU Emacs Lisp Reference Manual" [10]. In
spite of the errors and omissions, this document is invaluable. I used the
index extensively to look up the description of the Lisp functions as I
went. However, some of the descriptions could use additional information,
and a table of contents is needed. Another essential tool in writing GNU
Emacs code is the debugger. I found setting "debug-on-error" to be
aggravating since I am a novice user and frequently mistype. However, I did
use "debug-on-entry" for both debugging new code and learning existing code.

GNU Emacs programming is not extremely difficult. It helps to have done some
Lisp programming before. The documentation I used was helpful and is getting
better with each new revision.

Deficiencies

The GNU Emacs C++ browser and the etags program have a few deficiencies. I
believe that these deficiencies do not detract from the usefulness of the
browser. One problem which is evident when one looks at the parser
implementation is in the handling of instance parsing. Due to the way in
which initializers are skipped, function calls within initializers of
instances are not recorded. Another problem is that if a member function is
declared within a class definition which is itself inside a function, the
member function will be recorded as if it were a function call. This is also
due to the fact that the parser does not use a grammar which describes the
whole language.

There are some important commands that are missing in this first
implementation of the browser. One is a command which will display the
entire class hierarchy. This information is present in the tags table file.
It needs to be extracted and displayed. Another command that is needed would
show a list of all the member functions of a class. At present, the user
must go to the class definition to get this information.

Potential Enhancements

The GNU Emacs C++ browser could be enhanced in several ways. More work can
be done on the lex and yacc input so that the parser will recognize all
constructs properly. The difficulty here is to keep the parser efficient so
that etags processing is reasonably fast. Also, unfinished C++ code may not
completely compile. The browser should work for incomplete code. The other
way that the browser can be enhanced is by adding or changing browsing
commands. The current implementation is modelled on the pre-existing
commands. Some of these can be made more useful or more efficient. For
example, the commands which find the next item in a list use a sequential
search to find the last one referenced and then find another applicable
entry. This could be changed so that a list is built of the applicable
entries and a pointer kept to the last one referenced. With an
implementation such as this, new commands such as one for returning to the
previous entry can be easily implemented. Another potential enhancement is
to combine the browser with version control so that the user can browse
previous versions of the system.


Conclusions

The GNU Emacs C++ browser allows a programmer to view and edit programs
easily. It provides the ability to read and edit across multiple files
without forcing the programmer to explicitly open a file and search for what
he wants to see. The power of the browser is that it frees the programmer to
concentrate on the programming task rather than the structure and
organization of his sources files.

Appendix A

Installation

In order to install the C++ Browser, GNU Emacs should already be installed.
The following files are required for the browser.

	etags.c
	lex.yy.c
	y.tab.c
	makefile
	browse.el

The C sources are for producing the program etags.  The makefile should be
used to create it. The browser is based upon the tags facility in GNU Emacs.
This new version of etags is backward compatible with the distributed
version so that it may be overwritten if desired. The file browse.el
contains the commands to be loaded into GNU Emacs. This file should be
placed in the GNU Emacs lisp directory.

The user should make the following addition to his GNU Emacs initialization
file.

(load "browse.el")

This will take care of making the browser commands available and will set up
a key binding.

Creating the Tags Table File

The program etags is used to create and maintain the browser tags table
file. Before the program is run, the user must determine which source files
will be included in the tags table file. The names of these files are given
to the etags program either as absolute path or relative to the directory
from which GNU Emacs will be run. This path information is used by the
browser for finding and opening files, so it is important that the user
decide this first.

To run etags:

	etags -b filename1 filename2 ...

The -b option tells etags to create a browser file with all the appropriate
entries for the source files specified. Etags will also appropriately handle
masks in file names. For example, a browser tags table file for all include
files and sources in the current directory can be created with the following
command.

	etags -b *.h *.c

The result is a file called TAGS in the current working directory. The user
can add another file to an existing TAGS file by running etags in this way.

	etags -ba forgot_one.c

The -a option appends to TAGS in the same manner as the original version of
etags.

It is possible to create and use several tags table files with the browser.
However, it is necessary for the user to change tags table files explicitly.
Once the browser has read a TAGS file, it assumes it should use the same one
unless told to do otherwise. (Refer to the "visit-tags-table" command for
more information.)

Browser Commands

The following descriptions give the default key binding and the equivalent
lisp command name for each of the browser commands. The GNU Emacs tags
commands work exactly as described in the GNU Emacs Manual unless otherwise
specified. ("C-x" refers to control-x.)

C-x T		find-tag-at-caller
	This command takes two arguments- a tag name and a caller name. The
command finds the first call of the function (tag name) in the function
definition of caller name. If the user types RET when prompted for either
argument, the sexpr on or before point is used. The tag name becomes the
default string for C-s searches in order to facilitate finding multiple
calls to tag name within caller name.

C-x N		find-tag-next-caller
	This command assumes that a call to find-tag-callerlist has just
been done. This command finds the function call at the next caller in the
list. If this is the first time this command has been invoked since the list
was shown, the first caller in the list is used. When the end of the list is
reached, the user is told that there are no more. Another subsequent call
will begin at the start of the list again.

			find-last-tag-at-caller
	This command takes the name of a caller function as an argument. The
function tag name from a previous call to find-tag-callerlist, find-tag or
find-tag-next-caller is used as the tag to find at the given caller.

C-x L		find-tag-callerlist
	This command takes a tag name as an argument.  If the user types RET
when prompted for the tag name, the sexpr on or before point is used. The
command displays a list of all callers of tag name found in the tags table
file. This command is the prerequisite to find-tag-next-caller.



C-x C		find-class
	This command takes a single argument - a class name. If the user
types RET when prompted for the class name, the sexpr on or before point is
used. Point is placed at the class definition for class name. Class name may
or may not be a derived class.

C-x I			find-instance
	This command takes a single argument - an instance name. If the user
types RET when prompted for the instance name, the sexpr on or before point
is used. Point is placed at the declaration of instance name as an instance
of a user-defined type.

C-x 4 C-x C	find-class-other-window
	This command is the same as find-class except a new window is opened
and the class definition is displayed in this new window.

C-x 4 C-x I	find-instance-other-window
	This command is the same as find-instance except a new window is
opened and the instance declaration is displayed in this new window.

C-x K 		find-class-subclasslist
	This command takes a class name as an argument.  If the user types
RET when prompted for the class name, the sexpr on or before point is used.
The command displays a list of all subclasses of class name found in the
tags table file. This command is the prerequisite to
find-class-next-subclass.

C-x S		find-class-next-subclass
	This command assumes that a call to find-class-subclasslist has just
been done. This command finds the definition of the next subclass in the
list. If this is the first time this command has been invoked since the list
was shown, the first subclass in the list is used. When the end of the list
is reached, the user is told that there are no more. A subsequent call will
begin at the start of the list.

C-x J			find-class-instlist
	This command takes a class name as an argument.  If the user types
RET when prompted for the class name, the sexpr on or before point is used.
The command displays a list of all instances of type class name found in the
tags table file. This command is the prerequisite to
find-class-next-instance.

C-x M		find-class-next-instance
	This command assumes that a call to find-class-instlist has just
been done. This command finds the next instance declaration of a class in
the list. If this is the first time this command has been invoked since the
list was shown, the first instance in the list is used. When the end of the
list is reached, the user is told that there are no more. A subsequent call
will begin at the start of the list.

References

[1] Adele Goldberg, "Programmer as Reader",
IEEE Software, vol. 4, no. 5, September, 1987

[2] Bjarne Stroustrup, The C++ Programming Language,
AT&T Bell Laboratories, Murray Hill, New Jersey,
Addison-Wesley, Reading, Massachusetts, 1986

[3] Richard Stallman, GNU Emacs Manual, 
sixth edition, version 18, March, 1987

[4] S.R. Bourne, The UNIX System,
AT&T Bell Laboratories,
Addison-Wesley, Reading, Massachusetts, 1983

[5] Adele Goldberg and David Robson, Smalltalk-80: The Language and its 
Implementation, Xerox Palo Alto Research Center,
Addison-Wesley, Reading Massachusetts, 1983

[6] Brian Marick, "Lynx User's Guide",
University Of Illinois at Urbana-Champaign,
unpublished, 1987

[7] Joseph L. Steffen, "Interactive Examination of a C Program with Cscope",
AT&T Bell Laboratories, Naperville, Illinois,
USENIX Association Conference Proceedings,

Dallas, Texas, January, 1985

[8]  M.E. Lesk and E Schmidt, "Lex - A Lexical Analyzer Generator",
Computer Science Technical Report No. 39,
AT&T Bell Laboratories, Murray Hill, New Jersey, 1985

[9]  S.C. Johnson, "Yacc: Yet Another Compiler Compiler",
Computer Science Technical Report No. 32.
AT&T Bell Laboratories, Murray Hill, New Jersey, 1975

[10] Daniel LaLiberte, "GNU Emacs Lisp Reference Manual",
University Of Illinois at Urbana-Champaign,
unpublished, 1987

[11] Robert Krawitz, "GNU Emacs Programming",
unpublished, January,1987

