You are on page 1of 19

BASIC TACL COURSE

English Version, March 2005


title Beginners TACL Course

version, date English Version, t November jjjj

Author Dean Southall – dean.southall@gmail.com.removethisbit


Index
BASIC TACL COURSE....................................................................1

BASIC TACL COURSE....................................................................1

BASIC TACL COURSE....................................................................1

BASIC TACL COURSE....................................................................1

BASIC TACL COURSE....................................................................1

BASIC TACL COURSE....................................................................1

BASIC TACL COURSE....................................................................1

BASIC TACL COURSE....................................................................1

1. INTRODUCTION..........................................................................1
1.1 . General.......................................................................................1
2. TACL................................................................................................2
2.1 style & Standards........................................................................2
2.2 . TACL Variables........................................................................2
2.2.1 . Aliases ................................................................................3
2.2.2 . text.......................................................................................3
2.2.3 . Macro’s...............................................................................3
2.2.4 . Routine’s.............................................................................4
2.2.5 . Struct’s................................................................................5
2.2.6 . Def’s....................................................................................5
2.2.7 . Directories..........................................................................6
2.2.8 . Everything you wanted to know about variables but
were afraid to ask .........................................................................7
2.3 . General TACL tricks.................................................................7
2.3.1 . Be Nice................................................................................7
2.3.2 . Error Handling (only routines)........................................8
2.3.3 . Object Orientated?............................................................8
2.3.4 . TACL & Processes & files................................................9
2.3.5 . Defined Processes..........................................................10
2.3.6 . Debugging........................................................................11
2.3.7 . TACL Segments................................................................11
2.3.8 . TACL & Netbatch............................................................12
3. APPENDICES................................................................................13
3.1 . create^segment........................................................................13
3.2 . Defined Processes...................................................................15

R Beginners TACL Course English Version 1


1. Introduction

1.1 . General
The high level language TACL (Tandem’s Advanced Command
Language) is a Command Line Interpreter (CLI). It is interpreted
code and therefore fairly expensive in processor time compared to
compiled code.

This is just a basic course. After this course you can use the 2
TACL manuals :-
TACL Reference Manual
TACL Programming Guide

In order to use this manual you must have Basic Tandem


knowledge, the more the better.

R TACL Cursus 1
English Version
2. TACL

2.1 style & Standards


Look at the TACL Programming Guide page 1.2 for good style
tips.
TANDEM written macros/routines begin with _ or ^ thus your
macros must never begin with _ of ^.
You can use _ or ^ in the names of your macros e.g. tedit^file of
kill_process.

2.2 . TACL Variables


TACL is interpreted code (thus not compiled). The command of
TACL can heavily tax the system. You write TACL efficiently so
as not to hammer the system. There are 3 different ways to execute
TACL code:
1) Run <file name>
2) Load/ KEEP 1/ <library file>
3) Usage of segment files
A good example of 1) is your TACLCSTM (TACL custom) file.
Everyone has their own copy. It's used to customise your TACL
environment, to load TACL macros etc. etc.
Here below is an example of a TACLCSTM file:

?TACL ROUTINE
#SET #INFORMAT TACL
#SET #OUTFORMAT PRETTY

ATTACHSEG SHARED $DATA.DEAN.LOGSEG :LOGSEG


USE :LOGSEG [#uselist]
PMSG ON == shows the process number as a process starts
[#IF [#INTERACTIVE] |THEN|
:logseg:sp
]
RUN $DATA.DVNIBMT.BBSLOGON
param pathmon-name $PMW
dpp == define process peruse

(comments in a macro begins with ==)


[.....] means :- the value of something
|THEN| |ELSE| etc. are ‘labels’ and belong always to a multi
row/complex functions e.g. #IF #CASE etc.

The other 2 ways will be described later.

There are 8 sorts of TACL variables:


Macro’s
Routines
Directories
text
Aliases
Struct’s
Def’s
Delta's.

R TACL Cursus 2
English Version
2.2.1 . Aliases

These are the simplest TACL variables. They are useful for
shortcuts.

?SECTION t ALIAS
tedit

Instead of tedit you only have to type a t.


e.g. T $DATA01.DEAN.TACLCSTM

2.2.2 . text

These are the default variables commonly used to hold values e.g.
#PUSH name == make a variable
#SET name Dean == give the variable a value
#OUTPUT My name is [name] == show on the screen
#POP name == remove the variable

All #xxxx command's are codes of the Guardian operating system


and written in TAL or C. Many of this commands are comparable
with COBOL system calls.

2.2.3 . Macro’s

Macro's and routines are the programming language of TACL. They


can exist independently in a file (with ?TACL MACRO as 1st row)
or in a library file with other macro’s and routines. There is no
error handling possible in a macro.

?SECTION t MACRO
#OUPUT Tediting %1%.
TEDIT %1% %2% == %1% and %2% are parameters

If you type in: T TACLCSTM R then TACL will do the following :-


1) Reads the macro
2) replaces %1% door TACLCSTM
3) replaces %2% door R
4) runs the macro (thus: TEDIT TACLCSTM R)

