@q
@program lib-propdirs
1 9999 d
i
( lib-propdirs    v1.1    Jessy @ FurryMUCK    5/97, 8/01
  
  A library of property and directory handling routines.
  
  INSTALLATION:
  
  Set lib-propdirs L, and register as lib/propdir. In your MUCK window,
  type or paste the following def props:
  
@set lib-propdirs=_defs/copy_root:"$lib/propdirs" match "copy_root" call
@set lib-propdirs=_defs/move_root:"$lib/propdirs" match "move_root" call
@set lib-propdirs=_defs/copy_prop:"$lib/propdirs" match "copy_prop" call
@set lib-propdirs=_defs/move_prop:"$lib/propdirs" match "move_prop" call
@set lib-propdirs=_defs/remove_dir:"$lib/propdirs" match "remove_dir" call
@set lib-propdirs=_defs/copy_dir:"$lib/propdirs" match "copy_dir" call
@set lib-propdirs=_defs/move_dir:"$lib/propdirs" match "move_dir" call
@set lib-propdirs=_defs/remove_dir-r:"$lib/propdirs" match "remove_dir-r" call
@set lib-propdirs=_defs/copy_dir-r:"$lib/propdirs" match "copy_dir-r" call
@set lib-propdirs=_defs/move_dir-r:"$lib/propdirs" match "move_dir-r" call
  
  Then, set the _docs property for @view:
  
  @set lib-propdirs=_docs:@list $lib/propdirs=24-63
  
  USE:

  Note: Unless otherwise specified, 'propdir' should be read to mean 'any
	propdir other than / root'. Use copy_root and move_root for handling the
	/ root directory.
  
  Lib-propdirs includes the following routines:

	copy_root  [ d1 d2 --  ]
	  Copies all props and propdirs on d1 to d2.

	move_root  [ d1 d2 --  ]
	  Moves all props and propdirs on d1 to d2.
  
  copy_prop  [ d1 s1 d2 s2 --  ]
    Copies property s1 on object d1 to property s2 on object d2.
  
  move_prop  [ d1 s1 d2 s2 --  ]
    Moves property s1 on object d1 to property s2 on object d2.
    
  remove_dir  [ d s --  ]
    Removes directory s from object d, leaving any subdirectories in
    place. To remove subdirectories as well, use 'remove_dir-r'.
  
  copy_dir  [ d1 s1 d2 s2 --  ]
    Copies directory s1 from object d1 to directory s2 on object d2.
    This iterative version of will not copy subdirectories, but is
    significantly more efficient than the recursive version 'copy_dir-r'. 
    Use 'copy_dir' if you know that s1 will not include subdirectories,
    or do not wish to copy subdirs if present.
    
  move_dir  [ d1 s1 d2 s2 --  ]
    Moves directory s1 from object d1 to directory s2 on object d2. 
    s1 is deleted from d1. This iterative version of will not move
    subdirectories, but is significantly more efficient than the recursive
    version 'move_dir-r'. Use 'move_dir' if you know that s1 will not
    include subdirectories, or do not wish to move subdirs if present.
  
  remove_dir-r  [ d s --  ]
    Removes directory s and any of its subdirectories from object d.
    Unlike the 'copy' and 'move' routines, there is no significant
    difference in efficiency between 'remove_dir' and 'remove_dir-r'.
    
  copy_dir-r  [ d1 s1 d2 s2 --  ]
    Copies directory s1 and any of its subdirectories from object d1
    to directory s2 on object d2.
    
  move_dir-r  [ d1 s1 d2 s2 --  ]
    Moves directory s1 and any of its subdirectories from object d1
    to directory s2 on object d2. s1 is deleted from d1.
    
  Lib-propdirs may be freely ported. Please comment any changes.
)
 
: copy_prop  ( d1 s1 d2 s2 --  )     (* copy prop s1 on d1 to s2 on d2 *)
    
    4 rotate 4 rotate getprop setprop
;
Public copy_prop
: move_prop  ( d1 s1 d2 s2 --  )     (* move prop s1 on d1 to s2 on d2 *)
    
    4 pick 4 pick getprop setprop remove_prop
;
Public move_prop
  
: remove_dir  ( d s --  )        (* remove dir s from d; leave subdirs *)
    
    dup "*/" smatch not if
        "/" strcat
    then
    
    over over nextprop swap pop
    begin
        dup while
        over over nextprop
        3 pick rot "" setprop
    repeat
    pop pop
;
Public remove_dir
  
: copy_dir   ( d1 s1 d2 s2 --  ) (* copy dir s1 on d1 to dir s2 on d2.
                                    do not copy subdirs               *)
    4 pick 4 pick propdir? if
        3 pick "*/" smatch not if
            3 pick "/" strcat 3 put
        then
    else
        pop pop pop pop exit
    then
    dup "*/" smatch not if
        "/" strcat
    then
    
    3 pick 5 rotate 5 rotate 5 rotate 5 rotate
    dup 5 rotate 5 rotate 5 rotate 5 rotate
    
    4 pick 4 pick nextprop dup 4 put
    5 rotate 5 rotate 5 rotate 5 rotate
    
    begin
        4 pick 4 pick getprop if
            pop over
            7 pick 7 pick swap subst
            4 pick 4 pick 4 pick 4 pick
            4 rotate 4 rotate getprop setprop
            4 pick 4 pick nextprop dup not if
                break
            then
            dup 4 put 5 put
        else
            4 pick 4 pick dup "*/" smatch if
                dup strlen 1 - strcut pop
            then
            over over nextprop not if
                pop pop break
            then
            nextprop dup 4 put 5 put
        then
        pop over 7 pick 7 pick swap subst
    repeat
    pop pop pop pop pop pop pop pop
