Copyright 1994-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, 1994 A Day In The Life By Kevin G. Barkes This has been one of those months when I've been so flooded with work and netmail that my repeated attempts to assemble a coherent, themed column have been about as successful as DEC's efforts to convince the computing community that OpenVMS is really Open. Panic sets in. Terrible things happen. I write 43-word first sentences in a desperate search for a suitable subject. Suddenly it came to me... why not talk about the DCL stuff I encounter during a regular work day? Surely somebody will pick up something from those things I encounter or receive from the readers. Even better, it gives me a theme... Batch Stuff: Since most of the database publishing processing I do is repetitive, I've broken it down into a number of DCL command procedures. There are five steps I use for the majority of my work, and I've named the command files: 010.com 020.com 030.com 040.com 050.com Now, on a "plain vanilla" job, all I do is issue the command: $ SUBMIT * This submits all five command procedures, in numerical order, to the SYS$BATCH queue where they are treated as a single job. Why are the procedures numbered 010, 020, 030, etc.? Simple: if a job requires an additional processing step or five, I can add the extra procedures within the numerical gaps: 005.com 010.com 015.com 020.com 025.com 026.com 030.com 040.com 050.com This allows me to insert and remove processing steps easily. It also keeps me from inadvertantly messing up a thoroughly-debugged .com file. It may seem primitive, but think of it as modular programming at a ridiculously high level of granularity. Yeah, it's inefficient as well... on my VAXstation 4000 model 60 I waste almost .2 seconds of cpu time with all the file openings and closings. But it saves me a lot of time, since one 15 line command file is a lot easier to maintain than a 200 line one. Another handy item: remember that OpenVMS sticks the number of the submitted job into the local symbol $ENTRY. With the job number, you can have other procedures monitor, track, or perform post-processing on the procedure you originally submitted. A simple example: $ @test $entry $! TEST.COM $ WRITE SYS$OUTPUT 'P1' Another useful SUBMIT command parameter is /DELETE, which causes OpenVMS to delete the files submitted to the queue after their execution. I have a number of procedures which, when executed, write temporary, "disposable" .com files and submit them for batch processing with the /DELETE qualifier. This helps keep the number of .com files at a tolerable level. ***** Foreign Command Shortcut: Frank Noell of Channel Islands Software, Inc. faxed me a reminder of a nifty little trick. Many programs are designed to be run as foreign commands, so that command parameters can be passed to the executing image. For example, if my program FOO.EXE needs to be defined as a foreign command, I would have to issue the following: $ FOO :== $ DISK:[DIRECTORY]FOO.EXE then enter the command $ FOO PARAMETER Alternatively, I can issue the command: $ MCR DISK:[DIRECTORY]FOO.EXE PARAMETER MCR is an acronym for Monitor Console Routine, which is the user command line interface under the RSX-11 operating system for PDP-11s. It was included in the RSX compatibility mode software originally built into VMS. Even though the RSX compatibility was eventually split out of VMS and into a separate layered product, DEC kept MCR in the DCL command tables since it is commonly used as a shortcut to typing $ RUN SYS$SYSTEM:WHATEVER. The big difference between RUN and MCR is that the latter activates the image as a foreign command. ***** Shamless Plug: Instead of hiring an expensive consultant (ahem), consider CBM's new book, "OpenVMS Performance Management, Second Edition: Tuning Techniques for OpenVMS VAX and OpenVMS AXP" by James W. Coburn. I did the tech review on the book, and it's a straightforward, easy to follow guide to tweaking your system. Apologies for the length of the title, but it was the only way to let potential readers know that both VAX and AXP systems are included. The original edition only dealt with VAX architecture machines. ***** Friendly Worm: Here's a worm that came over the Internet, but you don't have to be afraid of it. It's a useful command file that eats up all those excess cpu cycles. Thanks to Steve Harris of MadenTech for his submission and for noting a fix in February's MATCH.COM procedure: "I tried MATCH.COM as presented in your article and couldn't get it to work," Steve reported. " To remedy it, I inserted the following line after the label 'Pchr_done:' - $ Pc = Pc + 1 ********** Kevin G. Barkes is an independent consultant whose favorite Internet newsgroup is alt.swedish.chef.bork.bork.bork. Kevin lurks on comp.os.vms and can be reached at kgbarkes@gmail.com. *************** PROGRAM 1 $! WORM! $ ESC[0,8] = 27 ! DEFINE 'ESCAPE' $ GON = ESC + "(0" ! GRAPHICS ON $ GOFF = ESC + "(B" ! GRAPHICS OFF $ WIDTH = F$GETDVI ("TT:", "DEVBUFSIZ") $ HEIGHT = F$GETDVI ("TT:", "TT_PAGE") $ UPPERBOUND = 1 $ LOWERBOUND = HEIGHT - 1 $ LEFTBOUND = 1 $ RIGHTBOUND = WIDTH $ UP = 1 $ RIGHT = 2 $ DOWN = 3 $ LEFT = 4 $ ! TABLE OF PRINTABLE CHARACTERS, ... $ TABLE'UP''UP'[0,8] = 120 $ TABLE'UP''LEFT'[0,8] = 107 $ TABLE'UP''RIGHT'[0,8] = 108 $ TABLE'DOWN''DOWN'[0,8] = 120 $ TABLE'DOWN''LEFT'[0,8] = 106 $ TABLE'DOWN''RIGHT'[0,8] = 109 $ TABLE'LEFT''LEFT'[0,8] = 113 $ TABLE'LEFT''UP'[0,8] = 109 $ TABLE'LEFT''DOWN'[0,8] = 108 $ TABLE'RIGHT''RIGHT'[0,8] = 113 $ TABLE'RIGHT''UP'[0,8] = 106 $ TABLE'RIGHT''DOWN'[0,8] = 107 $ ! START AT THE CENTER OF THE SCREEN, ... $ X_COOR = WIDTH/2 $ Y_COOR = HEIGHT/2 $ PREV_DIRECTION = UP $10: DIRECTION = 0 $ GOSUB GET_DIRECTION $ ! ARE WE TRYING TO DOUBLE BACK ON OURSELVES? $ IF DIRECTION .EQ. UP .AND. PREV_DIRECTION .EQ. DOWN THEN GOTO 10 $ IF DIRECTION .EQ. DOWN .AND. PREV_DIRECTION .EQ. UP THEN GOTO 10 $ IF DIRECTION .EQ. LEFT .AND. PREV_DIRECTION .EQ. RIGHT THEN GOTO 10 $ IF DIRECTION .EQ. RIGHT .AND. PREV_DIRECTION .EQ. LEFT THEN GOTO 10 $ ! ARE WE TRYING TO MOVE OFF THE SCREEN? $ IF DIRECTION .EQ. UP .AND. Y_COOR .EQ. UPPERBOUND THEN GOTO 10 $ IF DIRECTION .EQ. DOWN .AND. Y_COOR .EQ. LOWERBOUND THEN GOTO 10 $ IF DIRECTION .EQ. LEFT .AND. X_COOR .EQ. LEFTBOUND THEN GOTO 10 $ IF DIRECTION .EQ. RIGHT .AND. X_COOR .EQ. RIGHTBOUND THEN GOTO 10 $ ! POST THE WORM TO THE SCREEN, ... $ WRITE SYS$OUTPUT ESC,"[''Y_COOR';''X_COOR'H", - GON,TABLE'PREV_DIRECTION''DIRECTION',GOFF $ PREV_DIRECTION = DIRECTION $ IF DIRECTION .EQ. UP THEN Y_COOR = Y_COOR - 1 $ IF DIRECTION .EQ. DOWN THEN Y_COOR = Y_COOR + 1 $ IF DIRECTION .EQ. LEFT THEN X_COOR = X_COOR - 1 $ IF DIRECTION .EQ. RIGHT THEN X_COOR = X_COOR + 1 $ GOTO 10 $ GET_DIRECTION: $ ! GENERATE A RANDOM NUMBER BETWEEN 1 AND 4, ... $ TIME = F$FAO("!%T",0) $ TENS = F$INTEGER(F$EXTRACT(9,1,TIME)) $ ONES = F$INTEGER(F$EXTRACT(10,1,TIME)) $ IF (TENS/2) * 2 .EQ. TENS $ THEN $ ! UP OR DOWN? $ IF (ONES/2) * 2 .EQ. ONES $ THEN $ DIRECTION = UP $ ELSE $ DIRECTION = DOWN $ ENDIF $ ELSE $ ! LEFT OR RIGHT? $ IF (ONES/2) * 2 .EQ. ONES $ THEN $ DIRECTION = LEFT $ ELSE $ DIRECTION = RIGHT $ ENDIF $ ENDIF $ RETURN