#
# Create a directory shadowing a specified one.  Intended application is
# to allow multiple Starlab trees to share a single source tree, for use
# with different architectures or compiler options.

if ($#argv < 1) then
    echo Usage: shadowdir target-directory-name \[shadow-directory-name\]
    exit
endif

if (! -e $1) then
    echo Directory $1 not found
    exit
endif

#-----------------------------------------------------------------------

#   Make a list of identifiers for files which should be saved if
#   they already exist in the shadow tree, and which should *not*
#   be linked to counterparts in the real (CVS) source tree.

set PRECIOUS = (local/cshrc.starlab hdyn/evolve/Makefile hdyn/util/Makefile)

# Bad because we still have to enumerate the filenames below.

#-----------------------------------------------------------------------

# Hmmm...  Looks like DecUNIX and Linux finds operate differently!
# Keep track of which OS we are using (choice of only two, for now).
# Intent here is just to look at the files in the current directory,
# without descending into subdirectories.  Keep this under review...

if (X`uname` == XOSF1) then
    alias ff 'find * -prune'
else
    alias ff 'find . -maxdepth 1'
endif

# Handy alias (to shorten the command line):

alias gr 'grep -v CVS'

#-----------------------------------------------------------------------

# Make sure curr is a full pathname (not relative to .).  Note that,
# as usual, we have to be careful of the "pwd" functions.  On DecUNIX,
# the command pwd prepends a /tmp_mount to all automounted directory
# names, which causes symbolic links to fail on linux, which doesn't
# prepend and doesn't understand.  In csh, the $cwd variable in csh
# also has the /tmp_mount, and $PWD doesn't exist.  Hence we have to
# use tcsh (where pwd, cwd and PWD are all fine even in DecUNIX).
# However, we can't force this in the #magic first line, because we
# don't know where tcsh is in general (/usr/local/bin in DecUNIX, /bin
# in linux)!!  Thus, the best we can do is to use the # and assume
# that we are using tcsh when we invoke this script!  What an annoying
# operating system...

set curr = $cwd
chdir $1
set dir = $cwd
chdir $curr

#-----------------------------------------------------------------------

set shadow = ~/shadow_tmp
if ($#argv > 1) set shadow = $2

echo Source directory = $dir, shadow = $shadow

set dlist = (`chdir $dir; find . -type d | grep -v CVS`) # not too many, I hope!

if ($#dlist > 0) then

#   List of precious files actually saved.

    set savelist = ()

#   Remove any existing shadow directory.

    if (-d $shadow) then

#	Ask before overwriting an existing directory.

	echo -n "Overwrite existing directory $shadow? "
	set resp = $<

	if (X$resp != Xy && X$resp != XY) then
	    echo Aborted
	    exit
	endif

#	Must save some files in the Starlab shadow directory tree to
#	avoid having them overwritten or deleted.  Their directories
#	are defined in $PRECIOUS.  If the files exist in the current
#	shadow directory tree, save them and restore them at the end.
#	A (somewhat half-baked) way of doing this follows:

	chdir $shadow
	set mlist = (`find . -name Makefile -o -name cshrc.starlab`)

	if ($#mlist > 0) then
	    @ i = 0
	    foreach p ($PRECIOUS)
	    foreach m ($mlist)
		set tmp = (`echo $m | grep $p`)
		if ("X$tmp" != "X") then
		    if (! -l $tmp) then

			@ i++
			set savename = $curr/precious.save.$i

#			File exists and is a real file (not a link).
#			Save the file ($tmp) as $savename and store
#			its name in $savelist[$i].

			mv $tmp $savename
			set savelist = ($savelist $tmp)

			echo Saved $shadow/$tmp in $savename

		    endif
		endif
	    end
	    end
	endif
	chdir $curr

	/bin/rm -r -f $shadow
	echo Directory deleted

    endif

    mkdir $shadow
    chdir $shadow

#   Make shadow into a full pathname.

    set shadow = $cwd

#   Create the entire shadow directory tree before making any links.

    foreach sub ($dlist)

#	Order of traversal by find should ensure that parent
#	directories precede their children on the list.
 
	if (! -d $sub) then
	    mkdir $sub
#	    echo Created $sub
	endif

    end

    echo Created shadow directory tree of $#dlist nodes

#   Now traverse the shadow tree, creating links to all
#   source and header files.

    foreach sub ($dlist)

#	Check if some files should not be linked.

	set make_link = 1
	foreach p ($PRECIOUS)
	    set tmp = `echo $sub | grep $p:h`
	    if (X$tmp != X) set make_link = 0
	end

#	List relevant files in just the directory $dir/$sub.
#	(Note special Starlab cases for setup...)

	if (X$sub == X.) then
	    set flist = (starlab_start VERSION Makefile)	# Starlab...
	else if (X$sub == X./local || X$sub == X./sbin) then
	    set flist = (`chdir $dir/$sub; ff -type f`)
	else
	    set flist = \
		(`chdir $dir/$sub; ff -name '*.[cCfFh]' -o -name '[A-Z]*' | gr`)
	endif

	if ($#flist > 0) then
	    foreach file ($flist)
		if (-e $dir/$sub/$file) then
		    if ($make_link == 0 && \
			($file == Makefile || $file == ./Makefile \
			 || $file == cshrc.starlab \
			 || $file == ./cshrc.starlab) ) then
			echo "    *** " Skipping $sub/$file "***"
		    else
			ln -s $dir/$sub/$file $shadow/$sub/$file
		    endif
		endif
	    end
	    echo "   " $#flist links in $sub
	endif
    end

    echo "Shadow directory $shadow successfuly created"

    if ($#savelist > 0) then

#	Restore saved files.

	chdir $shadow
        @ i = 0
	foreach m ($savelist)
	    @ i++
	    mv $curr/precious.save.$i $savelist[$i]

	    echo Restored $shadow/$savelist[$i]

	end
	chdir $curr
    endif

endif
