\begindata{text,10971136} \textdsversion{12} \template{default} \define{global

advertisement
\begindata{text,10971136}
\textdsversion{12}
\template{default}
\define{global
}
\define{concat
}
\define{sans
}
\flushright{16 July 1993 }
\majorheading{Ness Hacker's Guide}
\center{by Wilfred J. Hansen}
\indent{\flushright{\smaller{_________________________________
Andrew Consortium
Carnegie Mellon University
_________________________________
}}
Ness is a programming language for the Andrew ToolKit. With it,
documents
can be processed and can even contain active elements controlled by Ness
scripts. The language features an innovative substring algebra for
string
processing.
This document is intended for people who want to do unusual things with
Ness. It describes how to extend the keyboard and menus with Ness, how
to
call methods and class procedures from Ness, how to access instance
variables of objects, and how to utilize Ness from C code.
For a description of the other Ness documents, see the \bold{Ness User's
Manual}.
1. NessUseDialogBoxInsteadOfWarning
2. Accessing ATK objects: methods, class procedures, and instance
variables
3. Redefining keys and menus for ATK Applications
4. Calling Ness from C code
5. Ness system files
}\smaller{\
\begindata{bp,10693824}
\enddata{bp,10693824}
\view{bpv,10693824,70,0,0}
}
Copyright IBM Corporation 1988, 1989 - All Rights Reserved
Copyright Carnegie Mellon University 1993 - All Rights
Reserved\smaller{
\smaller{
$Disclaimer:
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all copies and that
both that copyright notice, this permission notice, and the following
disclaimer appear in supporting documentation, and that the names of
IBM, Carnegie Mellon University, and other copyright holders, not be
used in advertising or publicity pertaining to distribution of the
software
without specific, written prior permission.
IBM, CARNEGIE MELLON UNIVERSITY, AND THE OTHER COPYRIGHT HOLDERS
DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT
SHALL IBM, CARNEGIE MELLON UNIVERSITY, OR ANY OTHER COPYRIGHT HOLDER
BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
OF THIS SOFTWARE.
$
$Log: nesshack.doc,v $
Revision 1.5
1993/07/17
04:31:45
wjh
remove notes about future developments
modernize layout, copyrights, etc.
\begindata{bp,10694016}
\enddata{bp,10694016}
\view{bpv,10694016,71,0,0}}}
\section{1. Ness preference options}
Ness supports two preference options.
When Ness scripts appear in documents or applications, they are normally
surrounded with a warning text describing the dangers of freely using
scripts from others. You may prefer to have a dialog box appear instead
of
the warning message. To get this the preference option is
"NessUseDialogBoxInsteadOfWarning". To activate it, put in your
~/preferences file the line
\leftindent{*.NessUseDialogBoxInsteadOfWarning: on}
When you have installed this option, any Ness you encounter in documents
or
applications will be announced to you in a dialog box with four options:
\leftindent{\sans{\bold{Ness script here.
it
from?
Do you trust the user you got
\leftindent{Cancel - Keep Ness script inactive
Help - Add warning text to script
Scan - Check for dangerous statements
Empower - I trust the source of this script}}}}
If you just want to eyeball the script, choose the first option and
scroll
through the Ness inset. When you are ready to compile, you can choose
the
compilation options from the Ness menu.
Another preference option is NessPath. The value of this preference is a
comma separated list of directories to be searched for library files.
The
default value is
*.NessPath:/usr/andrew/lib/ness
Incidentally: These directories are scanned once when Ness is initiated
in
a process. If new files are later added to the library, Ness will not
learn about them; they will however, be available to proceses started
after they are added.
\section{2. Accessing ATK objects: methods, class procedures, and
instance
variables}
Ness scripts may call functions defined by the ATK "class" preprocessor.
Let <var>, <class>, <method>, and <proc> be identifiers and \italic{obj}
an expression with an object as its value. Then:
To retrieve the value of instance variable <var> of object \italic{obj}
in
class <class> write
<class>_Get<var>(\italic{obj})
and to set the value write
<class>_Set<var>(\italic{obj}, value)
To call
<method>
in
<class>
on object \italic{obj} write
<class>_<method>(\italic{obj}, other parameters)
and to call the classprocedure <proc>
in
<class>
write
<class>_<proc>(parameter list)
Before any of these can operate, the script must declare that it is going
to utilize functions defined in class. This is done by writing a comment
saying (exactly):
--$enable class access
\section{3. Redefining keys and menus for ATK Applications}
During initialization, each ATK application reads ~/.atkinit or
~/.<applicationname>init if it exists. This file can contain
specifications that redefine the keys and menus provided for various
objects when viewed by the application. Ness can be used to write the
code
that is executed for these specifications.
The first step is to have the ness processor available during
initialization. This is done by adding to the .XYZinit file the line
load ness
which searches the CLASSPATH for ness.do and loads it. As it is loaded,
Ness installs in the proctable the entry ness-load, which is used to load
and compile Ness files which can themselves define entries in the
proctable.
Once Ness is loaded, the .XYZinit file can utilize ness-load to load
specifications written in Ness:
call ness-load /usr/andrew/lib/wc.n
where the last component of the line is the filename of the Ness program.
(This is Ness source code as text; it is not a Ness object.) Note that
no security is applied; if your .XYZinit file loads a ness script it is
compiled and its event handlers are activated without asking your
permission.
Ness programs utilize special \bold{extend} and \bold{on} syntax to bind
key sequences and menu options to Ness code. The script extends the
special name "view:\italic{viewname}", where \italic{viewname} is the
name
of a view class. To apply to all views, the string can be "view:view".
Within such an extend block, event specifications are acceptable for
\bold{on keys} and \bold{on menu}. This must be compiled BEFORE the
window
is created, so it is best done from
call ness-load <filename>
in .atkinit or one of your other .XYZinit files.
For example, here is the section of /usr/andrew/lib/ness/wc.n which
establishes a menu option for counting words:
\example{\smaller{
extend "view:textview"\leftindent{
on menu"Search/Spell,Count Words"\leftindent{
wc_showcount()}
end menu}
end extend}}
It is this event specification which is invoked by the lines shown above
for the .XYZinit file. (As of this writing, this file contains 13993
words.)
\section{4.
Calling Ness from C code}
A program in the C language can construct a Ness object, load it with a
script, and cause its execution. First create a new instance of a ness
object:
\leftindent{ness_New()
Ness. }
returns a struct ness * pointing to a brand new
The Ness object is a subclass of text, so all methods of the text data
object can be used to construct the Ness script.
If an argument is to be passed to the function main(), a pointer to it
must
be stored into the Ness. The pointer must refer to a struct nessmark
value
which provides the text of the argument.
\leftindent{ness_SupplyMarkerArg(ness, markerptr)}
The execution environment for a ness program consists of a defaulttext
value and an arbiter value. The defaulttext is the one the program will
refer to with the predefined variable of the same name. The arbiter is
the
name resolver that Ness will utilize for the \bold{extend} construct and
the inset() function. There are two ways to establish this environment.
Either variable can be set explicitly, or the EstablishViews method can
be
called to set them both.
\leftindent{ness_SetArbiter(ness, arbiterp)
surrounding arbiter.
ness_Set DefaultText(ness, textview)
defaulttext.
Sets the pointer to the
Sets the pointer to the
ness_EstablishViews(ness, child) where the child is some view which is a
child of the appropriate arbiter (or outside all arbiters, in which case
it
gets the default outer arbiter.) This function first sets the arbiter by
scanning up the view tree from the child view. It then uses various
hueristics to determine what is the defaulttext.}
The ness is compiled automatically before Execution, but can be
explicitly
compiled:
\leftindent{ness_Execute(ness, function-name) returns the error list.
The
ness is compiled and execution is initiated by calling the named
function.
By convention, the name is usually "main". If the return value is NULL,
there were no errors.
ness_Compile(ness) returns the error list. The Ness is compiled and not
executed. If the return value is NULL, there were no errors.}
To debug errors, it is preferable to install a nessview (if you have
windows, a call to ness_Expose(ness) will usually display the ness).
\leftindent{ness_Expose(ness)
possible.}
Causes the ness to be displayed if
If you want the compilation to check for statements which might damage
the
user's environment, you can set the access level with
ness_SetAccessLevel(nessobject, integer)
where the access levels are defined in ness.ch:
ness_codeRed,
/* do not even compile */
ness_codeOrange, /* give compile errors for all modification ops */
ness_codeYellow, /* give compile errors for file system ops */
ness_codeGreen,
/* prompt before first executing */
ness_codeBlue
/* compile without prompting */
ness_codeUV /* no warningNotice and no dialog box */
When a compilation or execution has errors, a list of them is recorded in
the struct ness object. Your program can manage this list with
ClearError,
NextError, and PreviousError.
ness_ClearErrors(ness)
Removes the list of errors; discards their space.
ness_NextError(ness) returns a struct errornode *. Advances a pointer
and
returns the next errornode on the list. After visiting the last error,
the
next call returns NULL. A subsequent call will return the first error
again.
ness_PreviousError(ness) returns a struct errornode *.
This function is
the same as NexError, but it moves the pointer in the opposite direction.
ness_printerrors(ness, file) returns the number of errors.
errors to file.
Prints the
ness_PrintAllErrors(msg) returns the number of errors found. This
classprocedure prints and counts all the error messages for all nesses in
the process.
\section{5. Ness system files}
The files listed below constitute the installation of Ness.
\bold{/usr/andrew/bin/nessrun}
-
Standalone execution of Ness programs.
\bold{/usr/andrew/lib/ness} - Library of Ness functions; see
nessfunc.doc. Also contains demos (next item).
\bold{/usr/andrew/lib/ness/demos } Ness: A Short Tutorial.
Demonstrations.
See nesstut.doc,
\bold{/usr/andrew/dlib/atk/} - Eleven dynamic objects constitute Ness.
They are listed here with their superclasses
lex.do
()
lexical analyzers; one for each compilation
lexdef.do
()
classes of lexical analyzer; one for each grammar
ness.do
(text)
the Ness compiler and interpreter
nessmark.do (mark)
the implementation of Ness markers
nesssym.do (toksym)
Ness symbol table entries
nessv.do
(scroll)
user interface to ness.do
sym.do
()
toksym.do
(sym) symbol table entries for lex
type.do
(sym) parses .ch files and builds tables
generic symbol table entries
\bold{goodness}
The Imakefile for andrew/atk/ness/objects alos includes the target
'goodness.' This program is identical to 'nessrun' except that in
goodness
many of the dynamic objects are statically linked instead of dynamically
linked. This difference has two effects:
run time: The runtime for nessrun isabout 2 seconds longer than
goodness,
primarily for the dynamic loading and linking.
object module size: The goodness object module is 1411072 bytes
unstripped
and 456704 bytes when stripped. The nessrun module is 1030144 bytes
unstripped and reduces to 362496 when stripped. Here are the sizes of
each:
\leftindent{
% \bold{size ../objects/nessrun}
text
data
221184
bss
dec
139264
hex
22700 383148
5d8ac
% \bold{size ../objects/goodness}
text
data
288768
bss
dec
165888
hex
26756 481412
75884}
The maximum memory during nessrun execution on one program was 247K,
while
it was only 228K for goodness on the same program. It is my guess that
goodness avoids memory fragmentation by the loaded modules.
\enddata{text,10971136}
Download