[ Home | Evals | Support | Buy | Investors | Search ]
  Subsribe to the NewMange SOA Newsletter  
NetManage Worldwide Sites
 
  Technical Support
  Legacy
  Solutions
    Search Knowledgebase
    FAQs
    Technical Documents
  Downloads
    Patches, Fixes and Updates
    Manuals and Guides
  PC/TCP OnNet Writing Scripts with SLANG

Table of Contents

Conventions Used
Overview
Basic Concepts
The Define Primitive
Arguments Containing Functions
White Spaces in Arguments
Commands, Calls, and Terminology
The Value Primitive
Cascading Value Strings
Storage and Retrieval Primitives
I/O Functions
Looping and Flow Control Functions
Arithmetic Functions
Comparison Functions
Miscellaneous Functions
Remote I/O Functions
Storing Scripts with the Define Primitive
Creating Loops in Scripts
Debugging with Debug Mode
Troubleshooting SLANG Scripts

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:

  • define
  • value
  • delete

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:

  • ==
  • has
  • compare

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