"""Configuration file parser.

A setup file consists of sections, lead by a "[section]" header,
and followed by "name: value" entries, with continuations and such in
the style of rfc822.

The option values can contain format strings which refer to other
values in the same section, or values in a special [DEFAULT] section.
For example:

    something: %(dir)s/whatever

would resolve the "%(dir)s" to the value of dir.  All reference
expansions are done late, on demand.

Intrinsic defaults can be specified by passing them into the
ConfigParser constructor as a dictionary.

class:

ConfigParser -- responsible for for parsing a list of
                configuration files, and managing the parsed database.

    methods:

    __init__(defaults=None) -- create the parser and specify a
                               dictionary of intrinsic defaults.  The
                               keys must be strings, the values must
                               be appropriate for %()s string
                               interpolation.  Note that `name' is
                               always an intrinsic default; it's value
                               is the section's name.

    sections() -- return all the configuration section names, sans DEFAULT

    options(section) -- return list of configuration options for the named
			section

    read(*filenames) -- read and parse the list of named configuration files

    get(section, option, raw=0) -- return a string value for the named
				   option.  All % interpolations are
				   expanded in the return values, based on
				   the defaults passed into the constructor
				   and the DEFAULT section.

    getint(section, options) -- like get(), but convert value to an integer

    getfloat(section, options) -- like get(), but convert value to a float

    getboolean(section, options) -- like get(), but convert value to
				    a boolean (currently defined as 0
				    or 1, only)
"""

import sys
import string
import regex
from types import ListType


SECTHEAD_RE = "^\[\([-A-Za-z0-9]*\)\][" + string.whitespace + "]*$"
secthead_cre = regex.compile(SECTHEAD_RE)
OPTION_RE = "^\([-A-Za-z0-9.]+\)\(:\|[" + string.whitespace + "]*=\)\(.*\)$"
option_cre = regex.compile(OPTION_RE)

DEFAULTSECT = "DEFAULT"



# exception classes
class Error:
    def __init__(self, msg=''):
	self.__msg = msg
    def __repr__(self):
	return self.__msg

class NoSectionError(Error):
    def __init__(self, section):
	Error.__init__(self, 'No section: %s' % section)
	self.section = section

class DuplicateSectionError(Error):
    def __init__(self, section):
	Error.__init__(self, "Section %s already exists" % section)
	self.section = section

class NoOptionError(Error):
    def __init__(self, option, section):
	Error.__init__(self, "No option `%s' in section: %s" %
		       (option, section))
	self.option = option
	self.section = section

class InterpolationError(Error):
    def __init__(self, reference, option, section):
	Error.__init__(self,
		       "Bad value substitution: sect `%s', opt `%s', ref `%s'"
		       % (section, option, reference))
	self.reference = reference
	self.option = option
	self.section = section



class ConfigParser:
    def __init__(self, defaults=None):
	self.__sections = {}
	if defaults is None:
	    self.__defaults = {}
	else:
	    self.__defaults = defaults

    def defaults(self):
	return self.__defaults

    def sections(self):
	"""Return a list of section names, excluding [DEFAULT]"""
	# self.__sections will never have [DEFAULT] in it
	return self.__sections.keys()

    def add_section(self, section):
	"""Create a new section in the configuration.

	Raise DuplicateSectionError if a section by the specified name
	already exists.
	"""
	if self.__sections.has_key(section):
	    raise DuplicateSectionError(section)
	self.__sections[section] = {}

    def has_section(self, section):
	"""Indicate whether the named section is present in the configuration.

	The DEFAULT section is not acknowledged.
	"""
	return self.__sections.has_key(section)

    def options(self, section):
	try:
	    opts = self.__sections[section].copy()
	except KeyError:
	    raise NoSectionError(section)
	opts.update(self.__defaults)
	return opts.keys()

    def read(self, filenames):
	"""Read and parse a list of filenames."""
	if type(filenames) is type(''):
	    filenames = [filenames]
	for file in filenames:
	    try:
		fp = open(file, 'r')
		self.__read(fp)
	    except IOError:
		pass

    def get(self, section, option, raw=0):
	"""Get an option value for a given section.

	All % interpolations are expanded in the return values, based
	on the defaults passed into the constructor.

	The section DEFAULT is special.
	"""
	try:
	    d = self.__sections[section].copy()
	except KeyError:
	    if section == DEFAULTSECT:
		d = {}
	    else:
		raise NoSectionError(section)
	d.update(self.__defaults)
	option = string.lower(option)
	try:
	    rawval = d[option]
	except KeyError:
	    raise NoOptionError(option, section)
	# do the string interpolation
	if raw:
	    return rawval
	try:
	    return rawval % d
	except KeyError, key:
	    raise InterpolationError(key, option, section)

    def __get(self, section, conv, option):
	return conv(self.get(section, option))

    def getint(self, section, option):
	return self.__get(section, string.atoi, option)

    def getfloat(self, section, option):
	return self.__get(section, string.atof, option)

    def getboolean(self, section, option):
	v = self.get(section, option)
	val = string.atoi(v)
	if val not in (0, 1):
	    raise ValueError, 'Not a boolean: %s' % v
	return val

    def __read(self, fp):
	"""Parse a sectioned setup file.

	The sections in setup file contains a title line at the top,
	indicated by a name in square brackets (`[]'), plus key/value
	options lines, indicated by `name: value' format lines.
	Continuation are represented by an embedded newline then
	leading whitespace.  Blank lines, lines beginning with a '#',
	and just about everything else is ignored.
	"""
	cursect = None			# None, or a dictionary
	optname = None
	lineno = 0
	while 1:
	    line = fp.readline()
	    if not line:
		break
	    lineno = lineno + 1
	    # comment or blank line?
	    if string.strip(line) == '' or line[0] in '#;':
		continue
	    if string.lower(string.split(line)[0]) == 'rem' \
	       and line[0] == "r":	# no leading whitespace
		continue
	    # continuation line?
	    if line[0] in ' \t' and cursect <> None and optname:
		value = string.strip(line)
		if value:
		    cursect = cursect[optname] + '\n ' + value
	    # a section header?
	    elif secthead_cre.match(line) >= 0:
		sectname = secthead_cre.group(1)
		if self.__sections.has_key(sectname):
		    cursect = self.__sections[sectname]
		elif sectname == DEFAULTSECT:
		    cursect = self.__defaults
		else:
		    cursect = {'name': sectname}
		    self.__sections[sectname] = cursect
		# So sections can't start with a continuation line.
		optname = None
	    # an option line?
	    elif option_cre.match(line) >= 0:
		optname, optval = option_cre.group(1, 3)
		optname = string.lower(optname)
		optval = string.strip(optval)
		# allow empty values
		if optval == '""':
		    optval = ''
		cursect[optname] = optval
	    # an error
	    else:
		print 'Error in %s at %d: %s', (fp.name, lineno, `line`)
