#!/bin/sh  
# \
exec oagtclsh "$0" "$@"

# $Log: not supported by cvs2svn $
# Revision 1.5  1999/11/15 18:53:24  borland
# Now replaces readback names also if NewReadbackName is present in the file.
#
# Revision 1.4  1999/04/15 14:59:44  borland
# Multipass algorithm now works with linked files, also.
#
# Revision 1.3  1999/04/15 14:31:24  borland
# Now does two passes to ensure that all name changes and PV deletions are
# detected.  In some cases, a PV was renamed and then deleted in one
# xref file.
#
# Revision 1.2  1999/03/15 15:35:31  borland
# Now works properly when the xref file is in a different directory from
# the files being modified.
#
# Revision 1.1  1999/03/15 15:28:47  borland
# First version.  Processes SDDS files to replace ControlName data according
# to a cross-reference file containing OldControlName and NewControlName.
#

set auto_path [linsert $auto_path 0  /usr/local/oag/apps/lib/$env(HOST_ARCH)]
set auto_path [linsert $auto_path 0 /usr/local/oag/lib_patch/$env(HOST_ARCH)]
APSStandardSetup

set usage "usage: replaceControlNames -xrefFile <name> -fileList <list> \[-test 1\] \[-removeBad 1\]\nThe file list may include unresolved wildcard sequences."
set xrefFile ""
set fileList ""
set test 0
set removeBad 0
set args $argv
if {[APSStrictParseArguments {xrefFile fileList test removeBad}] || \
        ![string length $xrefFile] || ![llength $fileList]} {
    puts stderr $usage
    exit 1
}
if ![file exists $xrefFile] {
    puts stderr "Not found: $xrefFile"
    exit 1
}
set xrefColumnList [APSGetSDDSNames -class column -fileName $xrefFile]

# Get the full filename for the xrefFile
set tailName [file tail $xrefFile]
set dirName [file dirname $xrefFile]
set oldDir [pwd]
cd $dirName
set dirName [pwd]
cd $oldDir
set xrefFile $dirName/$tailName

foreach item $fileList {
    set matchList [lsort [glob -nocomplain $item]]
    if ![llength $matchList] {
        puts stderr "No match: $item"
        continue
    }
    foreach filename $matchList {
        puts stderr "Working on $filename"
        set directory [file dirname $filename]
        set oldDir [pwd]
        set filename [file tail $filename]
        cd $directory
        set tmpRoot /tmp/[APSTmpString]
        if [string compare [file type $filename] link]==0 {
            set newname [APSNextGenerationedName \
                           -name [file tail [file readlink $filename]]]
            set isLink 1
            file copy -force [file readlink $filename] $tmpRoot.orig
        } else {
            if [catch {file copy -force $filename ${filename}~} result] {
                puts stderr "$result"
                cd $oldDir
                continue
            }
            set newname $filename
            set filename ${filename}~
            set isLink 0
            file copy -force $filename $tmpRoot.orig
        }
        set startFile $tmpRoot.orig
        set takeColumnList NewControlName
        set deleteColumnList ControlName
        set renameColumnList NewControlName=ControlName 
        set procOpt1 ""
        if [lsearch -exact $xrefColumnList NewReadbackName]!=-1 {
            lappend takeColumnList NewReadbackName
            lappend deleteColumnList ReadbackName
            lappend renameColumnList NewReadbackName=ReadbackName
            set procOpt1 -match=column,ReadbackName=,!
        }
        for {set pass 0} {$pass<2} {incr pass} {
            if [catch {eval exec sddsxref $startFile $xrefFile -pipe=out \
                         -match=ControlName=OldControlName \
                         -take=[join $takeColumnList ,] -nowarning -reuse=row \
                         | sddsconvert -pipe -nowarning \
                         -delete=column,[join $deleteColumnList ,] \
                         | sddsconvert -pipe \
                         -rename=column,[join $renameColumnList ,] \
                         | sddsprocess -pipe=in $tmpRoot.changed \
                         -match=column,ControlName=,! $procOpt1 -nowarning
                exec sddsselect $startFile $xrefFile $tmpRoot.same -nowarning \
                         -match=ControlName=OldControlName -invert -reuse=row
                exec sddscombine $tmpRoot.changed $tmpRoot.same -merge \
                         $tmpRoot.new -overwrite} result] {
                puts stderr "$result"
                cd $oldDir
                break
            }
            file copy -force $tmpRoot.new $startFile
            eval file delete -force $tmpRoot.same $tmpRoot.changed
        }
        if $pass!=2 continue
        file copy -force $startFile $newname
        eval file delete $startFile $tmpRoot.orig
        if {$test || $removeBad} {
            if [catch {exec sddsconvert $newname -pipe=out -dele=param,* \
                         | sddssnapshot -pipe \
                         | sddsxref $newname -pipe -leave=* -transfer=param,* \
                         | tee $newname.snap \
                         | sddsprocess -pipe=in $newname.bad -nowarning \
                         -match=column,CAError=y} result] {
                puts stderr "$result"
            }
            catch {exec sdds2stream -rows $newname.bad | token -n=1} rows
            if $rows==0 {
                eval file delete -force $newname.bad $newname.snap
            } else {
                puts stderr "$rows bad PVs (listed in $newname.bad)"
                if $removeBad {
                    if [catch {exec sddsprocess $newname.snap -pipe=out \
                                 -match=column,CAError=n \
                                 | sddsconvert -pipe=in $newname \
                                 -delete=column,CAError,Value} result] {
                        puts stderr "$result"
                        eval file delete -force $newname $newname.snap
                        cd $oldDir
                        contine
                    }
                    eval file delete -force $newname.snap
                }
            }
        }
        puts stderr "Old file: [exec sdds2stream -rows $filename]    New file: [exec sdds2stream -rows $newname]"
        if {$isLink && [file exists $newname]} {
            eval file delete -force $filename
            if [catch {exec ln -s $newname $filename} result] {
                puts stderr "$result"
                continue
            }
        }
        cd $oldDir
    }
}