Macro’s are simple and quick to make and are very useful for small
pieces of code. As they become bigger, they become more difficult
to read (who knows what %9% means after 100 rows of code?) and
slower because TACL a macro must be read twice read because the
parameters have to be filled in first before execution can take place.

R TACL Cursus 3
English Version
2.2.4 . Routine’s

Routine's are more complex than macro’s but give more


functionality:
1) You can write your own error handling.
2) You can control the parameters.
3) you can return a value back to the calling routine/macro.
4) you can a exit a routine whenever you want.
?SECTION T ROUTINE
#FRAME
#PUSH filename type
#SET type [#ARGUMENT / VALUE filename / FILENAME WORD]
[#CASE [type]
|1| [#IF [#FILEINFO / OPENNOW / [filename]] |then|
#OUTPUT Sorry guy! [filename] is already open
|else|
[#IF [#FILEINFO /CODE/[filename]] = 101 |then|
tedit [filename] A [#REST]
|else|
#OUTPUT Sorry guy! [filename] is not an edit file
]
]
|2|
[#IF [#match [#INPUT [filename] exists not, create?] Y] |then|
tedit [filename] !
]
]
#UNFRAME

1) All variables made pushed (created) after the 1st #FRAME are
automatically deleted after the #UNFRAME (you can #POP xyz
but #UNFRAME is easier). You can use frames in routines and
macro's.
2) [filename] contains the value of the filename. If the filename is
$data.dean.taclcstm, then the command
#OUTPUT filename [filename]
displays the following :-
filename $data.dean.taclcstm
3) #ARGUMENT is comparable to %n% in a macro. Value
filename means: stead here the value of the 1st parameter. As
you #ARGUMENT for the 2nd time uses than reads he the 2nd
parameter etc. Before the value of the parameter in
#ARGUMENT is replaced, TACL looks in the check-list after
the 2nd “/”. First it checks if the parameter is a filename or a
word. If either of these are true then TACL the value in
filename and the value of the bit between brackets is 1 if it's a
filename and 2 if it's a word. If neither is true then uses TACL
the standard error handling and crashes with :
expecting the name of an existing file
or any text up to a standard TACL separator or end
You can avoid that TACL does this standard error-handling with
help of the command OTHERWISE (comparable with the
WHEN OTHER statement of EVALUATE). You can do your
own error-handling and output your own (hopefully more
meaningful!) error messages.
There are very many possibilities after the “/’. Look in the
“TACL REFERENCE MANUAL”, I've only shown a couple
here
Very many Guardian routines give a value back. #ARGUMENT
returns the number of the appropriate type. In the example you
get the value 1 as the parameter is a filename and the value 2 if
the argument is a word.
4) #CASE is similar to evaluate in COBOL85. An alternative is:
#IF type = 1 |THEN| ........ |ELSE| .......
5) [#FILEINFO /OPENNOW /[FILENAME]] and
[#IF [#FILEINFO /CODE/[FILENAME]] = 101

R TACL Cursus 4
English Version
are also very interesting. With the 1st command ask you
Guardian of the file [filename] is open. Guardian responds with
true (value -1 non-null-value) or not true (value 0). This is easy
to test with #IF. The 2nd command doesn't return a true/not true
value, but the filecode of the file.
6) #INPUT waits for input from of the user and gives as value the
input. e.g. #SET filename [#INPUT ...]
7) #MATCH can you use to compare 2 strings. The value returned
is 0 (strings are different) or -1 (strings are the same).

There are a number of differences between TACL routines/macro's


and obey-files. If there's a ?TACL ROUTINE or a ?TACL
MACRO as the 1st row then you see only the output of every row;
in an obey file you see the command and the output. A TACL file
you start with the command RUN; an obey file with the command
OBEY.

The difference between a TACL routine and a TACL macro is that


a routine is parsed just once and a macro twice. Thus it is better to
make your TACLCSTM file a ROUTINE than a macro.

