Copyright 1988-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 February, 1988 Cannibalism for Fun and Profit By Kevin G. Barkes Persons wishing to become thoroughly versed in DCL make it a point to look at all the command procedures they possibly can, even those which might seem to be totally unrelated to their primary areas of interest. The reason's simple; most good DCL command files contain chunks of code which can be "cannibalized", lifted from the original procedure and modified for some other purpose. So this month's reader-supplied command file serves two purposes: it's intended function, recording time spent editing files; and as a mini-library of DCL routines. Marc McCune of RR Donnelley Financial, Pittsburgh, PA, wrote EDIT_AGAIN.COM to help him keep track of time expended editing typesetting files and to provide a simple method of repeatedly editing the same file. Following each editing session, the procedure writes out a .TR (time record) file showing the name of the file edited, the start time, finish time, and elapsed time. This in itself makes EDIT_AGAIN of great value to persons desiring a painless way to log their efforts. More importantly, the procedure is loaded with lots of DCL tricks. We've covered many of them in previous columns, but Marc's thrown in a few newer concepts which bear examination. Let's quickly run through the procedure. To use the procedure, define a symbol in your login command file. Marc uses the EVE interface, so his definition is $ EVE :== @EDIT_AGAIN.COM The initial code turns off verification and error messages, but permits tracing by defining the logical name edit_trace to any non-null string. The logical name m_scr can be redefined to any convenient directory; this is where the procedure will store its time record (.TR) files. (Astute readers will note we're heeding DEC's admonition not to use the reserved "$" character in logical names.) The command line "parser" looks at the P1 parameter passed to the procedure to determine what actions should be taken, then checks to make certain the specified file name is legal. An EDIT command with no parameters causes the editor to call up the last file accessed. If everything checks out, the "time card" is punched; a .TR file is created in the m_scr directory with the same name as the file being edited. Should an error occur, the appropriate action is taken. If you prefer an editor other than EVE, make the appropriate changes in the lines which invoke it. Of special interest are the subroutines which obtain and calculate the time values. These would be useful in a large number of applications; I'd recommend examining them in detail and extracting them for use in other procedures. For example, they would be quite helpful in benchmarking the performance of discrete sections of a command file. Modifying them for such purposes would be an almost trivial matter. By altering the way in which the .TR files are written and maintained, it would be rather easy to write all the entries to a single file which would then be processed by another procedure in order to generate cumulative elapsed times for all files edited by a user or group of users. A quick SORT and judicious use of a few lexicals will make the task easy. ------- Jonathan W. Eveland of the Milwaukee Metropolitan Sewerage District submitted a nifty little procedure which "toggles" the terminal screen width. I condensed it a bit, leaving only nine lines of code (eight, if you don't count the continuation of the PTERM symbol assignment. Counting EXIT isn't fair). "Instead of using two (or more) symbols to manage terminal width," Jonathan explains, "the user needs only one symbol. When invoked, VT changes the screen width from 80 columns to 132 columns, or from any column width to 80 columns. Additionally, if the user specifies the width as a parameter, VT will set the screen to that width." Jonathan discovered that the screen width is the terminal's default buffer size, a value which can be returned by the F$GETDVI lexical function. The PTERM symbol assignment returns the physical device name of the terminal. If we break the line down into separate lexicals, we see: F$GETJPI("","MASTER_PID"), which makes certain the process identification number returned is that of the parent process, and not a subprocess without a terminal association; F$GETJPI(master pid,"TERMINAL"), which returns the name of the user terminal; and F$GETDVI(terminal,"TT_PHYDEVNAM), which returns the actual physical terminal name, necessary in case the user is logged in at a virtual terminal. We stuff the current terminal width ("DEFBUFSIZ") in the symbol OLD. If the current screen width is not 80, then the terminal width is changed to 132; if it isn't 80, it's set back to 80; and if the user supplied a parameter, its value is used instead. +++++++++++++++ PROGRAM 1 $! EDIT_AGAIN.COM --- Comments at end of file $ save_verify = 'f$verify(0)' $ org_mes = f$environment("message") $ set message/nof/noi/nos/not $ edit = "" $! "switch" to turn on procedure verification: $ if f$trnlnm("edit_trace") .nes. "" then $set verify $ on control_y then goto ABORT $ on error then goto EXIT $ bell[0,8] = 7 $ wso := write sys$output $ set terminal/noline ! disable CTRL/C definition on VT220 F6 key $ assign sys$login m_scr ! logical for record directory $! parse command line: $ if p1 .eqs. "" .or. - ! re-edit or... p1 .eqs. "," then goto TEST_NAME ! re-edit with new qualifiers $ if $extract(0,3,p1) .eqs. "REC" then goto RESTORE_FILE $! $ TEST_NAME: $ if p1 .eqs. "" .or. p1 .eqs. "," then p1 = REDIT $ if f$parse(p1) .nes. "" then goto GET_SPEC $ BAD_NAME: $ wso bell,bell,p1," is an invalid file specification. Please try again." $ wso "" $ goto NORMAL_END $! $ GET_SPEC: $ file_spec = f$parse(p1,,,"name") $ file_ext = f$parse(p1,,,"type") $ extension = f$extract(1,3,file_ext) $ file_name = file_spec+"_"+extension $! $! ----------| PUNCH THE TIME CLOCK |---------- $! /error is used to catch anything f$parse misses (like "*") $ open/write/error=bad_name outfile m_scr:'file_name'.tr $ mode := begin $ gosub get_time $ redit == p1 $! $!-------| START OF SESSION TIME-STAMP |------- $ write outfile "" $ write outfile "File edited: ",F$PARSE(P1)-";" $ write outfile "Edit session started ",BEGIN_TIME $ close outfile $! $ EDIT_FILE: $ define/user_mode sys$input sys$command $ edit/tpu/sec=evesecini 'redit' 'p2' 'p3' 'p4' 'p5' 'p6' 'p7' 'p8' $ goto EXIT $! $ RESTORE_FILE: $ define/user_mode sys$input sys$command $ edit/tpu/recover/section=evesecini 'redit' $ goto EXIT $! $! --------| CONTROL_Y TRAP |------- $ ABORT: $ wso bell $! ---- if there is a NEW file designation, then redefine the redit symbol $ if p1 .nes. "" then redit == p1 $ wso redit," Aborted by user." $ goto normal_end $! $ EXIT: $! ----------| PUNCH THE TIME CLOCK |---------- $ open/append outfile m_scr:'file_name'.tr $ mode := end $ gosub get_time $! $ gosub seconds $ gosub minutes $ gosub hours $ total_seconds = f$string(end_seconds - begin_seconds) $ if f$length(total_seconds) .eq. 1 then total_seconds = "0"+total_seconds $ total_minutes = f$string(end_minutes - begin_minutes) $ if f$length(total_minutes) .eq. 1 then total_minutes = "0"+total_minutes $ total_hours = f$string(end_hours - begin_hours) $ if f$length(total_hours) .eq. 1 then total_hours = "0"+total_hours $ total_time = total_hours+":"+total_minutes+":"+total_seconds $! $!-------| END OF SESSION TIME-STAMP |------- $ write outfile "Edit session ended ",END_TIME $ write outfile " ________" $ write outfile " TOTAL EDITING TIME: ",TOTAL_TIME $ close outfile $! $ NORMAL_END: $ set terminal/line/insert $ close outfile $ set message 'org_mes' $ exit_verify = f$verify(save_verify) $ exit $! $!---------------------- $ WARNING: $ wso bell,bell,p1," is an invalid file specification. Please try again." $ exit_verify = f$verify(save_verify) $ goto normal_end $! $!-------------------| SUBROUTINES |------------------- $ GET_TIME: $ time = f$cvtime(,,"time") $ 'mode'_time = f$extract(0,8,time) $ 'mode'_hours = f$integer(f$cvtime(TIME,,"hour")) $ 'mode'_minutes = f$integer(f$cvtime(TIME,,"minute")) $ 'mode'_seconds = f$integer(f$cvtime(TIME,,"second")) $ return $!----------------------------------------------------- $ SECONDS: $ if end_seconds .lt. begin_seconds then - end_minutes = end_minutes - 01 $ if end_seconds .lt. begin_seconds then - end_seconds = end_seconds + 60 $ return $!----------------------------------------------------- $ MINUTES: $ if end_minutes .lt. begin_minutes then - end_hours = end_hours - 1 $ if end_minutes .lt. begin_minutes then - end_minutes = end_minutes + 60 $ return $!----------------------------------------------------- $ HOURS: $ if end_hours .lt. begin_hours then - end_hours = end_hours + 12 $ return $! $!----| EDIT_AGAIN.COM by M. McCune |------------- $! $! This is a command procedure to simplify repeated editing of the $! same file using the vaxtpu EVE text editing interface and to $! record time spent in each editing session. $! $! Install symbol in login.com ----- EVE :== @EDIT_AGAIN.COM $! from vms $ prompt, the syntax is: $! EVE mydir:foo.bar $! to easily call up the same file for a re-edit, just type: $! EVE $! To change the default 'edit' file, use step 1 with a new filename $!---------------------------------------------------------------------------- $! -- VARIABLE DIRECTORY -- $! redit = file to be re-edited $! begin_time = start time of editing session $! end_time = ending time of editing session $! mode = either 'BEGIN' or 'END' $! 'mode'_hours } $! 'mode'_minutes } -- 'BEGIN' or 'END' time broken down $! 'mode'_seconds } $! total_time = total elapsed time of editing session $!---------------------------------------------------------------------------- ++++++++++++ PROGRAM 2 $! VT.COM $ V = 'F$VERIFY(0)' $ PTERM = F$GETDVI(F$GETJPI(F$GETJPI("","MASTER_PID"),- "TERMINAL"),"TT_PHYDEVNAM") $ OLD = F$GETDVI(PTERM,"DEVBUFSIZ") $ NEW = 80 $ IF OLD .EQ. 80 THEN NEW = 132 $ IF P1 .NE. 0 THEN NEW = P1 $ SET TERM/WIDTH='NEW' 'PTERM' $ V = F$VERIFY(V) $ EXIT $! Jonathan W. Eveland ---------- 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.