Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!water!watnot!watmath!clyde!cbatt!ucbvax!u3369429@seismo.CSS.GOV@murdu.OZ.AU From: u3369429@seismo.CSS.GOV@murdu.OZ.AU Newsgroups: mod.computers.vax Subject: SWING (modified) part 1 of 6 Message-ID: <8703030249.10135@murdu.OZ> Date: Tue, 3-Mar-87 13:49:22 EST Article-I.D.: murdu.8703030249.10135 Posted: Tue Mar 3 13:49:22 1987 Date-Received: Thu, 5-Mar-87 18:43:58 EST Sender: daemon@ucbvax.BERKELEY.EDU Reply-To: munnari!u3369429@seismo.CSS.GOV (Michael Bednarek) Distribution: world Organization: I.A.E.S.R., Melbourne University Lines: 725 Approved: info-vax@sri-kl.arpa $write sys$error "extract AAAREADME.GRC" $copy sys$input AAAREADME.GRC $deck/dollars="870303:12:53:38" SWING displays the current directory tree on a CRT screen for interactive tree manipulation. It is able to do the following: o SET DEFAULT by moving from node to node with the arrow keys and exiting SWING when the current node is the directory desired. o Rename a subdirectory. o Interactively create a new subdirectory. o Interactively move a subdirectory structure to a new position, with all of its children. o Interactively delete a tree structure - each node blinks and then disappears as it is deleted. This graphically does what the DELTREE type command procedures do. o Create hardcopy of the current directory structure. o Create a "binary save file" so the whole directory doesn't have to be searched each time SWING is used. The SWING program is written entirely in FORTRAN and replaces a lot of worn out command procedures that have been written over the years. It allows the user to quickly examine and manipulate a directory structure, saving time for the real work at hand. The screen manipulation is handled by the SMG routines and all eight directory levels are supported. The screen is switched between 80 and 132 columns as the directory tree changes size. The display scrolls up and down for long directory trees and commands are either entered by hitting keys or by a pulldown menu at the top of the screen. There is help while in SWING and a help file is furnished for the VMS HELP library as well. You have to try SWING to believe it. It is proof that computers can be easy to use! ------------------------------------------------------------------------ COMPLEMENTS, SUGGESTIONS AND COMPLAINTS TO THE FOLLOWING: Eric Andresen General Research Corporation 5383 Hollister Avenue Santa Barbara, CA 93111 (805)964-7724 Ext. 332 ------------------------------------------------------------------------ 870303:12:53:38 $write sys$error "extract AAA_ADD_SWING.MB" $copy sys$input AAA_ADD_SWING.MB $deck/dollars="870303:12:53:38" Features modified/added to SWING: o A few arrays needed to be dimensioned Dimension blabla(0:SOME_PARAMETER) ^^ o A few IF-statements needed to be turned around. E.g.: If (array(i).eq.0 .and. i.lt.Bound_of_i) must be written as If (i.lt.Bound_of_i .and. array(i).eq.0 ) o Added {Q,q,F10} as commands to quit (identical to {E,e,X,x,^Z} o Changed a flag in the HELP routine to look for HLP$LIBRARYx in the process table (no need to put SWING.HLP in the system help file). o Added support for directories a la TOPS-10/20, e.g.: o Rather than keeping the save-file in the top-level current tree, SWING now checks for a logical name SWING_SAVE and writes/reads save files there, the name being toplevel_SWING.SAV, e.g.: when SWING_SAVE = "D_3:[U3369429.SWING_SAVE]" and I swing through U3364711 and save, the file will be D_3:[U3369429.SWING_SAVE]U3364711_SWING.SAV May I suggest some guidelines for Fortran developers? Use "IMPLICIT NONE"! Someone observed that his FORSYSDEF.TLB didn't contain the proper $SMGDEF. That's due to a mockup on DEC's part. It happened at our site, too. I figured out the missing structure, and it compiled. BUT, no keystroke was recognised because they were all interrogated by their symbolic names, set up as PARAMETERs in $SMGDEF (the proper one), which were missing in my version. Compile using "/CHECK"! SWING bombed a number of times due to susbscript out of bounds. I as an author would find this rather embarrassing. This is not meant to put Eric Andresen down. In fact, I believe SWING is a very commendable effort and I use it a lot. 870303:12:53:38 $write sys$error "extract SWING.HLP" $copy sys$input SWING.HLP $deck/dollars="870303:12:53:38" !======================================================================= ! THIS IS THE HELP LIBRARY FOR SWING !======================================================================= ! ! This is the help file for the program SWING ! To add this to the standard help library on the VAX type: ! $ LIBRARY/HELP SYS$HELP:HELPLIB SWING.HLP ! ! Note that the processed version of this file (.HLB) ! is used by the SWING executable and must be located in SYS$HELP ! 1 SWING SWING is a VAX/VMS utility for displaying the graphical representation of directory trees on a VT100 or VT200 type terminal. It can be used to move to a directory or subdirectory, as is done with the SET DEFAULT command, and it can rename, move and delete subdirectories. SWING can also create hardcopy listings of a directory structure. Simply type SWING at the VMS prompt. 2 Moving_around Once SWING has drawn a picture of the default directory structure the cursor will be positioned at the current directory and it will be highlighted. The arrow keys can be used to move from one subdirectory to another. As you travel around you are "setting default" to that directory. To exit simply type X, E, Q, RETURN, CONTROL-Z, F10 or ENTER and you will return to VMS in the new directory location. As you move around with the arrow keys notice that the RIGHT, UP and DOWN arrows take you to the first directory available in that direction and that the LEFT arrow takes you to the parent of the current directory. Other commands can be entered to create, rename and move subdirectories, as well as delete entire directory trees and get a hardcopy listing of the current directory structure. To get help on these various commands enter the section of help called COMMANDS. 2 Save_file Every time SWING displays a directory tree it gets its information from either searching the disk or from a save file. If the logical name SWING_SAVE is defined as a directory, this file will be called SWING_SAVE:(top_level)_SWING.SAV. If such logical name is not defined, the file name is [(top_level)]SWING_SAV If SWING is going to be used on a regular basis it is advisable that the structure be saved in such a file. The SAVE command will create a save file and from that point on SWING will attempt to keep that file up-to-date. Having the save file will speed up initialization so much that it might be tempting to use SWING for "setting default" all of the time. If the directory structure is changed in any way by SWING the save file will be updated automatically, but if a change has occured without the use of SWING it will be necessary to do a manual SAVE on the new directory tree. NOTE: SWING does purge the save files provided the current process has enough privilege. 2 Commands Commands can be entered by either hitting the first letter of the commands located on the menu at the top of the screen or by hitting the CONTROL-P or DO keys and using the menu bar like a pulldown menu. The pulldown menu is operated by using the arrow keys to go to a selection and then hitting the ENTER key to choose that item. CONTROL-Z will exit the pulldown menu without making a choice. Although the pulldown menu is cute, hitting the first letter of the commands is by far a faster method. 3 Create CREATE prompts the user for the name of a new subdirectory to be created. The display will be updated and an actual directory is created. 3 Rename RENAME prompts for a new name to be given to the current directory. The display may change since the directories are in alphabetical order. 3 Move MOVE initiates the move operation by blinking the current subdirectory and then the user is asked to move to the a new parent directory. When either RETURN or ENTER is hit the move takes place. Both the new parent and the directory being moved can have other subdirectories attached to them as well. While moving to the new parent directory the operation can be canceled by hitting any key besides the arrow keys, ENTER and RETURN. 3 Delete DELETE causes the current directory and all subdirectories below it to be deleted automatically. The user is asked to enter YES before any delete operation takes place and the word YES must be spelled out completely. The deletion starts at the lowest subdirectory in the tree and works its way back to the current directory. As files are being deleted from a subdirectory that node will blink on the screen. If the subdirectory is successfully deleted the node name will blank out, so you can watch the directory tree being deleted graphically. IMPORTANT: IF A FILE DOES NOT HAVE DELETE ACCESS FOR THE USER, SWING WILL ATTEMPT TO CHANGE THE PROTECTION ON IT SO THAT IT CAN DELETE THE FILE (GIVEN THE PRIVILEGE OF THE USER ONLY) If a particular subdirectory or file still can't be deleted then the deletion process will continue anyway, leaving the protected files. A message will be given stating the problem. 3 Print PRINT creates a file for printing that contains a hardcopy version of the directory structure. One of two file types can be created. The normal output is for any printer and the LQP input file is for running through the LQP utility on a laser printer for a clean line drawn representation of the directory tree. The file is called SWING.LIS and it will be placed in the current directory. 3 Save SAVE causes a new save file to be created in the main directory. The save file is for speeding up the initialization of SWING. See the section called SAVE_FILE on the level of help above this level. 3 Option OPTION causes an optional full directory specification to be displayed at the top of the screen. The directory name will be modified each time the user moves to a new directory location. 3 Exit EXIT causes the SWING to exit to the currently selected subdirectory or directory. The keys E, X, Q, F10, CONTROL-Z, ENTER and RETURN exit SWING. 870303:12:53:38 $write sys$error "extract COMPILE.COM" $copy sys$input COMPILE.COM $deck/dollars="870303:12:53:38" $ ! COMMAND PROCEDURE TO COMPILE SWING $ ! It takes a VAX 8650 about 50 CPU seconds to do this. $ Set Default [.SWING.EXPORT] !*** LOCAL $! $ If F$Search("SWING.OLB").eqs."" then goto Create_OLB $ Write SYS$Output "Using library SWING.OLB" $ Goto C1 $! $Create_OLB: $ Write SYS$Output "Creating library SWING.OLB" $ Library/Create/Object SWING.OLB $! $C1: $ Fortran="Fortran/Check/NoList/Extend_Source" $! $ Fortran SWING $ Purge SWING.OBJ $! $ Fortran ADD_NODE $ Library SWING ADD_NODE $ Delete ADD_NODE.OBJ;* $! $ Fortran ADD_NODE_TO_DISPLAY $ Library SWING ADD_NODE_TO_DISPLAY $ Delete ADD_NODE_TO_DISPLAY.OBJ;* $! $ Fortran ADJUST_NODE_POINTERS $ Library SWING ADJUST_NODE_POINTERS $ Delete ADJUST_NODE_POINTERS.OBJ;* $! $ Fortran APPEND_NODE $ Library SWING APPEND_NODE $ Delete APPEND_NODE.OBJ;* $! $ Fortran CHANGE_OPTIONS $ Library SWING CHANGE_OPTIONS $ Delete CHANGE_OPTIONS.OBJ;* $! $ Fortran CHANGE_SPEC $ Library SWING CHANGE_SPEC $ Delete CHANGE_SPEC.OBJ;* $! $ Fortran CHECK_DIRECTORY_MOVE $ Library SWING CHECK_DIRECTORY_MOVE $ Delete CHECK_DIRECTORY_MOVE.OBJ;* $! $ Fortran CREATE_DIRECTORY $ Library SWING CREATE_DIRECTORY $ Delete CREATE_DIRECTORY.OBJ;* $! $ Fortran CRT $ Library SWING CRT $ Delete CRT.OBJ;* $! $ Fortran DEFINE_PASTE_BOARD $ Library SWING DEFINE_PASTE_BOARD $ Delete DEFINE_PASTE_BOARD.OBJ;* $! $ Fortran DEFINE_SMG_LAYOUT $ Library SWING DEFINE_SMG_LAYOUT $ Delete DEFINE_SMG_LAYOUT.OBJ;* $! $ Fortran DELETE_DIRECTORY $ Library SWING DELETE_DIRECTORY $ Delete DELETE_DIRECTORY.OBJ;* $! $ Fortran DELETE_FILES $ Library SWING DELETE_FILES $ Delete DELETE_FILES.OBJ;* $! $ Fortran DELETE_NODE $ Library SWING DELETE_NODE $ Delete DELETE_NODE.OBJ;* $! $ Fortran DIR_TO_FILE $ Library SWING DIR_TO_FILE $ Delete DIR_TO_FILE.OBJ;* $! $ Fortran DRAW_SCREEN $ Library SWING DRAW_SCREEN $ Delete DRAW_SCREEN.OBJ;* $! $ Fortran EXIT_SWING $ Library SWING EXIT_SWING $ Delete EXIT_SWING.OBJ;* $! $ Fortran FILE_TO_DIR $ Library SWING FILE_TO_DIR $ Delete FILE_TO_DIR.OBJ;* $! $ Fortran FIND_NODE $ Library SWING FIND_NODE $ Delete FIND_NODE.OBJ;* $! $ Fortran FREE_NODE $ Library SWING FREE_NODE $ Delete FREE_NODE.OBJ;* $! $ Fortran GET_LOCATION $ Library SWING GET_LOCATION $ Delete GET_LOCATION.OBJ;* $! $ Fortran HARDCOPY $ Library SWING HARDCOPY $ Delete HARDCOPY.OBJ;* $! $ Fortran HELP $ Library SWING HELP $ Delete HELP.OBJ;* $! $ Fortran LOAD_DISPLAY $ Library SWING LOAD_DISPLAY $ Delete LOAD_DISPLAY.OBJ;* $! $ Fortran LOAD_NODES $ Library SWING LOAD_NODES $ Delete LOAD_NODES.OBJ;* $! $ Fortran MODIFY_FILE_PROT $ Library SWING MODIFY_FILE_PROT $ Delete MODIFY_FILE_PROT.OBJ;* $! $ Fortran MOVE_NODE $ Library SWING MOVE_NODE $ Delete MOVE_NODE.OBJ;* $! $ Fortran PD_BAR_CHOICE $ Library SWING PD_BAR_CHOICE $ Delete PD_BAR_CHOICE.OBJ;* $! $ Fortran PD_DRAW_BAR $ Library SWING PD_DRAW_BAR $ Delete PD_DRAW_BAR.OBJ;* $! $ Fortran PD_GET_CHOICE $ Library SWING PD_GET_CHOICE $ Delete PD_GET_CHOICE.OBJ;* $! $ Fortran PD_LIST_CHOICE $ Library SWING PD_LIST_CHOICE $ Delete PD_LIST_CHOICE.OBJ;* $! $ Fortran PD_LOAD_BAR $ Library SWING PD_LOAD_BAR $ Delete PD_LOAD_BAR.OBJ;* $! $ Fortran PD_UNDRAW_BAR $ Library SWING PD_UNDRAW_BAR $ Delete PD_UNDRAW_BAR.OBJ;* $! $ Fortran PRINT_MESSAGE $ Library SWING PRINT_MESSAGE $ Delete PRINT_MESSAGE.OBJ;* $! $ Fortran RECORD_STRUCTURE $ Library SWING RECORD_STRUCTURE $ Delete RECORD_STRUCTURE.OBJ;* $! $ Fortran RENAME_DIRECTORY $ Library SWING RENAME_DIRECTORY $ Delete RENAME_DIRECTORY.OBJ;* $! $ Fortran RESET_TERMINAL $ Library SWING RESET_TERMINAL $ Delete RESET_TERMINAL.OBJ;* $! $ Fortran SET_NOTAB $ Library SWING SET_NOTAB $ Delete SET_NOTAB.OBJ;* $! $ Fortran SM_ALLOW_REPAINT $ Library SWING SM_ALLOW_REPAINT $ Delete SM_ALLOW_REPAINT.OBJ;* $! $ Fortran SM_REPAINT_SCREEN $ Library SWING SM_REPAINT_SCREEN $ Delete SM_REPAINT_SCREEN.OBJ;* $! $ Fortran UPDATE_SCREEN $ Library SWING UPDATE_SCREEN $ Delete UPDATE_SCREEN.OBJ;* $! $ Fortran UPDATE_WINDOW1 $ Library SWING UPDATE_WINDOW1 $ Delete UPDATE_WINDOW1.OBJ;* $! $ Link/NoMap SWING,SWING/Library 870303:12:53:38 $write sys$error "extract SHAR.COM" $copy sys$input SHAR.COM $deck/dollars="870303:12:53:38" $ VMS_shar aaa*.*,*.hlp,*.com,*.for,*.cmn,*.txt swing.shar 870303:12:53:38 $write sys$error "extract SWING.COM" $copy sys$input SWING.COM $deck/dollars="870303:12:53:38" $! This is my procedure to run SWING, the line in my LOGIN.COM file reads: $! SWING:=="@COM_LIB:SWING" $! $ Define/User SYS$INPUT SYS$COMMAND $ Run COM_LIB:SWING $! $! My procedure SDS needs to be run to update its stack. $ If "''SD_SP'".eqs."" then goto 10 ! did we run SDS before? $ SDS $ Exit ! We exit here because SDS does a check for D_PCD itself. $! $! Check whether we want our PROMPT line set. $10: If "''DO_PCD'" then PCD 870303:12:53:38 $write sys$error "extract ADD_NODE.FOR" $copy sys$input ADD_NODE.FOR $deck/dollars="870303:12:53:38" subroutine add_node( new_dir, parent ) include 'swing.cmn/List' character new_dir*42, spec*255 integer parent, len, new_node, free_node, ii logical greater call str$trim( new_dir, new_dir, len ) spec = node(parent).spec(1:node(parent).length)// . new_dir(1:len)//'.DIR;1' new_node = free_node() call file_to_dir( spec, . node(new_node).spec, . node(new_node).length, . node(new_node).name ) if ( node(parent).child .eq. 0 ) then node(parent).child = new_node else ii = node(parent).child if ( node(new_node).name .lt. node(ii).name ) then node(new_node).sister = node(parent).child node(parent).child = new_node else greater = .true. do while ( greater ) if ( node(ii).sister .eq. 0 ) then node(ii).sister = new_node greater = .false. else jj = ii ii = node(ii).sister if ( node(new_node).name .lt. node(ii).name ) then node(jj).sister = new_node node(new_node).sister = ii greater = .false. end if end if end do end if end if return end 870303:12:53:38 $write sys$error "extract ADD_NODE_TO_DISPLAY.FOR" $copy sys$input ADD_NODE_TO_DISPLAY.FOR $deck/dollars="870303:12:53:38" subroutine add_node_to_display( num ) include '($smgdef)/List' include 'swing.cmn/List' integer column, num node(num).rend = smg$m_reverse level = node(num).level column = level * 17 + 1 line = node(num).line call smg$put_chars( window2, node(num).name, line, column,, . node(num).rend ) call smg$draw_line( window2, line, column-3, line, column-1 ) if ( level .eq. last_level ) then call smg$draw_line( window2, line-1, column-3, line, column-3 ) else if ( level .eq. last_level + 1 ) then call smg$draw_line( window2, line, column-5, line, column-2 ) else if ( level .lt. last_level ) then call smg$draw_line( window2, last_line(level), column-3, . line, column-3 ) end if if ( .not. found .and. root .eq. node(num).spec ) then found = .true. cur_line = line cur_level = level end if last_level = level last_line(level) = line return end 870303:12:53:38 $write sys$error "extract ADJUST_NODE_POINTERS.FOR" $copy sys$input ADJUST_NODE_POINTERS.FOR $deck/dollars="870303:12:53:38" subroutine adjust_node_pointers include '($smgdef)/List' include 'swing.cmn/List' integer ll, jj, ptr(0:7) do ll = 1, MAX_LINES do jj = 0, MAX_LEVELS node_pointer(jj,ll) = 0 end do end do do jj = 0, MAX_LEVELS ptr(jj) = 0 end do ll = 1 !LINE ptr(0) = 1 node_pointer(0,ll) = 1 ptr(1) = node(ptr(0)).child do while( ptr(1) .ne. 0 ) node_pointer(1,ll) = ptr(1) node(ptr(1)).line = ll node(ptr(1)).level = 1 ptr(2) = node(ptr(1)).child do while( ptr(2) .ne. 0 ) node_pointer(2,ll) = ptr(2) node(ptr(2)).line = ll node(ptr(2)).level = 2 ptr(3) = node(ptr(2)).child do while( ptr(3) .ne. 0 ) node_pointer(3,ll) = ptr(3) node(ptr(3)).line = ll node(ptr(3)).level = 3 ptr(4) = node(ptr(3)).child do while( ptr(4) .ne. 0 ) node_pointer(4,ll) = ptr(4) node(ptr(4)).line = ll node(ptr(4)).level = 4 ptr(5) = node(ptr(4)).child do while( ptr(5) .ne. 0 ) node_pointer(5,ll) = ptr(5) node(ptr(5)).line = ll node(ptr(5)).level = 5 ptr(6) = node(ptr(5)).child do while( ptr(6) .ne. 0 ) node_pointer(6,ll) = ptr(6) node(ptr(6)).line = ll node(ptr(6)).level = 6 ptr(7) = node(ptr(6)).child do while( ptr(7) .ne. 0 ) node_pointer(7,ll) = ptr(7) node(ptr(7)).line = ll node(ptr(7)).level = 7 ptr(7) = node(ptr(7)).sister if ( ptr(7) .ne. 0 ) ll = ll + 1 end do ptr(6) = node(ptr(6)).sister if ( ptr(6) .ne. 0 ) ll = ll + 1 end do ptr(5) = node(ptr(5)).sister if ( ptr(5) .ne. 0 ) ll = ll + 1 end do ptr(4) = node(ptr(4)).sister if ( ptr(4) .ne. 0 ) ll = ll + 1 end do ptr(3) = node(ptr(3)).sister if ( ptr(3) .ne. 0 ) ll = ll + 1 end do ptr(2) = node(ptr(2)).sister if ( ptr(2) .ne. 0 ) ll = ll + 1 end do ptr(1) = node(ptr(1)).sister if ( ptr(1) .ne. 0 ) ll = ll + 1 end do lowest_level = 0 do ii = 1, num_nodes if ( node(ii).level .gt. lowest_level ) . lowest_level = node(ii).level end do if ( lowest_level .gt. 7 ) then call print_message( 'Directory nesting is to deep', 1 ) end if num_lines = ll return end 870303:12:53:38 $write sys$error "extract APPEND_NODE.FOR" $copy sys$input APPEND_NODE.FOR $deck/dollars="870303:12:53:38" subroutine append_node( level, spec, search ) include 'swing.cmn/List' integer level, len_node, free_node character spec*255, search*255 node_num = free_node() if ( level .gt. lowest_level ) lowest_level = level if ( level .le. last_level ) then line = line + 1 num_lines = line node(last_node(level)).sister = node_num else node(node_num-1).child = node_num end if if ( level .ne. 0 ) then call file_to_dir( spec, . node(node_num).spec, . node(node_num).length, . node(node_num).name ) else call str$trim( spec, spec, len_node ) node(node_num).spec = spec node(node_num).length = len_node if ( len_node .le. 10 ) then node(node_num).name = spec else node(node_num).name = spec(:11)//'*' end if end if node(node_num).line = line node(node_num).level = level node(node_num).rend = smg$m_reverse node_pointer(level,line) = node_num search = node(node_num).spec(1:node(node_num).length)//'*.dir;1' last_level = level last_node(level) = node_num return end 870303:12:53:38 $write sys$error "extract CHANGE_OPTIONS.FOR" $copy sys$input CHANGE_OPTIONS.FOR $deck/dollars="870303:12:53:38" subroutine change_options( code ) include 'swing.cmn/List' integer code if ( code .eq. 71 ) then use_window1 = .not. use_window1 end if if ( .not. use_window1 ) then call smg$erase_display( window1 ) else call update_window1 end if return end 870303:12:53:38 $write sys$error "extract CHANGE_SPEC.FOR" $copy sys$input CHANGE_SPEC.FOR $deck/dollars="870303:12:53:38" subroutine change_spec( parent, ptr ) include 'swing.cmn/List' character spec*255 integer len, parent, ptr, jj jj = node(ptr).length - 1 ii = jj do while ( ii .gt. 1 .and. . node(ptr).spec(ii:ii) .ne. '[' .and. . node(ptr).spec(ii:ii) .ne. '.' ) ii = ii - 1 end do ii = ii + 1 spec = node(parent).spec(1:node(parent).length)// . node(ptr).spec(ii:jj)//'.DIR;1' call file_to_dir( spec, . node(ptr).spec, . node(ptr).length, . node(ptr).name ) return end 870303:12:53:38