2.2.5 . Struct’s

This are TACL ‘records’. You can make TACL records with DDL
(Data Dictionary Language). This happens in the same way as with
COBOL. Thus if you have DDL source, can you quickly create
TACL struct's e.g. :

1 ?TACL
Output source for TACL is opened on $ZTN0.#WIN0027
2 output def p10559.
Loading Definition P10559
== SCHEMA PRODUCED DATE - TIME : 5/18/90 14:49:49
== Definition P10559 version 1 updated on 05/01/90 at 15:55
== NE05Z00A
?Section P10559 Struct
Begin
== Function-CODE
INT E41330;
== GUARDIAN NUMBER-FILENAME
INT E41331;
== MESSAGE-NUMBER
INT E41332;
== CODE-PROGRAM-RPCN
STRUCT E41333;
BEGIN CHAR BYTE(0:9); END;
== PROGRAM data
== ABEND-indicator
CHAR E41342;
End;
TACL output produced for P10559.

See the TACL manual for a description. See also paragraph 2.2.4.
over TACL & Netbatch for the _completion struct.

2.2.6 . Def’s

Def’s are local versions of TACL-variables. Thus in a


macro/routine you can make local versions of macros, routines,
struct’s etc. which disappear (if you use #FRAME and
#UNFRAME) when the routine finishes.
N.B: END is a useful argument for #ARGUMENT. This means ‘no
argument’ is also valid. We see also the usage of the command
#LOOP. There are 2 versions of this command:
1) #LOOP |while| condition |do| …….
2) #LOOP |do| ….. |until| condition
|while| checks the condition for the loop as it begins. |until|
executes the loop first and then checks the condition after each

R TACL Cursus 5
English Version
loop.

#APPEND ‘appends’ onto a variable; the variable becomes a


list/stack. We'll see more examples later of #APPEND.
#RESULT works only in routine’s. The gives a value back to the
calling routine/macro.
#TIMESTAMP shows how many seconds there have been since
midnight of 31st December 1974. Exciting eh! There are a lot
functions to translate this to something more useful (see the TACL
manual). Here below are a number of examples e.g.
#OUTPUT [#TIMESTAMP]
#OUTPUT [#CONTIME [#TIMESTAMP] ]
#OUTPUT [_CONTIME_TO_TEXT_DATE [#CONTIME [#TIMESTAMP]]]

gives ….

70670204971
1997 5 23 10 7 58 20
May 23, 1997

2.2.7 . Directories

You can organise all TACL-variables in directories. You can


compare them with directories on the PC. The difference between
directories and volumes.subvolumes is, that directories stay in
memory and volumes.subvolumes are on disk. On the Tandem you
use #PMSEARCHLIST in order to tell Guardian where to search for
programs and #USELIST for your TACL variables: e.g.

#SET #PMSEARCHLIST $SYSTEM.SYSTEM $DATS.NE00YRUN


USE :DEANSEG [#USELIST]

Try executing the following 3 commands at the TACL prompt:

#PMSEARCHLIST
#USELIST
ENV

Question: What happens?

SEGINFO is useful to tell you what segments you have attached


and some details about them.

Seginfo……
Pgs Pgs Bytes Bytes
Segment File Access Now Max Now Max % UC
Directory
$datf.#0008763 pr 24 1024 27332 2097152 1
11 :
$system.sys02.taclsegf sh 208 1024 420308 2097152 20
3 :utils.1
$dats.ne00ytcl.interseg sh 112 1024 226700 2097152 10 1
:internet.1
$datf.dean.deanseg sh 332 1024 667960 2097152 31
1 :deanseg.1
$datf.dean.DEANseg sh 616 1024 1257072 2097152 59
1 :DEANseg.1
$datf.dean.DEANseg2 sh 716 1024 1459540 2097152 69
1 :DEANseg2.1

The utils directory/segment $system.sys02.taclsegf contains


Tandem’s TACL’s. If you type “Variables :UTILS” you get as
output the content of the directory. :utils. It's always shared (sh
in the access column) and that means that everyone in this directory
may read, but not write to it. The : is your root directory. When you
#push to create variables or use the LOAD command to load
libraries, they will normally go here. All other directories hang off
the root directory (use “VTREE” to see this).

R TACL Cursus 6
English Version
You load macro’s with:

LOAD /KEEP 1/<file name>

You can change directory with home :<directory>

