Copyright 1989-2016 by Kevin G. Barkes
All rights reserved. This article may be duplicated or
redistributed provided no alterations of any kind are
made to this file.
This edition of DCL Dialogue is sponsored by Networking
Dynamics, developers and marketers of productivity software
for OpenVMS systems. Contact our website
www.networkingdynamics.com to download free demos of
our software and see how you will save time, money and
raise productivity! Be sure to mention DCL Dialogue!
DCL DIALOGUE
Originally published July, 1989
By Kevin G. Barkes
Don't Quote Me
Everyone has a pet peeve. Mine is excessive use of quotes in
DCL.
By "excessive", I mean placing quotes around DCL symbols in
locations where their use is superfluous, or forcing
substitutions with the apostrophe (') when such
substitution is unnecessary.
For a definitive discussion on the topic, refer to DEC's
"DCL Concepts" manual. In any event, here's a brief lowdown
on quoting rules in DCL:
ASSIGNMENT USE:
Symbols are assigned by using =, ==, := and :==. The = and
:= assign local symbols, while == and :== make global
symbol assignments.
When you use = or == to assign a string value to a symbol,
you must enclose the value being assigned in quotes:
$ COMMAND1 = "WRITE SYS$OUTPUT"
$ SHOW SYMBOL COMMAND1
COMMAND1 = "WRITE SYS$OUTPUT"
If you forget the quotes, you'll get:
$ COMMAND1 = WRITE SYS$OUTPUT
%DCL-W-UNDSYM, undefined symbol - check validity and spelling
\WRITE\
That's because DCL thinks the word WRITE is another symbol.
After all, you didn't enclose the phrase in quotes, which
is how the = determines if the value is a string.
If you need to include quotes in the symbol, you have to
enclose the quotes within quotes:
$ TEXT1 = "Drive, he said."
$ WRITE SYS$OUTPUT TEXT1
Drive, he said.
$ TEXT2 = """Drive, "" he said."
$ WRITE SYS$OUTPUT TEXT2
"Drive, " he said.
Note in the above examples there are no quotes or
apostrophes around the symbols TEXT1 or TEXT2. That's
because WRITE is one of the commands which can accept a
symbol as a command parameter.
You can save omit the quotes if you use := or :==, the
special string assignment operators:
$ COMMAND2 := write sys$output
$ SHOW SYMBOL COMMAND2
COMMAND2 = WRITE SYS$OUTPUT
$ TEXT1 := Drive, he said.
$ WRITE SYS$OUTPUT TEXT1
DRIVE, HE SAID.
In addition to assigning a string to a symbol, the := also
converts the string to all upper case, compresses multiple
spaces and tabs into single spaces, and trims any trailing
spaces.
If you don't want DCL to do any conversions, enclose the
string in quotes:
$ TEXT1 := "Drive, he said."
$ WRITE SYS$OUTPUT TEXT1
Drive, he said.
To include quotes in the symbol,
$ TEXT1 := """Drive, "" he said."
$ WRITE SYS$OUTPUT TEXT1
"Drive, " he said.
Watch what happens when we incorrectly place the quotes:
$ TEXT1 := "Drive, " he said.
$ WRITE SYS$OUTPUT TEXT1
Drive, HE SAID.
In this case, DCL preserved "Drive ,", since it was enclosed
in quotes, but converted the "he said", which was unquoted,
to all caps.
In the above example, we could have formatted the WRITE
commands as:
$ WRITE SYS$OUTPUT "''TEXT1'"
But why bother? WRITE can handle symbols all by itself.
MORE THAN WRITE
The WRITE command isn't the only one which can deal with
symbols without excessive quotes and apostrophes.
DEPOSIT, EXAMINE and IF automatically evaluate symbols
contained in their command line. DEPOSIT and EXAMINE are a
trifle obscure for the typical DCL user, so let's look at
IF:
$ VAL = 1
$ TEXT = "TRUE"
$ IF VAL .EQ. 1 THEN WRITE SYS$OUTPUT TEXT
TRUE
IF was able to tell that VAL was a symbol and, of course,
WRITE could handle the symbol TEXT with no problem.
Symbols are legal arguments to lexical functions as well:
$ FILE := LOGIN.COM
$ TYPE := UIC
$ VAL = F$FILE(FILE,TYPE)
$ WRITE SYS$OUTPUT VAL
[GROUP,USER]
Not a quote or apostrophe in sight. You could have entered:
$ VAL = F$FILE("''FILE'","''TYPE'")
as well. In a command procedure with SET VERIFY turned on, the line would
appear as
$ VAL = F$FILE("LOGIN.COM","UIC")
as the procedure executed. This is okay for debugging
purposes, but for the sake of efficiency and proper coding
technique, you should eliminate the excess baggage in the
final version of the file.
AN EXTREME EXAMPLE:
TTT.COM (Program 1) is a DCL version of the game
Tic-Tac-Toe. It's also an example of DCL code pared down to
an absolute minimum. Command names have been shortened as
much as possible, symbol and label names have been kept to
minimal size and comments are practically non-existant.
The original source for this game is about twice as large;
this is the "production" version, stripped down for speed.
Note there are very few quotes or apostrophes in the file;
the only places where they're used are in symbol
definitions and as the prompting text for the INQUIRE
command, which does not accept symbols.
I wrote this command file to prove to a UNIX afficiando that
DCL can be as unreadable as a UNIX shell script, and also
as an example of nontraditional uses of DCL for my "DCL
Diversions" session at the recent DECUS symposium in
Atlanta.
$! TTT_DCL -- See info at end of file.
$ GOT END
$B:
$ T := WR SYS$OUTPUT
$ O = "O"
$ O1 = ".OO"
$ O2 = "O.O"
$ O3 = "OO."
$ P = "."
$ Q1 = "Your play..."
$ Q2 = "> "
$ Q3 = "N"
$ Q4 = "Q"
$ Q5 = "Congratulations! You win!"
$ Q6 = "Play again? "
$ Q7 = "Sorry, I win."
$ Q8 = "Tie game."
$ Q9 = "Illegal move. Try again."
$ Q0 = "Thanks for playing."
$ QA = "Beginning new game..."
$ S = " "
$ WP = "XXX"
$ X = "X"
$ X1 = ".XX"
$ X2 = "X.X"
$ X3 = "XX."
$ Z = ""
$ GOS V
$! Initialization
$IN:
$ P1 = P
$ P2 = P
$ P3 = P
$ P4 = P
$ P5 = P
$ P6 = P
$ P7 = P
$ P8 = P
$ P9 = P
$ T QA
$!
$!
$N:
$ T Q1
$ INQ/NOP M "''Q2'"
$ IF M .EQS. Z .OR. -
F$LE(M) .GT. 1 THEN GOT E
$ IF M .EQS. Q3 THEN GOT IN
$ IF M .EQS. Q4 THEN GOT Q
$ IF F$IN(M) .EQ. 0 THEN GOT E
$ IF P'M' .NES. P THEN GOT E
$ P'M' = X
$ GOS BB
$ IF F$LOC(P,BD) .EQ. 9 -
THEN GOT TIE
$ GOS DB
$ GOS CW
$ IF W THEN GOT HW
$! Grab center square, if available.
$ IF P5 .NES. P THEN GOT W
$ P5 = O
$ GOS BB
$ GOS DB
$ GOT N
$W:
$ GOS DW
$ GOS WB
$ IF MV THEN GOT N
$ GOS GC
$ GOS BB
$ GOS DB
$ GOT N
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$! SUBROUTINES !
$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
$BB:
$ BD = P1+P2+P3+P4+P5+P6+P7+P8+P9
$ RET
$!
$! Display the board:
$DB:
$ T Z
$ T S+P1+S+P2+S+P3
$ T S+P4+S+P5+S+P6
$ T S+P7+S+P8+S+P9
$ T Z
$ RET
$!
$! Is move a winner?
$CW:
$ W = 0
$! Check horizontally:
$ IF P1+P2+P3 .EQS. WP THEN W=1
$ IF P4+P5+P6 .EQS. WP THEN W=1
$ IF P7+P8+P9 .EQS. WP THEN W=1
$ IF W THEN RET
$! Check vertically:
$ IF P1+P4+P7 .EQS. WP THEN W=1
$ IF P2+P5+P8 .EQS. WP THEN W=1
$ IF P3+P6+P9 .EQS. WP THEN W=1
$ IF W THEN RET
$! Check diagonally:
$ IF P1+P5+P9 .EQS. WP THEN W=1
$ IF P3+P5+P7 .EQS. WP THEN W=1
$ RET
$!
$WB:
$ MV = 0
$ OB = BD
$ R = P1+P2+P3
$ IF R .EQS. X1 THEN P1 = O
$ IF R .EQS. X2 THEN P2 = O
$ IF R .EQS. X3 THEN P3 = O
$ IF R .NES. P1+P2+P3 THEN GOT BN
$ R = P4+P5+P6
$ IF R .EQS. X1 THEN P4 = O
$ IF R .EQS. X2 THEN P5 = O
$ IF R .EQS. X3 THEN P6 = O
$ IF R .NES. P4+P5+P6 THEN GOT BN
$ R = P7+P8+P9
$ IF R .EQS. X1 THEN P7 = O
$ IF R .EQS. X2 THEN P8 = O
$ IF R .EQS. X3 THEN P9 = O
$ IF R .NES. P7+P8+P9 THEN GOT BN
$ R = P1+P4+P7
$ IF R .EQS. X1 THEN P1 = O
$ IF R .EQS. X2 THEN P4 = O
$ IF R .EQS. X3 THEN P7 = O
$ IF R .NES. P1+P4+P7 THEN GOT BN
$ R = P2+P5+P8
$ IF R .EQS. X1 THEN P2 = O
$ IF R .EQS. X2 THEN P5 = O
$ IF R .EQS. X3 THEN P8 = O
$ IF R .NES. P2+P5+P8 THEN GOT BN
$ R = P3+P6+P9
$ IF R .EQS. X1 THEN P3 = O
$ IF R .EQS. X2 THEN P6 = O
$ IF R .EQS. X3 THEN P9 = O
$ IF R .NES. P3+P6+P9 THEN GOT BN
$ R = P1+P5+P9
$ IF R .EQS. X1 THEN P1 = O
$ IF R .EQS. X2 THEN P5 = O
$ IF R .EQS. X3 THEN P9 = O
$ IF R .NES. P1+P5+P9 THEN GOT BN
$ R = P3+P5+P7
$ IF R .EQS. X1 THEN P3 = O
$ IF R .EQS. X2 THEN P5 = O
$ IF R .EQS. X3 THEN P7 = O
$ IF R .NES. P3+P5+P7 THEN GOT BN
$ RET
$BN:
$ MV = 1
$ GOS BB
$ GOS DB
$ RET
$!
$ DW:
$ MV = 0
$ OB = BD
$ R = P1+P2+P3
$ IF R .EQS. O1 THEN P1 = O
$ IF R .EQS. O2 THEN P2 = O
$ IF R .EQS. O3 THEN P3 = O
$ IF R .NES. P1+P2+P3 THEN GOT WD
$ R = P4+P5+P6
$ IF R .EQS. O1 THEN P4 = O
$ IF R .EQS. O2 THEN P5 = O
$ IF R .EQS. O3 THEN P6 = O
$ IF R .NES. P4+P5+P6 THEN GOT WD
$ R = P7+P8+P9
$ IF R .EQS. O1 THEN P7 = O
$ IF R .EQS. O2 THEN P8 = O
$ IF R .EQS. O3 THEN P9 = O
$ IF R .NES. P7+P8+P9 THEN GOT WD
$ R = P1+P4+P7
$ IF R .EQS. O1 THEN P1 = O
$ IF R .EQS. O2 THEN P4 = O
$ IF R .EQS. O3 THEN P7 = O
$ IF R .NES. P1+P4+P7 THEN GOT WD
$ R = P2+P5+P8
$ IF R .EQS. O1 THEN P2 = O
$ IF R .EQS. O2 THEN P5 = O
$ IF R .EQS. O3 THEN P8 = O
$ IF R .NES. P2+P5+P8 THEN GOT WD
$ R = P3+P6+P9
$ IF R .EQS. O1 THEN P3 = O
$ IF R .EQS. O2 THEN P6 = O
$ IF R .EQS. O3 THEN P9 = O
$ IF R .NES. P3+P6+P9 THEN GOT WD
$ R = P1+P5+P9
$ IF R .EQS. O1 THEN P1 = O
$ IF R .EQS. O2 THEN P5 = O
$ IF R .EQS. O3 THEN P9 = O
$ IF R .NES. P1+P5+P9 THEN GOT WD
$ R = P3+P5+P7
$ IF R .EQS. O1 THEN P3 = O
$ IF R .EQS. O2 THEN P5 = O
$ IF R .EQS. O3 THEN P7 = O
$ IF R .NES. P3+P5+P7 THEN GOT WD
$ RET
$WD:
$ MV = 1
$ GOS BB
$ GOS DB
$ GOT WC
$!
$GC:
$ IF P1 .NES. P THEN GOT G3
$ P1 = O
$ RET
$G3:
$ IF P3 .NES. P THEN GOT G7
$ P3 = O
$ RET
$G7:
$ IF P7 .NES. P THEN GOT G9
$ P7 = O
$ RET
$G9:
$ IF P9 .NES. P THEN RET
$ P9 = O
$ RET
$!
$ V:
$ TY SYS$INPUT:
This command procedure plays Tic-Tac-Toe.
Your mark is X and you will play first.
The board is numbered as follows:
1 2 3
4 5 6
7 8 9
When it is your turn to play, enter the
number of the square you wish to mark.
For example, if you type "5", the
result is:
. . .
. X .
. . .
You may start a new game by typing N
or quit by typing Q.
$ RET
$HW:
$ GOS DB
$ T Q5
$ INQ/NOP A "''Q6"
$ IF A THEN GOT IN
$ GOT Q
$!
$WC:
$ T Q7
$ INQ/NOP A "''Q6'"
$ IF A THEN GOT IN
$ GOT Q
$!
$TIE:
$ GOS DB
$ T Q8
$ INQ/NOP A "''Q6'"
$ IF A THEN GOT IN
$ GOT Q
$!
$E:
$ T Q9
$ GOT N
$!
$Q:
$ T Q0
$ EXI
$END:
$ GOT B
$! TTT_DCL
$! DCL version of Tic-Tac-Toe
$! Loosely based on algorithms contained
$! in the book "String and List
$! Processing in SNOBOL" by
$! Ralph E. Griswold and the SNOBOL4+ code
$! developed and copyrighted by Mark Emmer
$! of Catspaw, Inc.
$!
$! Copyright (C) 1999 by
$! Kevin G. Barkes
$! 1512 Annette Ave
$! Library, PA 15129
$! 412-854-2550 (Voice)
$! 412-854-4707 (Facsimile)
$! All rights reserved. No restriction on
$! non-commercial distribution. This
$! software is guaranteed to suck up cpu
$! time. No other warranties are made or
$! implied.
*********************
Kevin G. Barkes is an independent consultant. He publishes
the KGB Report newsletter, operates the www.kgbreport.com website,
lurks on comp.os.vms, and can be reached at kgbarkes@gmail.com.