;
Public copy_dir
    
: move_dir  ( d1 s1 d2 s2 --  )  (* move dir s1 on d1 to dir s2 on d2;
                                    delete originals; do not copy or
                                    delete subdirs                     *)
    4 pick 4 pick 4 pick 4 pick
    copy_dir
    pop pop remove_dir
;
Public move_dir
  
: remove_dir-r  ( d s --  )     (* remove dir s and s's subdirs from d *)
    
    dup "*/" smatch not if
        "/" strcat
    then
    
    over over nextprop swap pop
    begin
        dup while
        over over nextprop
        3 pick rot remove_prop
    repeat
    pop pop
;
Public remove_dir-r
  
: move_dir-r   ( d1 s2 d2 s2 --   )        (* move dir/subdirs s1 on d1
                                              to dir/subdirs s2 on d2  *)
    begin
        4 pick 4 pick propdir? not if
            dup "*/" smatch if
                dup strlen 1 - strcut pop 
            then
            3 pick "*/" smatch if
                3 pick dup strlen 1 - strcut pop 3 put
            then
            4 pick 4 pick getprop setprop remove_prop break
        then
        4 pick 4 pick propdir? if
            4 pick 4 pick 4 pick 4 pick
            dup "*/" smatch not if
                "/" strcat 
            then
            3 pick "*/" smatch not if
                3 pick "/" strcat 3 put
            then
            4 pick 4 pick nextprop dup
            3 pick 6 pick subst 
            2 put 3 put
            move_dir-r
        else
            4 pick 4 pick getprop setprop remove_prop
        then
    repeat
;
Public move_dir-r

: move_root  ( d1 d2 )                  (* move all props on d1 to d2 *)
  
	over "/" nextprop
	begin
	  dup while
    3 pick over 4 pick over move_dir-r
		3 pick swap nextprop
	repeat
	pop pop pop
;
public move_root
  
: copy_dir_loop  ( d1 s1 d2 s2 --  )         (* move dir/subdirs s1 on d1
                                              to dir/subdirs s2 on d2  *)
    begin
        4 pick 4 pick propdir? not if
            dup "*/" smatch if
                dup strlen 1 - strcut pop 
            then
            3 pick "*/" smatch if
                3 pick dup strlen 1 - strcut pop 3 put
            then
            4 pick 4 pick over over
            dup pid intostr "/" strcat swap strcat rot rot
            getprop prog rot rot setprop
            getprop setprop remove_prop break
        then
        4 pick 4 pick propdir? if
            4 pick 4 pick 4 pick 4 pick
            dup "*/" smatch not if
                "/" strcat 
            then
            3 pick "*/" smatch not if
                3 pick "/" strcat 3 put
            then
            4 pick 4 pick nextprop dup
            3 pick 6 pick subst 
            2 put 3 put
            copy_dir_loop
        else
            4 pick 4 pick getprop setprop remove_prop
        then
    repeat
;
  
: copy_dir-r    ( d1 s1 d2 s2 --  )        (* copy dir/subdirs s1 on d1
                                              to dir/subdirs s2 on d2  *)
   
         (* function copies to dest and prog, deleting from source;
            then copies back from prog to source, deleting from prog.     
            This turns out to be more efficient than leaving dir on 
            source and recording info necessary to back out of subdirs *)
                 
    4 pick 4 pick
    6 rotate 6 rotate 6 rotate 6 rotate 
    copy_dir_loop
    prog pid intostr "/" strcat 3 pick strcat
    4 rotate 4 rotate move_dir-r
;
Public copy_dir-r

: copy_root  ( d1 d2 )                  (* copy all props on d1 to d2 *)
  
	over "/" nextprop
	begin
	  dup while
    3 pick over 4 pick over copy_dir-r
		3 pick swap nextprop
	repeat
	pop pop pop
;
public copy_root
.
c
q
@set lib-propdirs=L
@reg lib-propdirs=reg/libpropdirs
@set lib-propdirs=_defs/copy_root:"$lib/propdirs" match "copy_root" call
@set lib-propdirs=_defs/move_root:"$lib/propdirs" match "move_root" call
@set lib-propdirs=_defs/copy_prop:"$lib/propdirs" match "copy_prop" call
@set lib-propdirs=_defs/move_prop:"$lib/propdirs" match "move_prop" call
@set lib-propdirs=_defs/remove_dir:"$lib/propdirs" match "remove_dir" call
@set lib-propdirs=_defs/copy_dir:"$lib/propdirs" match "copy_dir" call
@set lib-propdirs=_defs/move_dir:"$lib/propdirs" match "move_dir" call
@set lib-propdirs=_defs/remove_dir-r:"$lib/propdirs" match "remove_dir-r" call
@set lib-propdirs=_defs/copy_dir-r:"$lib/propdirs" match "copy_dir-r" call
@set lib-propdirs=_defs/move_dir-r:"$lib/propdirs" match "move_dir-r" call