As you the name of a variable type in, then TACL searches first in
the current directory and after that in every other directory in the
#USELIST. You can type “VARINFO <macro name>“ to see
summary info of a macro/routine/text variable e.g.
VARINFO volume
You can see the content of a macro with of OUTVAR e.g.
OUTVAR volume
OUTVAR OUTVAR
exercise : Try but the above 3 TACL command’s.

2.2.8 . Everything you wanted to know


about variables but were afraid to ask

TACL uses a stack for every variable. Thus as you do this

#PUSH x y z
#SETMANY x y z,1 2 3 == multiple of #SET
#PUSH y z
#OUTPUT [x] [y] [z]

Then get you 1 on the screen because the 2 newest versions of y


and z are empty. You can still see and use the old values :-

#OUTPUT [x.1] [y.1] [z.1]

You can use #POP to delete the new values e.g.


#POP x y z

Question: Can you #POP also use to delete old values? e.g.
#POP x.1

Answer: No, not unless it's the highest in the stack, which it isn't in
this case.

If you use LOAD <file name> without the KEEP 1 option, then
make you always a new copy on top of the old in the stack. If you
do this often then you'll start using up lots of memory!

Question: LOAD /KEEP 0/ <filename> is a valid statement. What


does it do?

2.3 . General TACL tricks

2.3.1 . Be Nice

A user generally prefers that his environment isn't changed after a


macro has ended. Take copies of variables you plan to change e.g
#DEFAULTS (this keeps track of your current subvol). This be
achieved with use of framing & popping:

#PUSH #DEFAULTS ==#DEFAULTS.2 created.


Volume $datf.work ==#DEFAULTS now = $datf.work
............. == the core of your
macro
#POP #DEFAULTS ==back to the subvolume where you
== started NOT on $datf.work

R TACL Cursus 7
English Version
2.3.2 . Error Handling (only routines)

[#CASE [#EXCEPTION]
|_CALL| == normal entry point for this ROUTINE
|_BREAK| == break key handling
#OUTPUT Session terminated
because the break key was hit
#UNFRAME
#RETURN
|_ERROR| #PUSH errtxt
#ERRORTEXT /CAPTURE errtxt/
#OUTPUT Tacl generated error
filtered
#OUTPUT error text contains :
#OUTPUTV ERRTXT
#UNFRAME
#RETURN
] == end of exception case

#FILTER _BREAK _ERROR


<real code begins here……. >

This piece code MUST be on the 1st line in a routine! Otherwise


the error-handling won't work properly!

Question: In the above TACL-variable there's #OUTPUT and


#OUTPUTV. What is the difference between these command's?

2.3.3 . Object Orientated?

With TACL you can quickly build up a library of routines. Make


the routines object-orientated (thus ‘black boxes’), so you can use
them again and again. Give them logical names and use #RESULT
to return true or false values if you can

?SECTION is_valid_define ROUTINE


#FRAME
#PUSH define^name
[#CASE [#ARGUMENT /VALUE define^name/ DEFINENAME WORD
END]
|1| #RESULT -1 == valid define name
|OTHERWISE| #RESULT 0 == invalid define name
]
#UNFRAME

?SECTION is_valid_file ROUTINE


#FRAME
#PUSH filename
[#CASE [#ARGUMENT /VALUE filename/ FILENAME/SYNTAX/ WORD
END]
|1| #RESULT -1 == valid filename
|OTHERWISE| #RESULT 0 == invalid filename
]
#UNFRAME

?SECTION DBU ROUTINE


#FRAME
#PUSH #DEFAULTS options filename #OUTFORMAT
#SET #OUTFORMAT PRETTY
[#IF [#MORE] |THEN|
#SET filename [#REST]
[#IF [is_valid_define =[filename]] |THEN|
< doe something here>
]
[#IF [is_valid_file [filename]] |THEN|
#SET options ,FILE [filename]
|ELSE|
#SET filename [#REST]
]

R TACL Cursus 8
English Version
]
[#IF [#VARIABLEINFO/EXISTENCE/ vol_1] AND
[#VARIABLEINFO/EXISTENCE/ &
env_name] A
< doe here something>
]
#UNFRAME

In the 2 subroutines “is_valid_.....” there is no usage made of


external variables. They give a true/not true value back.

In this example see you also again the usage of #ARGUMENT and
#RESULT.

New command's: #VARIABLEINFO has a number of possibilities.


In this example EXISTENCE checks if a TACL variable exists or
not. This gives always 0 of -1 back. #MORE and #REST are only
useful in routines. With #MORE can you check if there are more
arguments. If there are more arguments available then it gives -1
back, otherwise 0. This is useful if you want to process a list of
files but you don't know how many. With a combination of #LOOP
and #MORE you can process the whole list. #REST returns all of
the unread arguments in one job lot. This is useful as not all
parameters of important are for TACL: e.g.

