|
Table of Contents
The Dialer application, when connecting your PC to
a remote host, automatically executes scripts written in the SLANG(TM)
Scripting LANGuage. (SLANG is FTP's easy-to-use front-end for the
more difficult and more powerful language system called TRAC(TM).
The SLANG language is based on the TRAC language.) You can easily
modify the SLANG scripts used by Dialer. Using Dialer, you can write
simple and useful one-line SLANG scripts, or you can create complex
SLANG scripts that execute your own specially-defined functions.
You do not have to use all the features of SLANG to write scripts.
Scripts save connection time by logging your PC in to the remote
host, running applications on the local host, and then disconnecting
your PC automatically.
All SLANG scripts are translated automatically
into TRAC scripts and then they are executed by the TRAC system.
Thus the underlying TRAC system is the engine for all operations
in SLANG. You do not have to know anything about TRAC to use SLANG
or Dialer.
SLANG is able to operate with several scripting
languages. The SLANG system accepts scripts written in SLANG, in
FTP's COMSCRPT and, in TRAC.
Conventions Used
Double quotes are used to make clear to you
as a reader exactly what is being talked about in the explanation.
The quotes are not part of the SLANG syntax and should be discarded
before you put the quoted term into your script. However, if you
do put a quote mark in any SLANG statement, it will be treated as
any other character.
Single quotes mark new terms in SLANG, and wherever
a word has a specially defined meaning or the word or phrase is
to be given special emphasis.
Angle brackets mark the description by, not
the literal use, of a string, such as <str> to indicate
that in this argument, the user is supposed to insert his own string,
rather than "str" being a built-in SLANG term.
Return to Table of Contents.
Overview
This document on the SLANG language covers the
following subjects:
- Variables and Primitives
- I/O Primitives
- Looping and Flow Control Primitives
- Arithmetic Primitives
- Equivalence Primitives
- Miscellaneous Primitives
You will read about the following topics:
- Making your scripts more readable
- Understanding the SLANG syntax
- Understanding that everything in SLANG is
text
- Understanding that SLANG is a macro language
- Understanding how SLANG is interpreted
- Accessing variables and primitives
- Writing scripts with define primitives
- Using Loops in scripts
- Creating a script
- Debugging scripts
Return to Table of Contents
Basic Concepts
The key to writing successful scripts using
SLANG is to understand the underlying concepts upon which SLANG
is based. These key concepts are:
- Is all text.
- Syntax.
- Uses functions.
- Is a macro language.
- Is interpreted.
All is Text
SLANG scripts can transmit, display, store,
or compare anything read over the communications link or anything
that you type at your keyboard. All such content is "text".
Any key you type from your keyboard, any character string, is text
and can be used in SLANG. Your scripts, your typed commands, your
user-defined functions are produced from the keyboard. They are
text. Everything that you do in SLANG is done with text.
The fact that everything in SLANG is done with
text has some unique consequences. SLANG handles equally well both
your modem commands and your data, but it needs to be told clearly
what you want to do. It has two choices: is it text, or is it a
function?
SLANG can deal with the scripts of functions.
It can move, display, or store them as text strings. SLANG can also
deal with text strings. It can try to execute them as functions.
In either case, you can control what happens. Although SLANG deals
with everything as text, exactly what happens is done according
to strict SLANG rules.
SLANG does not employ the concept of 'variable',
where a variable has a 'value' which can be 'set'. Instead, SLANG
focuses its attention on pieces of text which are stored for later
use.
A character string or piece of text is treated
like an 'object'. An object is useful for what it is, or what it
can do. Like any other object, text in SLANG needs to be put somewhere
in order to store it. Like any object, a piece of text needs a name
to assist you in finding it and using it.
In SLANG, pieces of text are freely stored,
named, moved around, displayed, or executed. You command all this
by using the name of the text object to which you are referring.
SLANG places great emphasis upon the names of
things. The different kinds of names include: the names for SLANG's
built-in functions called "primitives", the names of your
user-defined functions, the names of strings of data, and so on.
Names are short character strings, and are also text. So, names
are bits of text used to refer to other pieces of text.
To do the necessary naming and storing, SLANG
has the built-in function define, which is a SLANG primitive. This
primitive define allows you to store any text and give it a name.
For example, the SLANG statement shown below stores the text voxbox@globe.com,
which is an Internet address.
(define, target, voxbox@globe.com )
It gives this address string the name target.
Now you can retrieve and use this complex line of characters by
using the name target.
In another example, the statement shown below
stores the short SLANG script (output, hello) (cr) under
the name response3. Now you can retrieve and use this new
user-defined function by using the name response3.
(define, response3, { (output, hello (cr)
)})
The details on exactly how to use the new names
will be explained more completely later in this introduction to
SLANG.
Names in SLANG are case sensitive. This gives
you flexibility in naming things. For example, the names of all
the SLANG primitives are always in lowercase. The upper-lowercase
distinction provides an easy way to distinguish between your own
user-defined functions and the built-in primitives. To distinguish
your function from a primitive, you just include some uppercase
letters in the name, as in "MyReceive" for the name of
your own version of the SLANG primitive "receive". However,
use of uppercase letters is not required.
SLANG Syntax
The "syntax" of a language is the set of
rules that tell you how to use the language. The SLANG syntax is
designed to make it easy to write SLANG scripts. SLANG syntax has
only a few rules to remember. There are only a very few syntax symbols.
The syntax symbols are:
Parentheses ( )
Braces { }
Comma ,
Symbols <* *>
Because the syntax symbols are the punctuation in
the SLANG language, if you use the wrong syntax, your scripts will
not work.
| To do this |
Use this character |
| To separate argument |
, the comma |
| Start a statement |
( |
| End a statement |
) |
| Start plain text |
{ |
| End plain text |
} |
| Start a comment |
<* |
| End a comment |
*> |
| |
|
There are two important things to remember about
the SLANG syntax:
1. The SLANG interpreter removes all white spaces
between characters (such as tab and space characters). To preserve
any desired white space, surround the text by braces as in
{Today is Monday.}
Without the braces, SLANG gives:
TodayisMonday.
2. Comments are set off with the symbols <* and
*>. For example:
<* The stored string is unchanged at this point. *>
It is always important to write scripts that
are readable so that, if the scripts need modification, they are
easy to understand. SLANG makes it easy to put comments into your
user-defined functions and scripts.
Also, remember that the primitive named input
which is driven by the keyboard, does not return a value until you
press Enter. The input primitive requires that you complete
a line before going ahead.
To make your SLANG scripts easier for the Dialer
application to understand, add the following line as the first line
of each script:
For SLANG scripts add
<* language=slang *>
For COMSCRPT scripts add
; language=comscrpt
Note that the "language=" statement is in
a comment, and must be on the first line of the script file you
would like Dialer to run. This line is not required, but allows
Dialer to directly determine the language being used, instead of
taking time to analyze the script file.
Functions
SLANG uses "functions" to perform its actions.
SLANG has two kinds of functions: The lowest-level action functions
are built into SLANG, they are permanent, and are called "primitives".
In addition to the SLANG primitives, you can define your own functions.
Each kind of function - primitive functions
or user-defined functions - generally requires additional information
before it can perform its action. This additional information is
supplied by parameters called "arguments". A function
together with its arguments makes a complete SLANG "statement".
A statement is always enclosed by a pair of parentheses.
Important: A statement is the primary unit in
the SLANG language.
All statements in SLANG have the form:
( <function> , <argument> , ...
, <argument> )
Here <function> stands for the name of
the function, and <argument> stands for any additional parameter
needed to carry out the action of the function. Commas (not spaces)
are the required SLANG separators.
Statements may be nested as in mathematical
expressions:
( <function> , ( <function> ,
... ) , ... )
Statements may also be strung together like:
( <function> , ... ) ( <function>
, ... ) ...
In whatever manner the statements are combined,
each statement retains this basic statement form.
The actions specified in a SLANG script are
carried out by the "interpreter". The statements of a
script are executed one by one, in a specified order: from the inside
to the outside, and from left to right. Nested mathematical expressions
were the model.
Every function or primitive has a name, and
every SLANG statement must have a name as its first argument. When
a SLANG statement is executed, the action for the named function
is carried out while using the information provided by the other
arguments, if any, of the statement.
The parentheses marking out the statements must
occur in matched pairs: there must be just as many left as right
parentheses, irrespective of nesting or serial positioning.
Macros
SLANG is a 'macro language', and such a language
has a very important feature: A macro language allows the 'cascading'
type of in-line replacement of language statements by their values.
Cascading means doing the work in a series of
definite step-by-step actions, where the results are carried forward
statement by statement, as in a waterfall. A macro processor is
a system that carries out the cascading actions specified in the
macro language. The SLANG system is a macro processor.
In SLANG the cascading action occurs wherever
statements are nested. The cascade feature allows very powerful
scripts to be easily written. Consider the following cascaded statement
for taking keystrokes and sending them over a line:
(send, (input))
This simple script directs the input primitive
to take characters from the keyboard. This script has two nested
statements involving the primitives send and input.
The inside statement acts first.
Whatever you type becomes the string value of
the (input) statement. For example, if your keystrokes
are
hello
followed by the Enter keystroke, the string hello
will become the returned value of the statement (input).
This string value hello will then automatically replace the original
statement (input) and SLANG now has:
(send,hello)
This statement now sends the string hello out
the communication link.
This kind of "cascade" step-by-step
movement of the input data string from one statement to another
is one of the important features of a macro language.
A final comment about this example. You always
have to terminate your typing with the input primitive. The SLANG
input primitive responds only to a complete line from the keyboard.
The Interpreter
The essence of an interpreter system is that
it deciphers a long script, statement by statement, to produce the
actions described. The actions are produced after calling up from
storage the scripts, statements, and information, and putting them
together for the built-in primitives to act upon.
Most of the essential features of the SLANG
interpreter are illustrated by the action of the define primitive.
These features are:
1. The cascading of return values from one statement
to another. This has already been illustrated.
2. The necessity for interpretation of all arguments
in a statement before the action of the statement can be carried
out.
3. The protection of white spaces and functions
inside an argument by curly brackets.
Following the discussion of the define primitive
and SLANG syntax, we can quickly move through the description of
the rest of the primitives of SLANG.
Return to Table of Contents
The Define Primitive
The define primitive is the most important primitive
in the SLANG language. It is used for storing and naming pieces
of text, and its action has already been illustrated. We must now
study the details of how it works. The define primitive is used
in a statement like:
(define,<name>,<string>)
This statement has three arguments. These arguments
completely define the action of the statement.
The first argument define is the name
of the SLANG primitive which carries out the storage action. The
first argument of a SLANG statement is always the name of a function,
either a primitive or a user-defined function.
The second argument is <name>.
In the notation being used in this documentation, what is inside
angle brackets < and > describes the kind of argument
you are supposed to use. It as only a description You do not put
the series of characters <name> into a script. Instead
you are supposed to use a name. You furnish the name, such as joe
or ABC. Other kinds of arguments will be distinguished
similarly by enclosing < and > characters. In the
documentation below, you will be told what kind string or characters
to use.
Any string can be used in the <name>
argument for the name, but it is desirable to avoid collision with
the names of the SLANG primitives. You can easily do this by including
at least one uppercase character in the name string. (If you don't
use uppercase letters, nothing will happen unless there is an actual
name collision.)
The third argument in the statement is <string>,
and it represents the text that you want to store. English sentences,
numbers, or SLANG statements can be stored in this argument. If
you want to store only a character sequence, without white spaces,
and not containing any SLANG functions, you can place the character
sequence in this argument position without further concern.
Return to Table of Contents
Arguments
Containing Functions
All SLANG statements have one or more arguments.
Arguments may be strings, parts of scripts, or any kind of text.
However, if you want to store a script with
functions, or store strings with white spaces, you must protect
the entire argument with the curly braces { and }.
We have already seen an example of this in the
"response3" script earlier:
(define, response3, { (output, hello (cr))
})
Consider what would happen if the curly brackets are
left out. Then the statement becomes:
(define, response3, (output, hello (cr))
)
Now the storage action of define is completely
different. SLANG, according to its rules, executes any functions
in an argument unprotected by braces. It must do this before the
argument can be used.
Therefore the two functions (output, hello)
and (cr) must be executed before the action of define can
occur. Before any define action (that is, any storage and naming)
can take place, these two functions are executed. As a result, hello
followed by an carriage return goes to the local screen. No characters
are returned by these functions. So, the third argument is empty,
null. What is left is:
(define, response3,)
Now the "define" primitive acts on
this statement. As the result the name "response3" is
set up, but it points to an empty string in storage. This is probably
not what was intended.
This effect can be avoided.
Return to Table of Contents
White Spaces in Arguments
In any argument, or in any SLANG statement whatsoever,
there is another consideration: When the SLANG interpreter examines
the arguments of any statement, that is, as it looks for the comma
separators, it also removes all white space characters such as space
and tab characters.
Thus if the tall boy is the string
put into some argument, then when the interpreter is through with
the string, only thetallboy is left. If you really want to preserve
the white space characters, you must put curly braces around the
string to protect it. The interpreter removes the curly braces,
but does not look inside, so if you use {the tall boy}
in your script, then the interpreter will not modify the string.
The string stays:
the tall boy
However, for convenience reasons, a name like
this is not a good name to use. The reason is that in all future
uses of such a name with white spaces, you will always have to use
the curly braces to protect the white spaces. This can be an annoyance.
On the other hand, if you really have a need for a multi-word name,
consider using such forms as: "the_tall_boy" or "the-tall-boy"
since neither of these forms will be affected by the interpreter,
and you will not need the curly braces.
Short strings, not having white spaces, and
not using curly braces, are the most frequently used argument forms
in SLANG, such as "cat", "123", and so on.
This need for protecting white spaces and function
statements in the arguments holds for all arguments in all of the
SLANG primitives.
This consistent action of the interpreter's
eliminating the white space is not a disadvantage. Instead, it is
a major advantage: white space characters can be used freely in
SLANG scripts to format the scripts and to make the scripts more
readable for people. The interpreter removes the white spaces for
the machine.
The use of white space for script formatting
is abundantly illustrated in the scripts given later in this chapter.
Return to Table of Contents
Commands, Calls,
and Terminology
The define primitive is the tool for storing
text objects in the SLANG system. How do you get them out and use
them?
The object is a user-defined function. You cause
it to go into action by using its name in a function statement.
If its name is "channel2", to open a communications channel,
you simple put the name in the first argument of a statement, and
use the statement in a script. You write the following in your script,
and that is it. It does its thing when the rest of the script executes.
(channel2)
You might also speak of the string (channel2)
as a "command". It is a complete statement requesting
an action. Similarly, in conformity with general programming use,
you might speak of the string as a "call" requesting the
action. In general, these words and this language is not used in
this documentation for SLANG.
The main reason is that using them gets the
words and the meanings all tangled up. For example, you could get
into a discussion of "What do you call the call for a call?"
Or, "How do you command a command?" Both are reasonable
questions when talking about SLANG.
In conclusion, for any function or script, you
use a statement to 'do' the function.
Return to Table of Contents
The Value Primitive
Suppose you do not want to store an object, but instead
you want to look at it. For example, you want to display a string
on your screen, or you want to look at, not execute, a stored statement.
For this, you use the value primitive, which allows you to retrieve
the literal string which is stored behind a given name.
(value,<name>)
The returned value of the value primitive is
the exact string which is stored, all characters, all white spaces,
all punctuation marks, everything. It converts a name to the object
named. In a sense, it is the logical converse of the define
primitive.
One of the uses of the value primitive
is to display on the screen exactly what is stored behind a name.
To do this, you use the script shown below and the named object
is displayed on the screen without interpretation.
(output,(value,<name>))
Since value is the converse of define,
the script shown below stores the object of <name2>
with the new name of <name1>. The new stored object
is an exact copy of the old.
(define,<name1>,(value,<name2>))
Return to Table of Contents
Cascading Value Strings
The value primitive illustrates some of the concepts
central to understanding SLANG, arguments, return values, and the
cascade of return values. These concepts will now be illustrated
with a series of tiny scripts.
Method A
We start by storing and retrieving a string
without white spaces. Call this "Method A." By this method,
the statement
(define,A,cat)
stores the string cat with name A.
This stored text can be retrieved with the simple statement (A).
Retrieval and display on the screen can be done with the compound
statement:
(output,(A))
On the screen there now appears:
cat
Things become quite different if you try storing a
string with white spaces, such as with the statement:
(define,B,{the tall boy})
Now retrieval can be tried using the same method as
above:
(output,(B))
Following the action of this statement, the
object named B is retrieved by (B); the object
is interpreted; the resulting string replaces statement (B); and
the cascaded resulting statement before the output action now is:
(output,thetallboy)
The second argument now is the interpreted result
of interpreting string the tall boy. Execution of this output statement
puts on the screen:
thetallboy
This is not what might have been intended. The white
spaces have been lost.
Method B
Quite a different series of actions occurs if we retrieve
the object with the value primitive. Call this "Method B."
The corresponding sequence of actions becomes:
(output,(value,B))
(output,the tall boy)
the tall boy
In most cases, this is the result that would
be wanted from this stored object.
It is important to emphasize that the principles
just illustrated apply to all arguments of all built-in functions,
and all user-defined functions, of SLANG. There are no exceptions.
Also, it is fair to say that most SLANG programming
will use short character strings with no white spaces. Thus, Method
A will be used in most programming, with Method B reserved for the
minority of cases where the preservation of the white spaces is
important.
Note that Method B can also be used to preserve
commas in a modem command string.
We now move on to the description of the rest
of the primitives in the SLANG language.
Return to Table of Contents
Storage and Retrieval
Primitives
There are three SLANG storage and retrieval
primitives. They are:
In addition, any statement whose first argument
is a user-defined text object can retrieve a text object not containing
SLANG executable statements.
Define Primitive
See Section B.4, "The
Define Primitive."
Value Primitive
See Section B.8, "The
Value Primitive."
Delete Primitive
The delete primitive deletes a text object previously
stored with the define primitive. It is useful for saving text storage
space. Storage space is limited. The amount of storage space available
(in bytes) can be determined with the storage_size primitive.
(delete, <name>)
Return to Table of Contents
I/O Functions
The sections that follow discuss the I/O functions.
The I/O Primitives
These SLANG primitives are useful for keyboard/screen
input and output. They are:
- output
- input
- conecho
- prompt
- message
Each of these primitives will be illustrated
in a properly formed statement and its action will be explained.
Each of the arguments will also be described.
Output Primitive
The output primitive displays <str>
on the screen. This primitive is the main
method for providing screen output to the user. The output primitive
returns a null string.
(output,<str>)
The output primitive is paired in purpose with the
input primitive for keyboard input. These two primitives are the
main channels for user control during the execution of a script.
If <str>
is text containing white spaces or functions, curly braces are required
to preserve the formatting. Use {<str>} in the second
argument.
You will often want to use a <str>
which contains executable functions. These functions will consistently
be interpreted before the screen display unless curly braces have
been used surrounding <str>.
On the other hand, with curly braces, the form
(output,{<str>}) will display
the text of <str> uninterpreted.
It will even display the text of any executable statements contained
in the argument.
Finally, (output,(value,<name>))
will display the uninterpreted text of the stored object named
<name>.
Input Primitive
The input primitive acquires input from the
keyboard, waiting until a full line ending in a carriage return
has been acquired.
(input)
The value string returned by the primitive is
the string read in, omitting the carriage return or line feed characters
at the ends of the lines. The input primitive returns a null string
if nothing has been read in before the Enter key is pressed.
Conecho Primitive
The conecho (for console echo) primitive sets or resets
the echoing or display of keystroke characters during the action
of the input primitive.
(conecho,off) and (conecho)
If there is no argument off,
the keyboard input echo is turned on, as in
(conecho) or (conecho,). The default
is on.
However, if argument off
is used, the echo is turned off as in (conecho,off).
prompt Primitive
The prompt primitive displays a dialog box with the
specified argument as message text and returns the prompt response
text string. You can specify a password_string to hide the prompt
response (such as a the password) by displaying a particular character
instead of the character that was entered.
(prompt, {message_text} [, password_character])
For example this command displays a dialog box with
the text, Password:, and a * appears as you enter each character
of your password.
(prompt,{Password:},*)
message Primitive
The message Primitive displays a message box.
(message,<text>,<buttons>,<icon>,<default>,<string1>,<string2>,<string3>)
<text> is the text of the message
to be displayed.
The following are valid strings for <buttons>
(not case sensitive):
| Argument String |
Displays |
OK
OKCANCEL
YESNO
YESNOCANCEL
RETRYCANCEL
ABORTRETRYIGNORE |
OK button
OK and CANCEL buttons.
YES and NO buttons. YES, NO, and CANCEL buttons.
RETRY and CANCEL buttons.
ABORT, RETRY, and IGNORE buttons. |
If the <buttons> argument is
left blank, the message box displays the OK button only.
The following are valid strings for <icon>
(not case sensitive, only the initial letter is required):
| Argument String |
Displays |
QUESTION (or q)
EXCLAMATION (or e)
INFORMATION (or i)
STOP (or s) |
Question mark icon.
Exclamation point icon.
Information icon.
Stop sign icon. |
If the <icon> argument is left
blank, the message box appears without an icon.
<default> may be 1, 2, or 3, and indicates
which of the buttons will initially be selected. For example, if
2 is specified and YESNOCANCEL was specified for <buttons>,
the NO button will be highlighted when the message box first appears.
The message primitive returns <string1>
if the user clicks the first button, <string2> if
the user clicks the second button, and <string3>
if the user clicks the third button.
Note: In the initial release of OnNet
2.0 (August, 1995) the following button selections do not work properly
in the message primitive:
If you have okcancel as the <buttons>
argument and you select "cancel" when the message box
appears, the primitive statement produces a null string instead
of the string you supplied as the <string2> argument.
If you have also specified a <string3> argument in
the primitive statement and you select "cancel" when the
message box appears, the primitive statement produces the <string3>
string instead of the <string2> string.
If you have retrycancel as the <buttons>
argument and you select "cancel" when the message box
appears, the primitive statement produces a null string instead
of the string you supplied as the <string2> argument. If you
have also specified a <string3> argument in the primitive
statement and you select "cancel" when the message box
appears, the primitive statement produces the <string3> string
instead of the <string2> string.
If you have abortretryignore as the
<buttons> argument and you select "retry"
when the message box appears, the primitive statement produces the
<string1> string instead of the <string2>
string.
Return to Table of Contents
Looping and
Flow Control Functions
The loop and flow control functions are described
below.
The Loop Primitives
There are five primitives that provide control
of iterative actions in SLANG:
- loop
- loopnum
- break
- lbreak
- exit
Loop Primitive
The important primitive in this family is loop.
The other primitives of the group assist in its use. loop is a complex
and important primitive, and it deserves careful study.
The primitive loop is the primitive that permits
SLANG to perform controlled iterations. There are three arguments
in the loop statement.
(loop,{<lscript>},<int>)
The second argument {<lscript>}
is the most important. <lscript> (standing for this
loop's script) is any SLANG script. <lscript> may
involve one or many functions. <lscript> may also
consist of text and white spaces. In general, <lscript>
will consist of combinations of functions and text. In the execution
of the loop primitive, the entire text of <lscript>
is copied into a special buffer, from which SLANG repeatedly makes
copies. These copies are then executed.
The third argument <int> is an
integer number greater than zero, or is -1. If <int>
is -1, the iterations are indefinitely continued. If <int>
is a positive integer N, the iterations are repeated N
times.
Additional control of the loop primitive's action
is provided by the built-in SLANG primitives loopnum, break, and
exit, whose actions are describe below. These loop primitives may
be placed among the statements of <lscript>.
Loopnum Primitive
The loopnum primitive does not take arguments. When
executed from within <lscript> it returns the current
count of the loop iterations, counting from 1. This returned value
may be used for controlling or stopping the loop.
(loopnum)
Break Primitive
The break primitive does not take arguments. When
executed from within <lscript> it terminates the
action of the loop primitive of which it is the argument. If there
are inner nested loops, these are categorically stopped. break does
not affect outer enclosing loops. There is not a return string.
lbreak Primitive
The lbreak primitive does not take arguments. When
executed from within <lscript> it immediately terminates
the action of the loop statement of which it is an argument. This
differs from the the break primitive, which does not cause termination
until the bottom of the loop is reached. There is not a return string.
Exit Primitive
The exit primitive does not take arguments. When executed
from within <lscript> it terminates the action of
the entire SLANG system and control returns to Dialer. Note that
the exit primitive will terminate a SLANG script and return to Dialer.
Note also that you do not have to be in a loop to use exit.
Return to Table of Contents
(exit)
Arithmetic Functions
The arithmetic primitives are described below.
The Arithmetic Primitives
The arithmetic primitives take integers as their second
and third arguments, and they return an integer result. This group
contains the five primitives:
Each is illustrated below in a properly formed
statement.
+ Primitive
The + primitive returns the sum of <int1>
+ <int2>.
(+,<int1>,<int2>)
Note: (define,x,1)
(+,(x),(x)) yields 2
Note: (define,x,+)
((x),1,1) yields 2
- Primitive
The - primitive returns the difference <int1>
- <int2>.
(-,<int1>,<int2>)
* Primitive
The * primitive returns the product <int1>
* <int2>.
(*,<int1>,<int2>)
/ Primitive
The / primitive returns integer quotient of <int1>
/ <int2>.
(/,int1,int2)
% Primitive
The % primitive returns the integer remainder
of <int1> divided by <int2>.
(%,int1,int2)
Return to Table of Contents
Comparison Functions
The comparison primitives are described below.
The Comparison Primitives
There are three comparison primitives:
The comparison primitives functions compare
two strings, specified by the second and third arguments, and depending
upon this comparison select among the subsequent arguments. The
selected argument determines the returned string.
== Primitive
The == primitive compares the interpreted results
of <str1> and <str2>, and returns
the interpreted value of string <T> if they are equal,
and the interpreted value of string <F> if they are
not.
(==,<str1>,<str2>,<T>,<F>)
This primitive is easiest to understand if all
the arguments are alphabetic strings, with no white spaces or functions.
Note that <T> and <F>
may be any kind of string, /including an executable statement.
If you place curly braces around the <T>
and <F> arguments, you prevent interpretation of
these arguments prior to the comparison action of the == primitive.
Without the curly brackets, you might not get the result that you
expect.
The == primitive may be used for changing the
course of action in a script, by allowing you to branch and select
one function or another. You may do this by selecting either function
names, or whole function statements using the <T>
and <F> arguments.
has Primitive
The has primitive compares the stored text with
<name>, and if the interpreted result of <str>
is included in the stored text, this statement returns interpreted
string <T>, and if not, returns interpreted string
<F>.
(has,<name>,<str>,<T>,<F>)
This primitive is easiest to understand if all
the arguments are alphabetic strings, without white spaces or functions.
Note that <T> and <F>
may be any kind of string, including an executable statement.
If you place curly braces around the <T>
and <F> arguments, you prevent interpretation of
these arguments prior to the comparison action of the has primitive.
Without the curly brackets, you might not get the result that you
expect.
The has primitive may be used for changing the
course of action in a script, by allowing you to branch and select
one function or another. You may do this by selecting either function
names, or whole function statements, using the <T>
and <F> arguments.
compare Primitive
The compare primitive compares two numeric values
and returns a user-specified string reporting whether the first
value is greater than, equal to, or less than the second value.
(compare,<n1>,<n2>,<string1>,<string2>,<string3>)
The compare primitive returns <string1>
if <n1> is greater than <n2>, <string2>
if <n1> is equal to <n2>, and <string3>
if <n1> is less than <n2>.
In the following example, the compare primitive
returns the string less.
(compare,45,59,greater,equal,less)
Return to Table of Contents
Miscellaneous Functions
The miscellaneous SLANG built-in primitives are described
below.
The Miscellaneous Primitives
This group of primitives provides miscellaneous
utility actions.
- start
- shell
- include
- replace
- storage_size
- debug
- time
- cr
- lf
- char
- username
- password
- modem
- phone
- ipaddress
- status
- trac
start Primitive
The start primitive has an argument, <command-line>.
It causes the execution of the script signified by <command-line>.
An exact path to the command may be necessary for execution. Both
DOS and Windows commands can be executed. Four additional arguments
allow you to add command line switches or arguments.
(start,<command-line>,<arg1>,<arg2>,<arg3>,<arg4>)
For example:
(start,c:\pctcp\rsh,-e,ls)
The start primitive differs from the shell primitive
in that it starts a separate independent task (either a DOS or Windows
application) and then returns immediately, causing the script to
continue.
shell Primitive
The shell primitive has one argument, {<command-line>}.
It causes the execution of the script signified by <command-line>.
The curly braces are essential to its action if the command line
has more than one argument. An exact path to the command may be
necessary for execution. Both DOS and Windows commands can be executed.
If there are arguments on the command line they
may be delimited by spaces, in which case curly braces must be used.
The number of arguments is not limited to 4 as with the start primitive.
(shell,{<script>})
For example:
(shell,{c:\pctcp\rsh -e ls})
The shell primitive differs from the start primitive
in that it begins a DOS or Windows application then "blocks"
waiting for that application to finish and it's window to close.
This is an important point, because if the application's window
is open after it completes, shell will not return and the script
will wait. PIF files may have to be adjusted to work with shell.
After the application's window is closed, shell returns and the
script continues.
The primitive shell is unusual among all the
SLANG primitives in that any reasonable use of shell requires curly
braces around this second argument.
include Primitive
The primitive include fetches the scripts named in
<filename> from disk. It is useful in loading the
SLANG system with your previously-defined scripts.
(include, <filename>)
replace Primitive
The replace primitive, like the has primitive, acts
upon the text stored with <name>. The replace primitive replaces
all occurrences of the string produced by argument <A>
with the string produced by argument <B>.
(replace,<name>,<A>,<B>)
A simple way to use this primitive is to use
simple character strings that do not contain functions for the arguments
at the arguments <A> and <B>, or to
put curly brackets around these arguments.
For example, say we want to change all occurrences
of fish to fat eels in the stored string which
has the name the lake. There are now two places where the white
space needs protection. This action is now done with the straightforward
statement:
(replace,{the lake},fish,{fat eels})
storage_size Primitive
The storage_size primitive returns the space still
available for use, expressed in bytes. It does not have arguments.
(storage_size)
debug Primitive
The primitive debug sets the debugging messages
action on or off. The action is like the remecho and conecho primitives.
The default is off.
(debug) and (debug,off)
This example illustrates how to turn on the
display of debugging messages. (The debugging messages begin with
----.)
(debug, on)
(replace, phone_number, 617, 508)
---- Replacing all occurrences of 617 with
508 in the variable phone_number
time Primitive
The time primitive returns a text string representing
the current date and time.
For example, the command (time) returns
Wed Sep 28 18:04:55 1994
cr Primitive
The cr primitive generates and returns a carriage
return character.
(cr)
It generally is used to terminate a command to a modem,
such as:
(send, ATH (cr))
An alternate way to do this is to enter the
following and to press the Enter key before the final curly
brace.
(send, { ATH
})
lf Primitive
The lf primitive generates and returns a line feed
character.
(lf)
char Primitive
The char primitive returns the ASCII value corresponding
to the decimal value specified.
(char,<value>)
In the following example, the char primitive
returns the left parenthesis.
(char,40)
username Primitive
The username primitive returns the username entered
in Dialer's configuration window.
(username) or (username,string>)
If an argument is supplied, the username is set for
the duration of the script.
password Primitive
The password primitive returns the password entered
in Dialer's configuration window.
(password)
or (password, <string>)
If an argument is supplied, the password is set for
the duration of the script.
modem Primitive
The modem primitive returns the specified modem control
string for the current serial connection's modem type (from the
MODEM.INI file in the PCTCP directory).
(modem, modem_string)
where modem_string is one of:
- init
- Gets the modem initialization string
- hang_up
- Gets the modem hang up string.
- dial
- Gets the modem dial string.
- reset
- Gets the modem reset string.
- pause
- Gets the modem pause string.
For example, this command returns the string
ATDT for a Touch Tone dialing method, and ATDP for a Pulse dialing
method.
(modem, dial)
phone Primitive
The phone primitive returns and optionally sets
the specified field of the phone number of the network service provider
for a serial network connection (SLIP/PPP). With a second argument,
phone sets the specified field to a new string.
(phone, phone_string [, new_setting] )
where phone_string is one of
- number
- Gets the phone number (including the area
code, but not the prefix).
- timeout
- Gets the timeout value.
For example, if the configured phone number
is 555-1212, the following command returns the string 555-1212:
(phone, number)
- This command sets and returns the phone number
string 666-9876.
(phone,number,{666-9876})
ipaddress Primitive
The ipaddress primitive returns and (optionally) sets
the IP address of the SLIP/PPP network interface in the PC/TCP kernel.
With an argument, ipaddress sets the IP address to the specified
argument.
(ipaddress [, new_setting] )
This command returns the configured IP address of
the interface (for example, 128.127.50.100).
(ipaddress)
This command sets and returns the IP address of the
serial network connection to 128.127.50.100.
(ipaddress, {128.127.50.100})
status Primitive
The status primitive updates the Status text in the
Dialer Simple Mode status window, and displays a countdown from
an optionally specified timeout value (in seconds).
(status,<text>) or (status,<text>,<timeout>)
For example,
(status, Dialing...,60)
trac Primitive
The trac primitive enables execution of a specified
primitive in the TRAC language.
(trac, <primitive>,<param1>,<param3>,...)
Return to Table of Contents
Remote I/O Functions
The remote I/O primitives are described below.
The Remote I/O Primitives
This group of primitives has fifteen members:
- send
- receive
- remecho
- poll
- port
- baud
- parity
- changemode
- identity
- secret
- escape
- get_ipaddress
- find_ipaddress
- num_ipaddresses
- frametype
send Primitive
The send primitive sends the text resulting
from interpretation of <str> to the modem.
(send,<str>)
Usually, when using send, the argument <str>
will be a statement or a script which will produce the text as it
is executed.
In other cases, you may wish to send ordinary
text from the second argument, for example, a line of a document.
It is necessary to protect the white spaces with curly brackets.
The statement using the primitive then takes the form:
(send,{ This is what is sent. Exactly! })
Note that when using Modem dialing commands,
the comma is often used. Commas to be sent over the modem connection
must be placed in curly braces.
(send,{ATDT9,1123456789,,123,})
receive Primitive
The receive primitive takes in characters from a modem
for <timeout> milliseconds, or until one of the <search_stringN>
arguments is detected. Then its input action stops and the received
string is returned. Characters are echoed to the console if the
remote echo is on (see the remecho primitive below). The returned
string is the string taken in, or the null string if nothing was
received in the <timeout> interval. From 1 up to
32 search_strings can be used. Search strings are case sensitive.
(receive,<timeout>,<search_string1>,<search_string2>,
...)
Note that millisecond equals seconds/1000.
remecho Primitive
The remecho primitive sets or resets the echo
of incoming characters operation of the receive primitive. If a
second parameter off is present, the echo is turned off.
Otherwise, the echo is turned on. The default is on.
(remecho) and (remecho,off)
poll Primitive
The poll primitive examines <item>
for its state. The choices for <item> are the literal
strings "physical", "lcp", and "ipcp".
Choices for <state> are the literal strings "opened"
and "closed". The returned value string of poll is <Y>
if the specified state was reached; <N> if it was
not before <time-out> (in milliseconds) elapsed.
In other words, the poll primitive blocks until the specified state
is achieved or the primitive times out.
(poll,<item>,<state>,<time-out>,{<Y>},{<N>})
port Primitive
The port primitive allows you to specify the
serial port to be used by Dialer. It takes one argument <n>,
which may have any one of the strings:
AUX
COM1
COM2
COM3
COM4
If one of the values is present, the port is
set (only if it is a valid serial port on your computer). If an
argument for port is absent, then the currently defined port is
returned.
(port,<n>) and (port)
baud Primitive
The baud primitive sets the speed of Dialer's
current serial port. The second argument <n> may
have values up to 230400. If an integer value for <n>
is present, the baud rate is set for that value. If not, the current
baud rate is returned.
(baud,<n>) and (baud)
Valid baud rates (limited to the capacity of
our serial hardware) for <n> must be exact and are:
110
300
600
1200
2400
4800
9600
14400
19200
38400
57600
115200
230400
parity Primitive
The parity primitive sets the parity of
Dialer's current serial port. The second argument <n>
is a character string. If <n> is present, the parity
is set for that type. If not, the current parity setting is returned.
(parity,<n>) and (parity)
Valid strings for <n> must be exact
and are:
None
Odd
Even
Mark
Space
changemode primitive
The changemode primitive sets the transmission mode
of the Dialer's current serial port. The default mode is packet
mode.
(changemode, <mode>)
Valid strings for <mode> are:
Packet
Raw
identity Primitive
The identity primitive returns the Password Authentication
Protocol (PAP) userid or Challenge-Handshake Protocol (CHAP) identity.
(identity) or (identity, <string>)
If an argument is supplied, the PAP userid or CHAP
identity is set to the value of the argument.
secret Primitive
The secret primitive returns the Password Authentication
Protocol (PAP) password or Challenge-Handshake Protocol (CHAP) secret.
(secret) or (secret, <password>)
If an argument is supplied, the PAP password or CHAP
secret is set to the value of the argument.
escape Primitive
The escape primitive performs any of several specified
escape functions on the comm port.
(escape,<comm_function>)
Valid strings for <comm_function> are:
setbreak - Turns
on the serial-break status.
clearbreak - Turns
off the serial-break status.
setdtr - Turns
on the modem's Data Terminal Ready (DTR) status.
cleardtr - Turns
off the modem's DTR status.
xon - Sends
XON flow control signal.
xoff -
Sends XOFF flow control signal.
get_ipaddress Primitive
The get_ipaddress primitive returns the <n>th
IP address received via the receive primitve during the current
session.
(get_ipaddress,<n>)
The get_ipaddress primitive is only available in SLIP
mode.
find_ipaddress Primitive
The find_ipaddress primitive returns the <nth>
IP address in <text>.
(find_ipaddress,<text>,<n>)
This primitive causes the list of IP addresses received
via the receive primitive to be cleared.
num_ipaddresses Primitive
The num_ipaddresses primitive returns the total number
of IP addresses received via the receive primitive during the current
session.
(num_ipaddresses)
The num_ipaddresses primitive is only available in
SLIP mode.
frametype Primitive
The frametype primitive reports the serial interface
protocol in use. The frametype primitive reports PPP, if
in PPP mode, SLIP, if in SLIP mode, and PPP_NOPROMPT,
if in PPP mode and the user has indicated that the server will not
be prompting for input.
(frametype)
Return to Table of Contents
Storing Scripts with
the Define Primitive
The "define" primitive allows you to create
your own user-defined functions. To do this, you first must create
an executable script, store the script, and give it a name. The
trick is to store the script, and not to let it go into execution
before you store it. You do this by placing the entire script within
a pair of curly braces { } .
Examples of Writing SLANG Scripts
The following statement stores and names an
imaginary script that logs your PC into a host machine called "fred".
The script is stored with the name "log_me_into_fred",
because this descriptive name helps you remember what the script
does. The actual details of why it gets into the "fred"
host will be buried in the script, and has nothing to do with the
name.
(define, log_me_into_fred,{
<* place your login script here*>
})
You might want another script, for a "wilma" host:
(define,log_me_into_wilma,{
<* place your login script here*>
})
A SLANG script can dial a telephone number and,
after making the connection, it can accept the data response, and
store the response with a temporary name such as "temp".
The script can then examine the string named
"temp" to determine whether the stored response contains
either the "fred" or "wilma" string, which would
indicate to which host it had been connected. You then want to use
the script that will properly log you in to one or the other host.
Here is an example of such a script with the kind of comments
you should use:
(define,temp,(receive,30000)) <* waits
30 seconds *>
(has,temp,fred,{(log_me_into_fred)}, <* yes temp holds "fred"
*>
{(log_me_into_wilma)}) <* not "fred", must be "wilma"
*>
If the string named temp contains the
substring fred, then the script named "log_me_into_fred"
is called; otherwise, the script named "log_me_into_wilma"
is called.
This second example illustrates another way
to perform the choice of the two script actions, using the macro
cascade action. In this example, the preamble text "log_me_into_"
will be combined with one of the two text fragments "fred"
or "wilma" to produce the full name needed to secure the
desired log-in script. It is done like this:
(define,temp,(receive,30000)) <* listens
for the response *>
(log_me_into_(has,temp,fred,wilma)) <* chooses the final string
*>
The statement in this second line has a cascade
action. In the first stage of the cascade, the "has" primitive
acts on the "temp" stored text to return the fragments
"fred" or "wilma".
In the second stage of the action, the selected
fragment is pasted onto the tail end of the fragment "log_me_into_"
to make a complete name string. As a result, one or the other of
the following statements will have been created and the desired
user-defined function will execute:
(log_me_into_fred)
<* or *>
(log_me_into_wilma)
Return to Table of Contents
Creating Loops in Scripts
With the loop primitive, you can produce repeating
actions in your scripts. The loop primitive has the following
syntax:
(loop, {<lcmds>}, <int>)
The loop primitive executes the script placed
in the argument <lcmds> for the number of times specified
by <int>.
For example, the following statement outputs
the literal string myname five times, preserving the spaces:
(loop,{
(output, { myname }) <* do this five times *>
},5)
The result is:
myname myname myname myname
myname
To output the string myname only one time,
the loop is written as follows. This way of using the loop statement
is useful for simulating case/switch statements, and for breaking
out of deeply nested function calls (see below).
(loop,{
(output, { myname }) <* do this once *>
})
In the example below, the string myname will output forever or until
you select the Stop Script button.
(loop,{
(output, { myname }) <* do this forever *>
},-1)
Exiting the Loop Statement Before Completing
the Specified Number of Iterations
You can exit or abort a loop statement using
the break primitive. The primitive break exits from the current
loop statement.
The loopnum primitive returns the current number of the loop iteration.
For example, the following script checks the
object named temp for inclusion of the string login. It does this
for every 15 seconds for a total interval of one minute or until
the string login is received. If the string login is found, the
(break) statement exits the loop statement immediately.
(loop,{
(define,temp,(receive,15000,login:))
(has,temp,login:,{(break)})
},4)
Next, a slightly more complicated but possibly more
robust example of the same thing. It is more robust in that it saves
all the input until it does the examination of temp.
(delete,temp) <* clear any previous
temp *>
(loop,{
<* cumulatively store into temp *>
(define,temp,(value,temp)(receive,15000,login:))
<* is a "login:" in temp? *>
(has,temp,login:,{(break)})
},4)
To Display the Loop Number
By using the loopnum primitive you can observe the
current loop number. The following example successively displays
the count number, from 1 to 10, placing a single space after each
number displayed.
(loop,{
(output,(loopnum){ }) <* display which loop we are in *>
},10)
Using Loops as a Case or Switch Statement
A programmer can use a loop statement as a case or
switch statement. The following illustration shows a portion of
a larger script. The larger script is intended to perform one of
several different user-defined functions, depending on what has
been received.
(define,temp,(receive,15000,login:)) <*
define always replaces *>
<* old strings *>
(loop,{
(has,temp,klingon.ftp.com,{
<* first user-defined function *>
(do_something)
(break)
})
(has,temp,kipper.ftp.com,{
(do_something_else)
(break)
})
(has,temp,salmon.ftp.com,{
(do_something_completely_different)
(break)
})
(do_something_if_no_conditions_are_true)
})
This script effectively mimics a C-language switch.
It executes once. The loop is only used to provide something to
break out of.
The Need for Curly Braces in Loop Statements
To ensure correct action the loop primitive, you must
use curly braces to protect your scripts within the argument <lcmds>.
To illustrate, the following faulty script displays the literal
string hello! just once rather than the five times that
was probably intended.
(loop,
(output,hello!) <* do this only once *>
,5)
What happens is that the second argument of
loop is executed by the interpreter as it looks for arguments of
the loop primitive. (Reason, no protecting curly braces.) SLANG
statements are just like mathematical statements: inner expressions
are evaluated first. In SLANG, the cascaded argument rule specifies
that all arguments must be interpreted, before statement execution.
Thus, all statements in the second argument are interpreted, and
a null string is left. All this happens before any action of the
loop primitive starts.
Now SLANG has:
(loop,,5)
The loop primitive now does its stuff with the
arguments that it has - it does nothing five times.
In order to display the string hello!
five times, you must use curly braces and write:
(loop,{
(output,hello!) <* do this five times *>
},5)
When the braces surround the output statement,
the following statement is first preserved in the loop primitive's
internal mechanism for the intended multiple execution. In this
way scripts for multiple actions can be used by the loop primitive.
(output,hello)
On the other hand, there may be times when you purposely
want to use the curly braces in a different manner. For example,
the following script displays This is a test. just once,
followed by hello! five times.
(loop,
(output,{This is a test.}) <* do this line once *>
{
(output,hello!) <* do this five times *>
}
,5)
For a simple experiment, you can try putting spaces
around the hello! and displaying the output in a column
using (cr)(lf).
Nesting Loops
SLANG can nest up to 6 loop statements, one
inside the other. If you try to use more levels, SLANG will object
when you try to execute your script and let you know it will not
work.
The loop action does not respect function boundaries.
A (break) statement exits out of the current loop statement, irrespective
of the complexity of the script being iterated. However, the action
of (break) does not go further. It stops only the current loop action,
and it also stops any subsidiary inner loops if there are any. However
if the loops are nested, any outer loops are unaffected.
For example, in the following script the (break)
statement executes from inside the user-defined function foo.
The (break) breaks out of the loop that has called foo.
A function can call a function that calls a function that executes
(break), and the action still works.
This technique is useful for breaking out of
a loop at any loop level, no matter how many layers of function
call.
(define,foo,{
(has,temp,login:, <* is "login:" found? *>
{(log_me_in)}, <* yes: login to the computer *>
{(break)} <* no: quit *>
)
})
(loop,{
(define,temp,
(receive,50000,login:)) <* get input *>
(foo) <* log in or abort *>
},-1)
Creating a Script
This example demonstrates a script that accesses
a remote host via FTP. The FTP application continues to run after
after the script finishes.
The script:
(define,login,{ <* A user login script
*>
(send,ATDT1234567(cr)) <* Dial the number *>
(define,temp,(receive,30000,login:))
<* Get input from the line *>
(has,temp,cactus,{ <* Is it the host cactus? *>
(send,raphael(cr)) <* Yes, send my user name *>
(define,temp,(receive,30000,Password:))
<* Get and store user input *>
(has,temp,password,{ <* Is it a password prompt? *>
(send,(output,{password please? })(input)(cr))
<* Yes, ask for, get, and send password *>
})
(output,(receive,10000)) <* Get and display any login message*>
})
})
(login <* Run the login script *>
(start, ftp) <* Start the FTP application *>
(send, +++) <* Hang up *>
(send, ath(cr))
(exit)
With this script, you are using the SLANG language
to log in to the remote host, start the FTP application, and disconnect
from the remote host. The FTP application continues to run in parallel
after the script finishes. (To run an application that terminates
before the next line of the script is interpreted, replace the shell
command in this example with a start command.)
All SLANG commands in the following example
are typed in to a file to be executed using the Start Script button
in Dialer.
To log in to a remote host
1. Type the following line to give the name "login"
to new script:
(define,login,{
2. Type the following line to communicate with the
modem and dial the number:
(send,ATDT1234567(cr))
3. Type the following line to begin the definition
of a storage object to hold the login prompt once the remote host
responds with one:
(define,temp,
4. Type the following line to receive the returned
prompt giving the received string the name "temp" :
(define,temp,(receive,30000,login:))
This receive statement waits 30 seconds for
the login prompt. However, if the prompt is received before 30 seconds,
the receive function immediately returns the received string. This
string usually contains the remote host name (in this case, the
expected return string is cactus login: ). Notice that
in the script that parentheses delimit both the define primitive
and the receive primitive, with commas used as argument separators.
5. Type the following line to begin the verification
that you have reached the correct host:
(has,temp,cactus,{
The script uses the primitive has to determine
whether the stored string named temp contains the substring cactus.
6. Type the following line to send your user-id
(in this case "raphael") followed by a carriage return
to the remote host:
(send,raphael(cr))
7. Type the following line to wait for the string
Password: from the remote host, storing the string with
the name temp:
(define,temp,(receive,30000,Password:))
The receive primitive waits no more than 30
seconds for the remote host to return the Password: prompt. Whatever
is received is stored with the name temp. If nothing is received,
the receive primitive will return nothing. An empty object will
be stored with name temp.
8. Type the following line to determine whether
the object named temp contains the string Password: sent from the
remote host:
(has,temp,Password:,{
9. Type the following lines, which put the message
"password please? " on the local screen, only if the stored
object temp contains the Password: string:
(send,(output,{password please? })(input)(cr))
})
Since the object temp does contain the string Password,
the output function writes to the local screen the message password
please? . The output statement does not return a string back
as an argument to the send statement, so it can be included in the
send statement with no adverse effect.
Following the output statement, (still within
the send primitive) there is an (input) statement to take keyboard
action from the local keyboard. The result of the (input) statement
is to wait for you to provide input from the keyboard by typing
your password. The input statement returns the string from your
keystrokes. The (cr) statement provides a carriage return character.
Your input and the carriage return are then the second argument
for the send primitive.
The send primitive then takes this string and
sends it to the remote host. In this way your password is never
stored anywhere in the computer.
10. Type the following lines to complete this
section of the script. The top line displays on the local screen
the login messages received from the remote host.
(output,(receive,10000))
})
})
The action of the output statement deserves
study. It contains a receive primitive with a 10-second delay, so
action is held up for 10 seconds. The receive statement then returns
its string to the output primitive, which in turn outputs to the
local screen what has been received from the remote host. Most likely
it will be a login confirmation or some other messages.
11. Now type the line to call the login function.
(login)
However, we are not done yet.
Executing an Application Automatically
You may want to do more than just log in, such
as transfer files to a remote host using FTP.
In this script the start command runs the FTP
application as a parallel task and returns immediately. That is,
when you disconnect from the remote host, the FTP application continues
to run.
To run an application that terminates before
the next line of the script is executed, you can use the shell
primitive
To execute the FTP application
1. Type the following line to start the FTP application:
(start,ftp) <* The application continues
to run in parallel. *>
Disconnecting from the Remote Host Automatically
You can have your script automatically disconnect
your PC from the remote host at this point by including the following
lines. They send a message to the modem causing it to disconnect:
(send, +++)
(pause,2000) <* Give the modem time to respond *>
(send, ath(cr))
Another example of how to disconnect your PC automatically
follows:
(loop,{send,+++)
(define,temp,(receive,2000,ok))
(has,temp,ok,{(break)})
(send,ATH0(cr))
})
Stopping
Dialer Script Mode
You can automatically stop the Dialer script mode
after disconnecting from a remote host by including the following
line in your SLANG script:
(exit)
Return to Table of Contents
Debugging with Debug Mode
Two primitives are used when debugging your
SLANG program: (debug) and (debug,off). These primitives turn debugging
messages on and off, respectively.
These primitives may be used anywhere in your
SLANG program. By carefully positioning these primitives, you can
debug selected portions of your script one at a time.
To illustrate how you can debug your scripts,
consider the following script, designed to log you into a remote
host. When this script is executed, it continues to abort the connection.
(remecho,off) <* turn off serial echo
|