Вы находитесь на странице: 1из 22

BASIC TACL COURSE

ENGLISH VERSION,
MARCH 2005
title Beginners TACL Course

version, date English Version, t September jjjj

Author Dean Southall – dean.southall@gmail.com


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

ENGLISH VERSION, .......................................................................1

ENGLISH VERSION, .......................................................................1

ENGLISH VERSION, .......................................................................1

ENGLISH VERSION, .......................................................................1

ENGLISH VERSION, .......................................................................1

ENGLISH VERSION, .......................................................................1

ENGLISH VERSION, .......................................................................1

ENGLISH VERSION, .......................................................................1

MARCH 2005......................................................................................1

MARCH 2005......................................................................................1

MARCH 2005......................................................................................1

MARCH 2005......................................................................................1

MARCH 2005......................................................................................1

MARCH 2005......................................................................................1

MARCH 2005......................................................................................1

MARCH 2005......................................................................................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....................................................................................6

R Beginners TACL Course English Version 1


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.................................................................8
2.3.1 . Be Nice................................................................................8
2.3.2 . Error Handling (only routines)........................................8
2.3.3 . Object Orientated?............................................................9
2.3.4 . TACL & Processes & files..............................................10
2.3.5 . Defined Processes..........................................................12
2.3.6 . Debugging........................................................................12
2.3.7 . TACL Segments................................................................13
2.3.8 . TACL & Netbatch............................................................13
3. APPENDICES................................................................................15
3.1 . create^segment........................................................................15
3.2 . Defined Processes...................................................................18

R Beginners TACL Course English Version 2


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

R TACL Cursus 4
English Version
(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
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

R TACL Cursus 5
English Version
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 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

R TACL Cursus 6
English Version
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).

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 :-

R TACL Cursus 7
English Version
#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

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

R TACL Cursus 8
English Version
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 9
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

R TACL Cursus 10
English Version
#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
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

R TACL Cursus 11
English Version
==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 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?

R TACL Cursus 12
English Version
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 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

R TACL Cursus 13
English Version
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 14
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?_]

R TACL Cursus 15
English Version
]

[#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;
]
#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

R TACL Cursus 16
English Version
|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
ENV
#POP segment^name backup^name n dest_vol older^backup^name

R TACL Cursus 17
English Version
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|

R TACL Cursus 18
English Version
#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


DP^MACRO SPOOLCOM

R TACL Cursus 19
English Version

Вам также может понравиться