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}}== |