IITS Logo IITS Home Page spacer FeedBack Site Map Search IITS Concordia University Home Page
IITS Welcome General Information Help & Documentation IITS Services

IITS HelplineVMS Beginner's FAQ


[top] [previous] [next]

5. DCL


What is...

1. What is DCL?

DCL stands for Digital Command Language. It is the primariy command line interface on OpenVMS systems. DCL is in charge of interpreting commands entered either interactively from a terminal, or read form a command procedure.

[up]

2. What is a DCL procedure?

Often the same series of DCL commands need to be issued many times, or some action needs to be automated. By placing a series of DCL commands in a file these goals can be attained. DCL supports control logic (IF, GOTO, CALL, etc.) so that quite complicated programs can be written in it, if need be.

Example DCL procedure (finds all organization:sequential files in a directory - not a terribly useful thing to do!):

   $!first line of DCL procedure: search_example.com
   $!P1 is a search string
   $ if(P1 .nes. "")
   $ then
   $   string = P1
   $ else
   $   string = "*.*"
   $ endif
   $top:
   $ file = f$search(string)
   $ if (file .eqs. "")then exit
   $ org = f$file_attributes(file,"ORG")
   $ if (org .eqs. "SEQ")then write sys$output file
   $ goto top
   $!last line of DCL procedure

   $ @SEARCH_EXAMPLE        Default, look at everything in local directory
   $ @SEARCH_EXAMPLE [.SUBDIR]*.TXT
                                  Look where indicated
   $ SUBMIT/LOG=SYS$LOGIN:/NOPRINT/AFTER=20:00 SEARCH_EXAMPLE
                    Default, but do in batch, after 8:00 PM
   $ SUBMIT/LOG=SYS$LOGIN:/NOPRINT/AFTER=20:00 -
   $_/PARAMETER=("[.SUBDIR]*.TXT")SEARCH_EXAMPLE
                    Look where indicated, in batch after 8:00 PM

[up]

3. Why would I ever use a DCL procedure?

You would use one if you don't want to type the same thing over and over, if you want something to happen when you aren't around, or if you need to do some processing and/or calculations, but not manually.

[up]


How do I...

1. How do I create a DCL procedure?

Use the same tools as for any other file.

[up]

2. How do I pass parameters into a DCL procedure interactively?

You can pass up to eight parameters to a DCL procedure.

   $ @procedure A B C D E F G H

Note: If any parameter A through H contains case sensitive values or spaces, enclose it in double quotes.

[up]

3. How do I pass parameters into a DCL procedure when it runs in batch?

You can pass up to eight parameters to a DCL procedure which is run in batch:

   $ SUBMIT/parameter=(A,B,C,D,E,F,G,H) procedure

Note: If any parameter A through H contains case sensitive values or spaces, enclose it in double quotes.

[up]

4. How do I see parameters inside a DCL procedure?

Inside a DCL command file they will appear as symbols, named P1 through P8.

Here is a common trick:

   $ if(P1 .eqs. "")
   $ then
   $!   There was no P1 parameter
   $ else
   $!   There was a P1 parameter
   $ endif

Note that other global symbols (those defined with :== or == before the procedure is run) may also be used inside a procedure. However, the proper way to test for one of these is like this:

   $ if("''SOME_GLOBAL_SYMBOL'" .eqs. "")

The "''symbol'" form must be used with global symbols because otherwise if one were not defined the procedure would generate an error like this:


  Undefined symbol - check validity and spelling
    \SOME_GLOBAL_SYMBOL\

The simpler form can be used for P1 through P8 because when a procedure starts, DCL creates all eight symbols automatically (even those that were not specified on the command line, which are set to "").

[up]

5. How do I control the flow of the procedure?

Here are some examples of the control structures in DCL, for more information on each use HELP:

   $ ON condition THEN action

   $ IF (expression) THEN action

   $ IF (expression)
   $ THEN
   $! action1
   $ ELSE
   $  action2
   $ ENDIF

   $ TOP:            This is a label, note the colon.
   $ GOTO TOP        This is a goto, not the lack of a colon.

Note 1: As for command procedures, up to eight parameters may be passed to a subroutine. This form is roughly equivalent to creating a separate file and executing it via "@filename parameters". Here is an example, note especially the SUBROUTINE and ENDSUBROUTINE lines:

   $ SUB1: SUBROUTINE Begin a subroutine declaration.
   $! a bunch of commands that compose the subroutine
   $ EXIT             Exit point for subroutine.
   $ ENDSUBROUTINE    End subroutine declaration.
   $ CALL SUB1 A B C D E F G H

Note 2: There is another form of subroutine, a labeled subroutine, that runs at the same level as the calling program. One cannot pass parameters to them. Not is there a need to - they have direct access to all locally defined variables. Here is an example of this second type of subroutine In the following example of this second type of subroutine, note in particular that the transfer of control to the subroutine is via a GOSUB rather than a CALL, that the SUBROUTINE and ENDSUBROUTINE lines are absent, and the use of RETURN instead of EXIT:

   $ SEMISUB1:        Begin a labeled subroutine.
   $! a bunch of commands that compose the subroutine
   $ RETURN [value]   Exit point for subroutine.
   $!
   $ GOSUB SEMISUB

[up]

6. How do I manipulate symbols?

