TOC PREV NEXT INDEX DOC LIST MASTER INDEX



Extensions to Cshell

This chapter describes the Apex Shell scripting language extensions to cshell. The following topics are covered in this chapter:


Functions vs. Procedures

Under Apex Shell, commands are either procedures or functions. Procedures are invoked in the same manner as cshell commands, and all standard cshell commands are procedures.

Functions are commands that return a string value. The return value is captured using the command substitution syntax `...`. Procedures and UNIX program calls may also be called with this syntax in order to capture return values.

For example:

This syntax does not allow nested function calls. However, nested function calls can be handled with a set of the nested call to a variable and a variable dereference in its place.

Calls to user-defined functions where the result is not of interest are written as one-line statements with the function name followed by the actual parameters. However, all other function calls require the `...` syntax.


User-Defined Functions

Apex Shell supports user-defined functions with the paired function and end_function keywords.

Within dialog box script files, keywords begin with the % character:

Within a function, parameters are referenced as $1, $2, etc. However, $argv is not reset within functions. Rather, the new for construct and the built-in functions parameter and parm_count can be used to handle variable argument lists.

The argument to the return statement is the return string for the function. If no return is executed, or no value is given, the function returns the null string.


For Loop

Apex Shell provides a c-like for statement in the following form:

<test> represents a cshell boolean expression. For example:


Object Types

Within cshell, depending on how you look at, there is basically one data type - string. All arguments and results are expressed using strings. Integers and booleans are conceptually present but are implemented as strings. Wordlists are somewhat like flexible arrays of strings.

Apex Shell extends this concept to provide new data types. The new data types facilitate manipulating data and providing direct access to Apex and Summit objects.

Object Declarations

To declare an object of one of these types the statement looks like:

Examples:

For anyone familiar with C++, it's like a variable declaration with a constructor call with arguments, without the parens, commas, and semicolon.

Some object declarations always require arguments, for example a pathname denoting a view. For others, arguments are not required, for example, declaring a set and taking the default characteristics. There may be declaration options for either kind, for example, a string_map can be created so that the domain values are always uppercased.

The name space of object variables is disjoint from shell variables. Redeclaring an object variable with the same name as an existing one frees any storage associated with the existing one and creates the new one.

Object variables have the same kind of dynamic scope as shell variables. Once they are declared they are visible everywhere. They remain in existence until the script terminates. However, there is also an operation to undeclare an object if one wants to free any space it is using before the script terminates.

For some types, an object can be declared and initialized with the value of another object of that type (like a C++ copy constructor). To do this the name of the other object is given as the single argument in the object declaration, For example,

There is support for static variables. An object declaration can be preceded by the word static. Such a declaration is processed only once when it is first executed.

Operation Syntax

Each object type has a set of operations associated with it. These operations are strictly classified as either functions or procedures.

Procedural operation calls are written as one-line statements. Functional operation calls are written using the backquote notation.

To specify the object that an operation is being performed on, we use the traditional dot notation:

Examples:

The name before the dot can be the literal name from an object declaration or can be a shell variable or parameter dereference whose string value is the name of an object.

All functional operations return a string value (which may be then processed as an integer or boolean in the usual way if it is one of those).

There are a few operations which construct an object of one of these new types, give it an internally generated name, and return that name as the operation's string value.

This is analogous to a function in a programming language which allocates an object and returns as its value a pointer to that object.

For example, there is an operator on "view" objects which returns a String_Map of the view's switches.

Passing the name of an object to a user-defined function is similar, For example, within the function, call operations as:

Type Operations

To see the set of operations available for a type:

This will print out the names of the functions and procedures specific to that type.

For example, in an xterm you can type

to see the operations specific to the type String_Map. In addition to the operations that are specific to a type there are some operations that are available for all or most types.

The function "name" returns the name or handle of an object if that notion is meaningful for the particular type. If not, the null string is returned:

The function Type_Name" returns the name of the type of the object.

The procedure "show" displays an image of the object. For some types this is just the name:

Some types support assignment. The statement to assign an object a2 to an object a1 looks like:

To delete space and undeclare an object the procedure is called "destroy":

Required Parameters

Each operation has a required set of parameters.

Given the dynamic nature of operation invocation (for example, $m.$op $a might be a call to string_map.bind with a missing second argument) checks for argument counts and validity are done at run time.

Erroneous parameter counts in object declarations or operation invocations cause the script to terminate at the line on which they occur, just like, No match, etc.

If an operation wants to detect an error but allow the user to deal with it, there is associated with each object a Condition which records the result of the last operation.

The fail and error functions can be used to detect and show error conditions.

For example


Preprocessing

Apex Shell supports the c-like preprocessing directives #include, #ifdef, and #define. The values tested in #ifdef must be #defined or environment variables.

Preprocessing must be explicitly enabled by the -P option when invoking apex_shell.

dlisp Insertion

At start-up, the Apex Shell interpreter compiles the script into a tree-structured, internal representation of (abstract) instructions. Each instruction consists of an operation with optional arguments. Each argument may itself be an instruction.

There is another scripting language, dlisp, which gets compiled into this same representation. Instructions in dlisp map one-to-one onto machine instructions.

Apex Shell allows dlisp code to be inserted in Apex Shell scripts. Any one-line statement that starts with < and ends with > is parsed as a dlisp statement.


Editor Operations

Within menu_item scripts, the substitution variables that are written as <SELECTION>, for example, in the separate-process scripting mechanisms are written within an Apex Shell script as $SELECTION

These values are resolved when the statement containing them is executed. This is in contrast to the separate-process actions where all occurrences of these prompts are presubstituted before the action is run.

An action is specified as being written in Apex Shell by placing the phrase shell apex on the "options" line.

Actions can also be written in dlisp, in which case the "options" line says, shell dlisp.

All of the former action facilities continue to exist.

Apex Shell should only be used for a menu action if the action will finish in a bounded, relatively short time.

Apex and Summit servers are single threaded.

While a server is processing a menu_item Apex Shell action it will not respond to any other events. So, for example, if while testing a new action, it goes into an infinite loop you'll have to kill the server and restart it.

Unlike the separate-process actions, actions written in Apex Shell do not register with the Jobs window.

Within Apex Shell menu_item actions, the statement

perform <operation_name> <arguments>

does the Window_Perform operation on the given window

The function

query <operation_name> <arguments>

does the Window_Query operation on the given window


Dialog Operations

The dialog specific operations that can be written in Apex Shell are largely the same as the ones described in the dlisp README file in the dialogs subdirectory of product release area ($APEX_HOME/dialogs/README)

You just drop the dlisp brackets, use spaces instead of commas, be careful about unwanted filename expansions, and carefully deal with quote characters, as always with any shell.

Display a line in the output window within a dialog script with the echo statement.

The dialog operations which take a widget as an argument are specially set up to have that parameter implicitly quoted. So you can write

without having to put quotes around the first argument.

The .dlisp file parser, by looking at the body of a program or function, decides whether it is written in dlisp or Apex Shell and parses it accordingly. The two formats can be used in the same file.


Limitations


Rational Software Corporation 
http://www.rational.com
support@rational.com
techpubs@rational.com
Copyright © 1993-2001, Rational Software Corporation. All rights reserved.
TOC PREV NEXT INDEX DOC LIST MASTER INDEX TECHNOTES APEX TIPS