From:	CSBVAX::MRGATE!info-vax-RELAY@KL.SRI.COM@SMTP 10-FEB-1988 12:33
To:	ARISIA::EVERHART
Subj:	prompt representing default...


Received: from CUNYVM.CUNY.EDU by KL.SRI.COM with TCP; Wed 3 Feb 88 11:06:20-PST
Received: from uwocc1.uwo.CA by CUNYVM.CUNY.EDU ; Wed, 03 Feb 88 13:55:23 EST
Received: from uwovax.UWO.CDN by uwocc1.uwo.CA (Mailer X1.25) with BSMTP id
 4335; Wed, 03 Feb 88 13:52:26 EST
From: Brent Sterner <BRENT@uwovax.UWO.CDN>
To: info-vax@KL.SRI.COM
Date: Wed, 3 Feb 88 13:39:35 EST
Subject: prompt representing default...
Message-id: <0570893975@uwovax.UWO.CDN>
Cc: brent@uwovax.UWO.CDN

   Hmmm.  A lot of discussion lately about prompting to remind you where
you are.  I don't do that here, but I have implemented a "P" command to
do "relative pathing".  We had a program under TOPS-10 to do that, and this
mimics the behaviour reasonably well.  Based on some other people's ideas.
Credit is given where identities are known.
   Consider this to be public domain.  Patch and hack all you like.
Suggestions or improvements are welcome.  Reworking in a high level
language would also be welcome.  To use, define P = "@dev:[dir]P.COM.
   See the end of the command procedures for examples and help.  Invoked
after installation via P EXAMPLES <cr> or P HELP <cr>.  (It is amazing
how quickly you get used to typing P <cr> to see where you are.)   Brent.