TEDIT [filename] [#REST] ==#REST has no value of contains


the
parameters for
TEDIT

Questions :
1. The other possibilities of #VARIABLEINFO are in the TACL
manual. What possibilities are there.
2. Write an example that #LOOP and #MORE that uses a list of
filenames to and displays them in a nicer way on the screen. Use
[#FILENAMES] as input e.g.

display_files [#FILENAMES]
3. what do #OUTFORMAT and #INFORMAT do? why in the
DBU example is #OUTFORMAT pushed?

2.3.4 . TACL & Processes & files

EDIT/in infile,out outfile,nowait/


EDIT/inv edit_in DYNAMIC,outv edit_out,nowait/

Maybe can you guess what the 2nd command does as you
(hopefully!) know what the 1st line does. Here can you make good
use of #APPEND and #EXTRACT e.g.
?TACL ROUTINE
#FRAME
#PUSH ipm results edit^level next
fup purgedata $datf.dean.DEANTACL
EDIT /INV ipm DYNAMIC ,OUTV results,NAME, NOWAIT/
SINK [#WAIT ipm]
#SET results
#SET next [#FILENAMES/MAXIMUM 1/*]
[#LOOP |WHILE| NOT [#EMPTYV next] |DO|
[#IF ([#FILEINFO/CODE/[next]] = 101) AND
([#FILEINFO/EOF/[next]] > 0) AND
(NOT [#FILEINFO /OPENNOW/[next]])
|THEN|
#OUTPUT [next]
#APPEND ipm GET [next] put $datf.dean.DEANtemp!
#APPEND ipm CB /?TACL/?SECTION [next]/ A
#APPEND ipm GET $datf.dean.DEANTACL
#APPEND ipm GET $DATF.DEAN.DEANtemp TO L

R TACL Cursus 9
English Version
SINK [#WAIT ipm]
#OUTPUTV results
#SET results
|ELSE|
#OUTPUT Problem with [next]
fi [next]
]
#SET next [#FILENAMES/MAXIMUM 1,PREVIOUS [next]/*]
] == END LOOP
#APPEND ipm EXIT
SINK [#WAIT ipm]
#UNFRAME

DYNAMIC means that the program runs until an exit-command is


received. You can first fill in ipm and after that EDIT /inv
ipm, ......, but if you use the above way than you can do nowaited
processing. You use #APPEND <variable> (<variable is that of
/INV <variable>) to make a list of commands (in the same way as
you type a command in and after that hit return). When there is
something on the input list than EDIT begins (of FUP or whatever
you choose) to process the command. You can add more
commands onto the list and they become processed sequentially
when the scheduler is ready. With nowaited processing you can
give a command to a process. While that command is being
processed you can do something else. You must only use a #WAIT
command when you are ready to process the output of the EDIT
process. You can use #WAIT with input and output variables. With
an input #wait TACL waits until the process has finished all the
commands on it's input queue/stack. With a #wait on an output
variable TACL waits until there is some output in the output
variable (NOT until the process output variable is completely
ready).

Questions:
1. If you type “#WAIT ipm results”, what value do get you back?
2. why is use made of SINK [#WAIT ipm]?

You can also use #SET #TRACE -1 to start the debugger. You can
also use #FILENAMES with the option MAXIMUM. With
maximum 1 and Previous ..... you can process the files 1 for 1 in a
subvolume (See the above example)

FILETOVAR and VARTOFILE are useful if you want to work files


and don't know EDIT very well e.g.

#PUSH file^in^memory
FILETOVAR $DATF.DEAN.TEMP file^in^memory
==process file^in^memory
VARTOFILE file^in^memory $DATF.DEAN.TEMPOUT

FILETOVAR reads a file and puts the content of the file in a


TACL-variable; VARTOFILE works the other way.
LET ON! FILETOVAR and VARTOFILE are TACL (interpreted)
routines. For bigger files you can better use FUP or EDIT.

2.3.5 . Defined Processes

Disk IO is always fairly heavy and slow in comparison with


processing in the memory. FUP, PERUSE etc. are used fairly
often. With help of TACL can you make these processes ‘memory
resident’ with help of ‘define process’; e.g.

?SECTION DPP ROUTINE


DP PERUSE/PNAME P,NOHISTORY,NOSTART,INIT PERUSE_INIT, &
PREPARSE PER_PRE, MACRO P_MAC/ [dp^supervisor]
DPSP

See the appendices for the content of peruse_init, DPSP (Define

R TACL Cursus 10
English Version
Process Spoolcom etc.
PNAME is the abbreviation to talk to the Tandem utility (thus in
this case you use P instead of PERUSE)
You can, as in TACL, use/cancel history with the
HISTORY/NOHISTORY option.
INIT is a macro or routine which is run only once when you start
up PERUSE (in this case) for the 1st time. PREPARSE is very
useful. You can use it to translate your own shortcuts for
commands into the full blown commands.

2.3.6 . Debugging

You can debug TACL code by using of

#SET #TRACE -1

You can type this into the macro or routine you want to debug or
type it in at the TACL prompt and after that you type :

B <macro name>
R
<macro name>

Watch Out : if the macro/routine is in a shared segment then you


get an error message. Just load the macro and then try again

question:
Try to debug the Tandem TACL Routine VOLUME with “#SET
#TRACE -1” and “B VOLUME”.
1. What happens then?
2. why do you think that you get an error message?

2.3.7 . TACL Segments

TACL is interpreted code (thus not compiled). The use of TACL


can heavily tax the system. You must use TACL wisely. There are
3 different ways to execute TACL code:

1) RUN <file name>


2) LOAD / KEEP 1/ <library file>
3) Usage of segment files

With 1) loads TACL the code each time into memory. You use
more disk space as you every TACL macro is in a separate file.
This is handy for testing macros however.
With 2) everyone who loads the library has a copy of all macro’s in
the library. This is quicker but can use a lot of memory.
With 3) the macros are in shared memory so everyone can use the
macros. Further the TACL code in a segment is pre-
processed/compiled and therefore quicker. The attachment to a
segment is far quicker than a LOAD of a TACL library file. A
segment object file has a file code of 440. To use a segment do the
following:

ATTACHSEG SHARED $DATF.DEAN.DEANSEG :DEANSEG


USE :DEANSEG [#USELIST]

If you type in #USELIST at the TACL prompt then you see the
updated value of it :-
#USELIST

The ‘use’-command tells TACL where to look for TACL routines.


If you LOAD TACL libraries, by default the routines get loaded
into your default TACL directory and are they not usable by other

R TACL Cursus 11
English Version
people.

See the create^segment command in the appendices if you want to


know how you make a segment file.

Macro's are slower than routines. A macro must twice read become
because TACL the %1% etc. must be replaced by the parameters.
Macro's are also less readable. Use macro's only for small pieces of
code.

2.3.8 . TACL & Netbatch

Netbatch (Tandem’s Batch scheduler) uses TACL as default


executor (you can also DDL, COBOL85 etc. use). A average
TACL batch file (actually a normal obey file), looks like this .

#OUTPUT Netbatch in file for BT0666CB


RUN [object^vol].BT0666CB
[#IF [_completion:completioncode] = 0 |THEN|
#output completed :
[#IF [#INTERACTIVE]|THEN|
== Not running under Netbatch
#OUTPUT Interactive operation - no release attempted
|else|
zbat:release * == release dependent program’s
]
|ELSE|
#OUTPUT FAILURE CONTACT SUPPORT NOW :
] == end if

There are a couple of unusual TACL command's for Netbatch.


JOBID 0 (part of the RUN command) makes a program
independent of the batch job i.e. It keeps running when the batch
job ends. Otherwise, when a batch job ends normally, then TACL
tries to stop ALL processes started by the batch job. With JOBID
0 the program runs independently and keeps running after the end
of the batch job.
You can use #INTERACTIVE to check if your job is running
under Netbatch or interactively.
ZBAT:RELEASE kicks off the dependent batch program(s) run.
The dependency are sorted out in Netbatch by WAITON.

_completion is a struct that looks after the completion information


of the program. If you type “#SET #PMSG -1” then TACL shows
this information after the shut down of a program.

Question:
What are the possible values of _completion:completioncode?

R TACL Cursus 12
English Version
3. Appendices

3.1 . create^segment
?SECTION create^segment ROUTINE
==#FRAME don't use frame because unframe will pop the segment!
[#CASE [#EXCEPTION]
|_CALL| == normal entry point for this ROUTINE

|_BREAK| == break key handling


#OUTPUT
#OUTPUT Session terminated because the break key was hit ...
[#IF [#VARIABLEINFO/EXISTENCE/ :tempseg]
|THEN|
DETACHSEG :tempseg
]
SINK [#PURGE TEMPSEG]
#RETURN
|_ERROR| #PUSH errtxt
#ERRORTEXT /CAPTURE errtxt/
#OUTPUT
#OUTPUT Tacl generated error filtered
#OUTPUT error text contains :
#OUTPUTV ERRTXT
[#IF [#VARIABLEINFO/EXISTENCE/ :tempseg]
|THEN|
DETACHSEG :tempseg
]
SINK [#PURGE TEMPSEG]
#RETURN
] == end of exception case

#FILTER _BREAK _ERROR

home :
#PUSH segment^name backup^name n dest_vol older^backup^name file buffer

[#DEF do^env^segs ROUTINE


|BODY|
#OUTPUT Ignore any complaints here unless defines in segment file
#PUSH run_type_eodeom env_date env_jdate env_month
set^environment^dates
]

SINK [#ARGUMENT /TEXT segment^name/ WORD END]


[#LOOP |WHILE| [#EMPTYV segment^name] OR [#CHARCOUNT
segment^name] > 8 |DO|
#OUTPUT There are some commonly used segments already defined but this
#OUTPUT routine will cater for an individual's segment
#OUTPUT Type DEFINES as the segment name to regenerate the defines for
[env_name]
#SET segment^name [#INPUT Please enter segment name to be regenerated?_]
]

[#IF [#VARIABLEINFO/EXISTENCE/ :tempseg]


|THEN|
DETACHSEG :tempseg
]
#OUTPUT Purging TEMPSEG and creating new one
SINK [#PURGE TEMPSEG]
CREATESEG TEMPSEG
FUP /OUTV buffer/ SECURE TEMPSEG, "NNNN"
ATTACHSEG PRIVATE TEMPSEG :TEMPSEG
HOME :TEMPSEG
[#CASE [segment^name]
|DSAPSEG| #OUTPUT Creating DSAPSEG
#PUSH :output :pointer #DEFAULTS
[#DEF :dsap^out STRUCT
BEGIN
CHAR disk (0:7);
FILLER 28;
CHAR free^percent (0:2);
FILLER 4;
CHAR frag^count (0:4);
FILLER 5;
CHAR biggest^ext (0:25);
END;
]

R TACL Cursus 13
English Version
#SET dest_vol $SYSTEM.BPTACL
DSAP /OUTV output/$*,SHORT
#SET pointer [#LINEFIND output 1 $]
#SET pointer [#COMPUTE [pointer] - 1]
#LINEDEL output 1 FOR [pointer]
[#LOOP |DO|
#EXTRACTV output dsap^out
[#DEF :TEMPSEG:[dsap^out:disk(1:7)] DIRECTORY]
HOME :TEMPSEG:[dsap^out:disk(1:7)]
#PUSH old^files big^files
DSAP /OUTV old^files/[dsap^out:disk(0:7)],OPENED
[dsap^age],BYUSER,DETAIL
DSAP /OUTV big^files/[dsap^out:disk(0:7)],SIZE OVER
2441,BYUSER,DETAIL
== Display all old files and all files over 5 Meg
|UNTIL| [#EMPTYV output]
]

|LOGSEG| #OUTPUT loading GLOPTLIB


SINK [#LOAD/KEEP 1/$DATA.DEAN.GLOPTLIB]
#OUTPUT loading CONTTLIB
SINK [#LOAD/KEEP 1/$DATA.DEAN.CONTTLIB]
#OUTPUT loading tapeback
SINK [#LOAD/KEEP 1/$DATA.DEAN.tapeback]
#SET dest_vol $DATA.DEAN

|DEFINES | #SET dest_vol $SYSTEM.BPTACL


#SET segment^name [env_name]DEFS
do_defines == takes some time - loads the defines etc

|OTHERWISE|
on You have chosen to create a strange new lifeform
on
on Do not use this for new environment segments as they
on must be added to the list first...see Dean
on
on At each prompt type in the name of the tacl file to load
on When you have finished, hit return with nothing entered
#SET file [#INPUT Load which file ?_]
[#LOOP |WHILE| NOT [#EMPTYV file] |DO|
LOAD/KEEP 1/[file]
#SET file [#INPUT Load which file ?_]
]
#SET dest_vol [#INPUT Which $VOL.SUBVOL do you want me to the
put segment on?]
]
DETACHSEG :TEMPSEG

#set n 9
#SET backup^name [#CHARGET segment^name 1 FOR 7]
#SET backup^name [backup^name][n]
SINK [#PURGE [dest_vol].[backup^name]]
[#LOOP |DO|
#SET older^backup^name [#CHARGET segment^name 1 FOR 7]
#SET older^backup^name [older^backup^name][n]
#SET n [#COMPUTE [n] - 1]
#SET backup^name [#CHARGET segment^name 1 FOR 7]
#SET backup^name [backup^name][n]
[#IF [#PURGE [dest_vol].[backup^name]] = 12 |THEN|
RENAME [dest_vol].[backup^name] [dest_vol].[older^backup^name]
]
|UNTIL| [n] <= 1
]
[#IF [#PURGE [dest_vol].[segment^name]] = 12
|THEN|
RENAME [dest_vol].[segment^name] [dest_vol].[backup^name]
]

FUP /OUTV buffer/ DUP TEMPSEG,[dest_vol].[segment^name]


SINK [#PURGE tempseg]
#OUTPUT Securing [dest_vol].[segment^name]
FUP /OUTV buffer/ SECURE [dest_vol].[segment^name], "Nnnn"

[#IF [#VARIABLEINFO/EXISTENCE/ :[segment^name]]


|THEN|
DETACHSEG :[segment^name]
]

ATTACHSEG SHARED [dest_vol].[segment^name] :[segment^name]


USE :[segment^name] [#USELIST]
#OUTPUT [dest_vol].[segment^name] successfully defined

R TACL Cursus 14
English Version
ENV
#POP segment^name backup^name n dest_vol older^backup^name

3.2 . Defined Processes


?SECTION PERUSE_INIT ROUTINE
#OUTPUT Peruse no longer does a J on entry so that you now can
have access to
#OUTPUT PERUSAL! By typing # or # <command> you can pass
commands between
#OUTPUT PERUSE and SPOOLCOM.

?SECTION P_MAC MACRO


DP^MACRO P

?SECTION PER_PRE ROUTINE


#PUSH in_cmd
[#IF [#ARGUMENT/TEXT in_cmd/ TEXT END]]
[#IF NOT [#EMPTYV in_cmd] |THEN|
[#IF [#COMPAREV "#" "[#CHARGET in_cmd 1]"]
|THEN|
#CHARDEL in_cmd 1
SPOOLCOM [in_cmd]
#SET :DPCOMMAND
|ELSE|
#SETMANY in_cmd, [in_cmd]
[#CASE [in_cmd]
|D | #SET :DPCOMMAND DEL
|D* | SPOOLCOM JOB (OWNER),DELETE
#SET :DPCOMMAND
|D*!| SPOOLCOM JOB (OWNER),DELETE!
#SET :DPCOMMAND
|JN | #SET :DPCOMMAND
|HA | #SET :DPCOMMAND HOLDAFTER
|HAO| #SET :DPCOMMAND HOLDAFTER OFF
|PRINT| #SET :DPCOMMAND L EDIT/OUT PRINTEMP/A
SINK [#WAIT :DPCOMMAND]
FUP COPY PRINTEMP,[default^printer]
PURGE PRINTEMP
|E EXIT | #LINEDEL :DPCOMMAND 1 FOR 1
#OUTPUT Please use CTRL-Y to exit. Sorry for the
inconvenience..
|OTHERWISE|
]
]
]
#POP in_cmd

?SECTION DPSP ROUTINE


DP SPOOLCOM/NOSTART,MACRO SP_MAC,PREPARSE
SPOOLCOM^PREPARSE/ [dp^supervisor]

?SECTION SPOOLCOM^PREPARSE ROUTINE


#FRAME
#PUSH in_cmd
[#IF [#ARGUMENT/TEXT in_cmd/ TEXT END]]
[#IF NOT [#EMPTYV in_cmd] |THEN|
[#IF [#COMPAREV "#" "[#CHARGET in_cmd 1]"]
|THEN|
#CHARDEL in_cmd 1
P [in_cmd]
#SET :DPCOMMAND
|ELSE|
#SETMANY in_cmd, [in_cmd]
[#CASE [in_cmd]
|D* | #SET :DPCOMMAND JOB (OWNER),DELETE
|D*!| #SET :DPCOMMAND JOB (OWNER),DELETE!
|E EXIT | #LINEDEL :DPCOMMAND 1 FOR 1
#OUTPUT Please use CTRL-Y to exit. Sorry for the
inconvenience.
|OTHERWISE|
]
]
]
#UNFRAME

?SECTION SP_MAC MACRO

R TACL Cursus 15
English Version
DP^MACRO SPOOLCOM

R TACL Cursus 16
English Version

You might also like