# -*- Tcl -*-
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#.IDENT     $Id: ConFiles.tcl,v 1.1 2004/09/06 14:47:13 cguirao Exp $
#.LANGUAGE  Tcl/Tk
#.AUTHOR    A M Chavan, ESO
#.PURPOSE   Configuration files handling
#.COMMENTS 
#   Definition of functions to handle configuration files.
#
#.VERSION   1.0  08-Feb-94: AMC, Creation
#.VERSION   1.1  09-Mar-94: AMC, Added possibility to read in more
#				 than one configuration file in sequence.
#.VERSION   2.0  21-Oct-96: AMC, Removed dependancy from phrs array.
#--------------------------------------------------------------------

########################################################
#							#
# Initializations					#
#							#
#########################################################

#########################################################
#							#
# Local functions					#
# Names start vith prefix "cf__"			#
#							#
#########################################################

proc cf__ProcessNameValue {n v nvarray} {
    #
    # Substitute shell var values;
    # substitute ~/ sequences with $HOME;
    # initialize nvarray() array
    #
    global env
    upvar $nvarray nva

    set shellVarRegexp {\$([A-z]+)}
    set nt [string trim $n]
    if {$nt == ""} {
	return 0	    	    	;# null names are not allowed
    }
    set vt [string trim $v]

#puts "<$nt> <$vt>"
    regsub "^~/" $vt {$HOME/} vt
    while {[regexp $shellVarRegexp $vt all varname] == 1 } {
	set c ""
	catch {set c $env($varname)} qqq
	regsub $shellVarRegexp $vt $c vt
    }
    
    # names starting with "encrypted-" are decrypted first
    # and the "encrypted-" prefix is removed
    if {[string match {encrypted-*} $nt]} {
	set nva([string range $nt 10 end]) [stdecrypt $vt]
    } else {
	set nva($nt) $vt
    }
    return 1
}

#########################################################
#							#
# Exported Functions					#
# Exported function names start vith a capital letter	#
#							#
#########################################################

#
# NAME
#    ScanConfigFile -- Scan a configuration file & initialize nvarray
#
# SYNOPSIS
#    ScanConfigFile confile nvarray
#
# DESCRIPTION
#    Scan configuration file confile and add name/values pairs to an array.
#
#   A configuration file is an ASCII file. Blank lines and lines
#   beginning with '#' are ignored. Valid lines contain name/value
#   pairs, separated a colon ':' character and possibly white
#   space. Example configuration file:
#
#      #This is an example configuration file
#      # This line is ignored, just like the following blank line
#   
#           Target: a, b, c
#      Secondary Target : aaa      
#      Null valued name:
#      Another null valued name   :
#      : Null name line, ignored like a comment line
#      printer: $PRINTER
#      libs: $HOME/lib:$HOME/lib/tcl
#      My-Temp: ~/tmp
#      encrypted-password: 277c74be674ea893
#    
#      # End of configuration file
#  
#   In the example above: 
#   * name "Target" is associated to value "a, b, c";
#   * name "Secondary Target" is associated to value  "aaa"; 
#   * names "Null valued name" and "Another null valued name" are
#     associated to value "", and are correctly defined;
#   * the values of environment variables $PRINTER and $HOME are used
#     to compute the values of names "printer" and "libs"; names
#     starting with the "~/" string are treated as if they begin with
#     "$HOME/";
#   * null names (i.e., lines beginning with a colon) are silently
#     discarded.
#   * names starting with "encrypted-" are decrypted first, then
#     the "encrypted-" prefix is removed: so the value of the
#     "password" name will be "Secret!" (see stencrypt/stdecrypt).
#   Note that white space around the colon character, and leding and
#   trailing whitespace, are discarded. White space within a name or a
#   value is preserved.
# 
#
# PARAMETERS
#    configf    Pathname of configuration file
#    nvarray    Array where name/value pairs will be added. Exisiting
#               entries will be overwritten.
#
# RETURNS
#    Nothing.
#
# EXAMPLE
#    ScanConfigFile /tmp/base.cf conf
#
#    If the file /tmp/base.cf contains the example configuration file
#    above, after the call to ScanConfigFile the conf array will
#    contain one entry per each valid line of the file: so
#    $conf(Target) will be "a, b, c", etc.
#
# NOTES
#
# HISTORY
#    08-Feb-94 amc	Creation
#    09-Mar-94 amc	Commented out "unset phrs": now when reading
#			more than one configuration file we just
#			keep adding to phrs().
#    21-Oct-96 amc	Removed dependenacy from phrs array.
#

proc ScanConfigFile {configf nvarray} {

    upvar $nvarray nva

    set sc [scancontext create]
    scanmatch $sc {puts "Unrecognized line ($matchInfo(linenum)): <$matchInfo(line)>"}
    scanmatch $sc {^[	 ]*\#} {continue}
    scanmatch $sc {^[	 ]*$} {continue}
    scanmatch $sc {([^:]*):(.*)} {cf__ProcessNameValue $matchInfo(submatch0) $matchInfo(submatch1) nva}

    set f [open $configf r]
    scanfile $sc $f
    close $f
}



proc TestScanConfigFile {configf} {
    ScanConfigFile $configf nva
    foreach n [array names nva] {
	puts "$n: $nva($n)"
    }
}


