Update a configuration file: Difference between revisions

Content deleted Content added
→‎{{header|TXR}}: Uses TXR 041 features.
Line 406: Line 406:
(for L Data
(for L Data
(prinl (glue " " (if (car L) L (cdr L)))) ) ) )</lang>
(prinl (glue " " (if (car L) L (cdr L)))) ) ) )</lang>


=={{header|Python}}==
<lang Python>#!/usr/bin/env python

#----------------------------------------------------------------------------
# STANDARD MODULES
#----------------------------------------------------------------------------
import re
import string

#----------------------------------------------------------------------------
# GLOBAL: VARIABLES
#----------------------------------------------------------------------------
DISABLED_PREFIX = ';'

#----------------------------------------------------------------------------
# CLASS Option
#----------------------------------------------------------------------------
class Option(object):
"""An option, characterized by its name and its (optional) value. and by
its status, which can be enabled or disabled.
If its value is None, it is regarded to as a boolean option with a
value of true.
"""

#------------------------------------------------------------------------
def __init__(self, name, value=None, disabled=False,
disabled_prefix=DISABLED_PREFIX):
"""Create an Option instance, setting its name to 'name' (always
converted to a string) and its value to 'value'. If 'disabled' is
True, the option is considered disabled, otherwise enabled.
The string 'disabled_prefix' is used as a prefix when generating the
string representation of the option.
"""
self.name = str(name)
self.value = value
self.disabled = bool(disabled)
self.disabled_prefix = disabled_prefix

#------------------------------------------------------------------------
def __str__(self):
"""Return a string representation of the Option instance.
This always includes the option name, followed by a space and the
option value (if it is not None). If the option is disabled, the
whole string is preprendend by the string stored in the instance
attribute 'disabled_prefix' and a space.
"""
disabled = ('', '%s ' % self.disabled_prefix)[self.disabled]
value = (' %s' % self.value, '')[self.value is None]
return ''.join((disabled, self.name, value))
#----------------------------------------------------------------------------
# CLASS Config
#----------------------------------------------------------------------------
class Config(object):
"""A set of configuration options and comment strings.
"""
# Regular expression matching a valid option line.
reOPTION = r'^\s*(?P<disabled>%s*)\s*(?P<name>\w+)(?:\s+(?P<value>.+?))?\s*$'

#------------------------------------------------------------------------
def __init__(self, fname=None, disabled_prefix=DISABLED_PREFIX):
"""Initialize a Config instance, optionally reading the contents of
the configuration file 'fname'.
The string 'disabled_prefix' is used as a prefix when generating the
string representation of the options.
"""
self.disabled_prefix = disabled_prefix
self.contents = [] # Sequence of strings and Option instances.
self.options = {} # Map an option name to an Option instance.
self.creOPTION = re.compile(self.reOPTION % self.disabled_prefix)
if fname:
self.parse_file(fname)

#------------------------------------------------------------------------
def __str__(self):
"""Return a string representation of the Config instance.
This is just the concatenation of all the items stored in the
attribute 'contents'.
"""
return '\n'.join(map(str, self.contents))

#------------------------------------------------------------------------
def parse_file(self, fname):
"""Parse all the lines of file 'fname' by applying the method
'parser_lines' on the file contents.
"""
with open(fname) as f:
self.parse_lines(f)
return self

#------------------------------------------------------------------------
def parse_lines(self, lines):
"""Parse all the lines of iterable 'lines' by invoking the method
'parse_line' for each line in 'lines'.
"""
for line in lines:
self.parse_line(line)
return self

#------------------------------------------------------------------------
def parse_line(self, line):
"""Parse the line 'line', looking for options.
If an option line is found, spaces are stripped from the start and
the end of 'line' and any non-printable character is removed as well.
Only the first occurrence of an option is processed, all the other
occurrences are ignored. A valid option is added to the instance
attribute 'contents' (in order to preserve its position among the
other lines). It is also added to the mapping stored in the instance
attribute 'options'.
Any non-option string is added the the instance attribute 'contents',
except those lines starting with the string stored into the instance
attribute 'disabled_prefix' which are not followed by any option
name.
"""
s = ''.join(c for c in line.strip() if c in string.printable)
moOPTION = self.creOPTION.match(s)
if moOPTION:
name = moOPTION.group('name').upper()
if not name in self.options:
self.add_option(name, moOPTION.group('value'),
moOPTION.group('disabled'))
else:
if not s.startswith(self.disabled_prefix):
self.contents.append(line.rstrip())
return self

#------------------------------------------------------------------------
def add_option(self, name, value=None, disabled=False):
"""Create a new Option instance, named 'name' (always converted to
uppercase) with value 'value' and set its disabled status to
'disabled'.
The Option instance is added to the instance attribute 'contents'.
It is also added to the mapping stored in the instance attribute
'options'.
"""
name = name.upper()
opt = Option(name, value, disabled)
self.options[name] = opt
self.contents.append(opt)
return opt

#------------------------------------------------------------------------
def set_option(self, name, value=None, disabled=False):
"""Look for an option named 'name' (always converted to
uppercase) among the options stored in the instance
attribute 'options'.
If it is not found, a new Option instance is created.
In any case its value is set to 'value' and its disabled
status to 'disabled'.
"""
name = name.upper()
opt = self.options.get(name)
if opt:
opt.value = value
opt.disabled = disabled
else:
opt = self.add_option(name, value, disabled)
return opt

#------------------------------------------------------------------------
def enable_option(self, name, value=None):
"""Enable the option named 'name' (always converted to
uppercase) and set its value to 'value'.
If the option is not found, it is created and added to the
end of the instance attribute 'contents'.
"""
return self.set_option(name, value, False)

#------------------------------------------------------------------------
def disable_option(self, name, value=None):
"""Disable the option named 'name' (always converted to
uppercase) and set its value to 'value'.
If the option is not found, it is created and added to the
end of the instance attribute 'contents'.
"""
return self.set_option(name, value, True)

#------------------------------------------------------------------------
def get_option(self, name):
"""Return the value of the option named 'name' (always
converted to uppercase).
If the option is not found in the instance attribute
'options', None is returned. If the stored value is None,
it is regarded to as a boolean option and its enable status
is returned. Othrwise its value is returned.
"""
opt = self.options.get(name.upper())
if opt:
enabled = not bool(opt.disabled)
if opt.value is None:
value = enabled
else:
value = enabled and opt.value
else:
value = None
return value

#----------------------------------------------------------------------------
# MAIN
#----------------------------------------------------------------------------
if __name__ == '__main__':
import sys
cfg = Config(sys.argv[1] if len(sys.argv) > 1 else None)
cfg.disable_option('needspeeling')
cfg.enable_option('seedsremoved')
cfg.enable_option('numberofbananas', 1024)
cfg.enable_option('numberofstrawberries', 62000)
print cfg
</lang>


=={{header|Ruby}}==
=={{header|Ruby}}==