There are a lot things that one can do with symbols. Here is a not particularly useful piece of code that shows some of them.

   $ INQUIRE string "This is a prompt, enter a string"
   $! echo the string to the terminal, note that it has gone to all upper case
   $ WRITE SYS$OUTPUT string
   $! echo the string to the terminal, show what quotes do in double quotes
   $ WRITE SYS$OUTPUT "This is a ''string'"
   $! Here's a lexical function - learn them, love them
   $ x = f$length(string)
   $ WRITE SYS$OUTPUT "''string' is ''x' characters long"
   $! one more time, same output, different method
   $ WRITE SYS$OUTPUT string," is ",x," characters long"
   $ write sys$output "Here is ''string' in all lower case, no spaces",-
   F$edit(string,"LOWERCASE,COLLAPSE")
   $!
   $! invert string order
   $!
   $ ix = X - 1
   $ OUTSTRING=""
   $ TOP:
   $   OUTSTRING = OUTSTRING + F$EXTRACT(ix, 1, string)
   $   ix = ix - 1
   $   if (ix .ge. 0)then goto top
   $ write sys$Output "''string' backwards is: ''outstring'"
   $!
   $! more fun with strings, replace part of a string
   $!
   $ frag = "this is a long string"
   $ frag[0,4] := THIS
   $ write sys$output "this is frag now: ''frag'"
   $!
   $! remove a piece and glue on another one
   $!
   $ where :== disk:[DIR.SUBDIR1]
   $ where = where - "]" + ".SUBDIR2]filename"
   $ write sys$Output "Where is ''where'"
   $!
   $! ring a bell on the user's terminal
   $!
   $ bell[0,7]=7
   $ write sys$output "You should hear a bell''bell'"

[up]

7. How do I manipulate logical names?

Use DEFINE, ASSIGN, DEASSIGN and sometimes SHOW LOGICAL or F$TRNLNM("logical_symbol_name").

Examples:

   $ DEFINE there DISK1:[USERS.FRED]
            Define a logical value specifying a location.
   $ ASSIGN DISK1:[USERS.FRED] there
            Same effect as preceding command.
   $ DEFINE avalue "This is a string that some program needs"
   $ SHOW LOG avalue
     "AVALUE" = "This is a string that some program needs" (LNM$PROCESS_TABLE)
   $ DEASSIGN avalue      Get rid of the logical name.

[up]

8. How do I gather information about files, processes, the system, etc.?

Use lexical functions. For more information use:

   $ HELP LEXICAL   Look up info on lexical functions.

See in particular:

  F$FILE_ATTRIBUTES      Get file information
  F$GETDVI               Get device information
  F$GETJPI               Get job and process information
  F$GETQUI               Get batch and print job information
  F$GETSYI               Get local system information

[up]

9. How do I bury untypable values in symbols??

10. How do I make text blinking, underlined, and so forth?

To put things like {bell} or {escape} into a text string one must use a special symbol definition syntax. Note that the symbol must not have been previously defined or this will NOT work.

   $ bell[0,7]=7
   $ esc[0,7]=27
   $ write sys$output "''esc'[5mblinking''esc'[m and beeping ''bell'"

The list of escape codes for various terminals is in SYS$SYSTEM:SMGTERMS.TXT, where {$} is used for {escape}. Note that the user's terminal must understand VT type escape codes to respond properly. You can and should check this before sending these codes to a terminal (and NEVER to a batch job). This information can be found via:

   $    if(F$GETDVI("TERM","TT_DECCRT"))then some action

[up]

11. How do I do decimal math?

With "vanilla" DCL you cannot - it only supports integer math. However, in some cases you can fake it, for instance, if you need to multiply 1.2 * 1.3, you might instead multiply 12 * 13 and then use other DCL features to shift the decimal point back where you want it.

Sometimes a better option is to use ICALCV. (ICALCV is available via anonymous FTP as [.software]ICALCV.ZIP from seqaxp.bio.caltech.edu, UNZIP is available from ftp.wku.edu) ICALC is a small program that implements a command line calculator, ICALCV is a slightly modified version that places the last 10 results into a comma delimited list and assigns that string to the DCL symbol ICALC_OUT. So, for instance:

   $  show symbol icalc    ICALC must be defined
    ICALC == "$ICALC:ICALCV"
   $  define/user sys$output nla0:  suppress terminal output
   $  icalc 1.2*1.3
   $  write sys$Output icalc_out Show the result
        1.56

Or, to do a bunch of things at once, for instance, as part of a DCL procedure:

   $  string := 1.2*1.3; 1.3*1.5; 1.5*1.9; 1.2*sqrt(10)
   $  define/user sys$output nla0:  suppress terminal output
   $  icalc 'string'
   $  write sys$Output icalc_out Show the result
        1.56,        1.95,        2.85,        3.794733192

Then use F$ELEMENT to retrieve each desired result, for instance:

   $  write sys$output f$element(0,",",icalc_out)
        1.56
   $  write sys$output f$element(1,",",icalc_out)
        1.95

etc.

[up]

[top] [previous] [next]


  [Back to Helpline Home Page]


Author: David Mathog
Credits: Rich Lafferty
Maintained by: helpline@alcor.concordia.ca
Last update: $Date: 1999/05/18 16:16:23 $ -- Rich Lafferty