=======================< cut >===========================
$ old_verify = f$verify(0)      ! Turn off verification
$       goto begin
$! P.COM is a VMS DCL implementation of the UWO TOPS-10 "P" "relative pathing"
$! command originally written by Peter Marshall at UWO.
$! The idea for the program originally came from Colin Knill,   1981-Sept v1.1
$! Some modifications were attempted by adm a little later.     1981-Oct v1.2 ?
$! This previous work is the basis for the following command procedure
$! written by                                   'beletz' 1981-Nov-25. v2.0
$! additions    - the # command                 'beletz' 1981-Dec-4.  v2.1
$!              - the ) and ( command           'beletz' 1982-Feb-27. v2.2
$!              - multi level pathing           'beletz' 1982-Nov-15. v3.0
$!              - eliminating spaces in command 'beletz' 1982-Nov-18. v3.1
$!              - eliminating predeffinition
$!                of symbol SAVE_UFD            'beletz' 1983-Nov-3.  v3.2
$!              - Mod to P+ function
$!                uses logical SYS$LOGIN as home McHardy 1986-May-2.  v4.0
$!              - Implement multiple commands per
$!                line and tidy up.              Brent Sterner  1987-March v5.0
$!
$ begin:
$ !     Stuff all the arguments into one long string with no white space.
$ xarg = ""
$ opr  = ""
$ arg  = ""
$ args = f$edit("''p1'''p2'''p3'''p4'''p5'''p6'''p7'''p8'","COLLAPSE,UPCASE")
$ alen = f$length(args)
$ !     Here to loop for each command in the string.
$ process_loop:
$ !     If no arguments, just display where we are.
$       if args .eqs. "" then  goto done                ! Nothing to check.
$ !     Extract the "operator" and branch appropriately.
$       opr = f$extract(0,1,args)
$       if opr .eqs. "."   then goto down
$       if opr .eqs. ">"   then goto down
$       if opr .eqs. "<"   then goto up
$       if opr .eqs. ")"   then goto down
$       if opr .eqs. "("   then goto delete
$       if opr .eqs. "*"   then goto home
$       if opr .eqs. "+"   then goto home
$       if opr .eqs. "#"   then goto logical
$       if opr .eqs. ";"   then goto replace_path
$       if opr .eqs. "?"   then goto save_path
$       if opr .eqs. "^"   then goto switch_path
$       if opr .eqs. "H"   then goto help               ! UPPER CASE !
$       if opr .eqs. "E"   then goto examples           ! UPPER CASE !
$                               goto boo_boo
$ !.............................................................................
$ up:                           ! Path "up" one level.
$       set default [-]
$ no_argument:                  ! Here if the "opr" expects no argument.
$       args = f$extract(1,alen,args)
$       alen = f$length(args)
$       goto process_loop
$ !.............................................................................
$ home:                         ! Path to the sys$login "home" directory.
$       set default sys$login
$       goto no_argument
$ !.............................................................................
$ down:                         ! Path down to the specified directory.
$       gosub get_dir           ! Extract the desired directory.
$       if arg .eqs. "" then goto no_directory
$       direc:='f$directory()'                  ! Current directory
$       len='f$length(direc)'-2
$       direc:='f$extract(1,len,direc)'
$       if f$search("''arg'.dir") .eqs. ""   then gosub create_dir
$       set default ['direc'.'arg']
$       goto process_loop
$ no_directory:                 ! message that no <dir> specified
$       write sys$output " No directory was specifed; ''opr' ignored."
$       goto process_loop
$ !.............................................................................
$ logical:                      ! Path to an explicit logical name.
$       gosub get_dir           ! Extract the logical name.
$       if arg .eqs. "" then goto no_directory
$       set default 'arg'       ! Set it
$       goto process_loop
$ !.............................................................................
$ delete:                       ! Delete a directory.  This may be in either
$                               ! of two forms: If a directory argument is
$                               ! specified, delete from this directory.
$                               ! If not, P < and delete where we came from.
$                               ! The latter is the inverse of ")".
$       gosub get_dir           ! Extract the desired directory.
$       xarg = arg              ! Remember the actual argument (null or not).
$       if arg .nes. "" then goto delete_this_directory
$ delete_where_we_are:          ! Pop a level and delete where we were.
$       temp1 = f$directory()-"["-"]"   ! Remember where we are.
$       set def [-]
$       temp2 = f$directory()-"["-"]"
$       loc = f$locate(temp2,temp1)     ! Find our bearings.
$       arg = f$extract(f$length(temp2),f$length(temp1),temp1) - "."
$ delete_this_directory:        ! Delete the specified directory.
$       set protection 'arg'.dir/prot=(o:rwed)
$       delete 'arg'.dir;*      ! DCL diagnostic if failure.
$       if $severity then write sys$output "''arg'.dir;* has been deleted"
$       arg = xarg              ! Remember the original argument.
$       goto process_loop
$ !.............................................................................
$ replace_path:                 ! Save the current path and switch to
$                               ! previously saved path.
$       if last_path .eqs. "" then goto no_path  ! Need a place to go.
$       new_path:='f$directory()'       ! Remember where we are.
$       set default 'last_path' ! You know where to go.
$       last_path:=='new_path'  ! Remember where we were for next time.
$       goto no_argument
$ !.............................................................................
$ save_path:                    ! Save the current path.
$       last_path:=='f$directory()'     ! Global symbol!
$       goto no_argument
$ !.............................................................................
$ switch_path:                  ! Set path to previously saved path.
$       if last_path .eqs. "" then goto no_path  ! Need a place to go.
$       set default 'last_path' ! You know where to go.
$       goto no_argument
$ no_path:      ! tell user there was no previously saved path
$       write sys$output " No previously saved path found ; ''opr' ignored."
$       goto no_argument
$ !.............................................................................
$ !.............................................................................
$ get_dir:                      ! Here if a directory specification is expected.
$       args = f$extract(1,alen,args)
$       alen = f$length(args)
$       delim = alen
$               temp = f$locate(".",args)
$                  if temp .lt. delim THEN delim = temp
$               temp = f$locate(">",args)
$                  if temp .lt. delim THEN delim = temp
$               temp = f$locate("<",args)
$                  if temp .lt. delim THEN delim = temp
$               temp = f$locate(")",args)
$                  if temp .lt. delim THEN delim = temp
$               temp = f$locate("(",args)
$                  if temp .lt. delim THEN delim = temp
$               temp = f$locate("*",args)
$                  if temp .lt. delim THEN delim = temp
$               temp = f$locate("+",args)
$                  if temp .lt. delim THEN delim = temp
$               temp = f$locate("#",args)
$                  if temp .lt. delim THEN delim = temp
$               temp = f$locate(";",args)
$                  if temp .lt. delim THEN delim = temp
$               temp = f$locate("?",args)
$                  if temp .lt. delim THEN delim = temp
$               temp = f$locate("^",args)
$                  if temp .lt. delim THEN delim = temp
$       arg  = f$extract(0,delim,args)          ! Get the directory name.
$       args = f$extract(delim,alen-delim,args) ! Anything else on the line.
$       alen = f$length(args)                   ! Length of anythin else.
$ return                                        ! End of get_dir.
$ create_dir:                   ! Here to decide whether or not to create
$                               ! a sub-directory which does not exist.
$       if opr .eqs. ")" then goto make_dir
$ create_dir_ask:               ! Here to ask if the directory doesn't exist.
$       inquire/nopun p1 "''arg'.dir does not exist. Create it (Y/N) ? "
$       res:='f$extract(0,1,p1)'
$       if res .eqs. "y" .or. res .eqs. "Y" then goto make_dir
$ create_dir_nope:              ! User error.  Give up, but report where we are.
$       goto done
$ make_dir:                     ! Create a new directory.
$       create/directory ['direc'.'arg']
$ return
$ !.............................................................................
$ !.............................................................................
$ !.............................................................................
$ done: ! process complete, show the processor and current default directory
$ write sys$output "  Processor node is ''f$getsyi("NODENAME")'"
$       sho default
$ dummy = f$verify(old_verify)
$       exit
$ !.............................................................................
$ help: ! here for some help in using the path program.
$       type sys$input

The P command invokes a command procedure to perform relative pathing.
P accepts arguments which consist of operators.  Some operators expect
an argument (normally a sub-directory).  Operators include the following:
("x" represends a sub-directory name)
        P>x     - x.dir exists in the current directory (else ask if
                  it should be created).  SET DEFAULT [.x].
        P.x     - identical to P>x.
        P)x     - create x.dir; then SET DEFAULT [.x].
        P(x     - x.dir exists in the current directory.  Delete
                  x.dir (will fail if the directory is not empty).
        P<      - SET DEFAULT [-]       (ie path "up" one level)
        P(      - SET DEFAULT [-]; then delete the directory you
                  just came from (fails if directory not empty).
        P+      - SET DEFAULT SYS$LOGIN
        P *     - SET DEFAULT SYS$LOGIN
                  (the space is required due to the way DCL is parsed)
        P#x     - x is a logical assignment.  SET DEFAULT x.
        P?      - Remember the current path.
        P^      - Set path to the previously saved path.
        P;      - Remember the current path;  set the new path
                  to the previously saved path.
        P help  - display this help text.
        P examp - display examples text.
$ dummy = f$verify(old_verify)
$       exit
$ !.............................................................................
$ examples: ! here for some working examples in using the path program.
$       type sys$input

 $ P *                                          ! Start at the login directory
 PUBLIC1:[71_105]
 $ p>newdir                                     ! Path to [.NEWDIR].
 NEWDIR.dir does not exist. Create it (Y/N) ? y ! Doesn't exist.  Create it!
  PUBLIC1:[71_105.NEWDIR]
 $ p)newer)1st                                  ! Path down 2 more levels and
  PUBLIC1:[71_105.NEWDIR.NEWER.1ST]             ! create without asking.
 $ p<)2nd<)3rd]                                 ! Path up, then down (creating)
  PUBLIC1:[71_105.NEWDIR.NEWER.3RD              ! [.2ND]. Ditto creating [.3RD].
 $ p<                                           ! Path up one level and
  PUBLIC1:[71_105.NEWDIR.NEWER]
 $ dir *.dir/date/size/prot                     ! show the 3 sub-directories.

 Directory PUBLIC1:[71_105.NEWDIR.NEWER]

 1ST.DIR;1                          1  25-MAR-1987 13:42  (RWE,RWE,RWE,E)
 2ND.DIR;1                          1  25-MAR-1987 13:43  (RWE,RWE,RWE,E)
 3RD.DIR;1                          1  25-MAR-1987 13:43  (RWE,RWE,RWE,E)

 Total of 3 files, 3 blocks.
 $ p(1st                                        ! Delete 1ST.DIR (empty).
 1ST.dir;* has been deleted
  PUBLIC1:[71_105.NEWDIR.NEWER]                 ! (P always displays path).
 $ p>2nd                                        ! Path down to 2ND.
  PUBLIC1:[71_105.NEWDIR.NEWER.2ND]
 $ p(>3rd                                       ! Delete current (2ND) empty
 2ND.dir;* has been deleted                     ! subdirectory; down to 3RD.
  PUBLIC1:[71_105.NEWDIR.NEWER.3RD]
 $ p(((                                         ! Up 3x deleting empty sub
 3RD.dir;* has been deleted                     ! directories as we go.
 NEWER.dir;* has been deleted
 NEWDIR.dir;* has been deleted
  PUBLIC1:[71_105]
 $ p)x                                          ! Down (create) into X.
  PUBLIC1:[71_105.X]
 $ p<)y                                         ! Up, down (create) into Y.
  PUBLIC1:[71_105.Y]
 $ p+>x                                         ! To top level, then to X.
  PUBLIC1:[71_105.X]
 $ p *>y                                        ! To top level, then to Y.
  PUBLIC1:[71_105.Y]                            ! (Note: space is necessary.)
 $ p#sys$login                                  ! To logical SYS$LOGIN.
  PUBLIC1:[71_105]
 $ p+                                           ! To top level.
  PUBLIC1:[71_105]
 $ p>z                                          ! Down to Z.DIR.
  PUBLIC1:[71_105.Z]
 $ p?                                           ! Remember this path.
  PUBLIC1:[71_105.Z]
 $ p;                                           ! Save this path and
  PUBLIC1:[71_105.Z]                            ! go to saved path (same).
 $ p<                                           ! Path up a level.
  PUBLIC1:[71_105]
 $ p;                                           ! Remember and switch.
  PUBLIC1:[71_105.Z]
 $ p;                                           ! Remember and switch.
  PUBLIC1:[71_105]
 $ p^                                           ! Go to the remembered path but
  PUBLIC1:[71_105.Z]                            ! retain the remembered path.
 $ p+>c                                         ! Move around a bit.
  PUBLIC1:[71_105.C]
 $ p+>folder                                    ! Move around some more.
  PUBLIC1:[71_105.FOLDER]
 $ p^                                           ! Go to the remembered path.
  PUBLIC1:[71_105.Z]
 $ bye                                          ! UWO logoff
 Pid: 2ba6      Uic: 71_105      User: BRENT
 Charge: $   3.41 (discount 0%)
 Logout for  RTA3 at 25-MAR-1987 13:46:43.72
 Run time 00:00:12.31   Connect time 00:12
 Disk I/O:         395
 Terminal I/O:     484
 Page Faults:     4411

$ dummy = f$verify(old_verify)
$       exit
$ !.............................................................................
$ boo_boo:
$       type sys$input
        The UWO "P" command is a DCL procedure to perform relative pathing.
        The general format of the command is "P [arg1[arg2[...]]]
        The space is only required to assist in DCL parsing of some
                argument operators (for example "P<" is valid).
        For help type   "P help"
$ dummy = f$verify(old_verify)
$       exit
$ !.............................................................................
$ !.............................................................................
$ !.............................................................................
--
Brent Sterner
Technical Support Manager, Academic Systems
Telephone   (519)661-2151 x6036
Network     <BRENT@uwovax.UWO.CDN>
    Long        Computing & Communications Services
     and        Natural Sciences Building
      Winding   The University of Western Ontario
       Road     London, Ontario, Canada  N6A 5B7

-------

