Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / devtools / v9 / lib / python2.4 / ConfigParser.py
CommitLineData
920dae64
AT
1"""Configuration file parser.
2
3A setup file consists of sections, lead by a "[section]" header,
4and followed by "name: value" entries, with continuations and such in
5the style of RFC 822.
6
7The option values can contain format strings which refer to other values in
8the same section, or values in a special [DEFAULT] section.
9
10For example:
11
12 something: %(dir)s/whatever
13
14would resolve the "%(dir)s" to the value of dir. All reference
15expansions are done late, on demand.
16
17Intrinsic defaults can be specified by passing them into the
18ConfigParser constructor as a dictionary.
19
20class:
21
22ConfigParser -- responsible for parsing a list of
23 configuration files, and managing the parsed database.
24
25 methods:
26
27 __init__(defaults=None)
28 create the parser and specify a dictionary of intrinsic defaults. The
29 keys must be strings, the values must be appropriate for %()s string
30 interpolation. Note that `__name__' is always an intrinsic default;
31 its value is the section's name.
32
33 sections()
34 return all the configuration section names, sans DEFAULT
35
36 has_section(section)
37 return whether the given section exists
38
39 has_option(section, option)
40 return whether the given option exists in the given section
41
42 options(section)
43 return list of configuration options for the named section
44
45 read(filenames)
46 read and parse the list of named configuration files, given by
47 name. A single filename is also allowed. Non-existing files
48 are ignored. Return list of successfully read files.
49
50 readfp(fp, filename=None)
51 read and parse one configuration file, given as a file object.
52 The filename defaults to fp.name; it is only used in error
53 messages (if fp has no `name' attribute, the string `<???>' is used).
54
55 get(section, option, raw=False, vars=None)
56 return a string value for the named option. All % interpolations are
57 expanded in the return values, based on the defaults passed into the
58 constructor and the DEFAULT section. Additional substitutions may be
59 provided using the `vars' argument, which must be a dictionary whose
60 contents override any pre-existing defaults.
61
62 getint(section, options)
63 like get(), but convert value to an integer
64
65 getfloat(section, options)
66 like get(), but convert value to a float
67
68 getboolean(section, options)
69 like get(), but convert value to a boolean (currently case
70 insensitively defined as 0, false, no, off for False, and 1, true,
71 yes, on for True). Returns False or True.
72
73 items(section, raw=False, vars=None)
74 return a list of tuples with (name, value) for each option
75 in the section.
76
77 remove_section(section)
78 remove the given file section and all its options
79
80 remove_option(section, option)
81 remove the given option from the given section
82
83 set(section, option, value)
84 set the given option
85
86 write(fp)
87 write the configuration state in .ini format
88"""
89
90import re
91
92__all__ = ["NoSectionError", "DuplicateSectionError", "NoOptionError",
93 "InterpolationError", "InterpolationDepthError",
94 "InterpolationSyntaxError", "ParsingError",
95 "MissingSectionHeaderError",
96 "ConfigParser", "SafeConfigParser", "RawConfigParser",
97 "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"]
98
99DEFAULTSECT = "DEFAULT"
100
101MAX_INTERPOLATION_DEPTH = 10
102
103
104
105# exception classes
106class Error(Exception):
107 """Base class for ConfigParser exceptions."""
108
109 def __init__(self, msg=''):
110 self.message = msg
111 Exception.__init__(self, msg)
112
113 def __repr__(self):
114 return self.message
115
116 __str__ = __repr__
117
118class NoSectionError(Error):
119 """Raised when no section matches a requested option."""
120
121 def __init__(self, section):
122 Error.__init__(self, 'No section: %r' % (section,))
123 self.section = section
124
125class DuplicateSectionError(Error):
126 """Raised when a section is multiply-created."""
127
128 def __init__(self, section):
129 Error.__init__(self, "Section %r already exists" % section)
130 self.section = section
131
132class NoOptionError(Error):
133 """A requested option was not found."""
134
135 def __init__(self, option, section):
136 Error.__init__(self, "No option %r in section: %r" %
137 (option, section))
138 self.option = option
139 self.section = section
140
141class InterpolationError(Error):
142 """Base class for interpolation-related exceptions."""
143
144 def __init__(self, option, section, msg):
145 Error.__init__(self, msg)
146 self.option = option
147 self.section = section
148
149class InterpolationMissingOptionError(InterpolationError):
150 """A string substitution required a setting which was not available."""
151
152 def __init__(self, option, section, rawval, reference):
153 msg = ("Bad value substitution:\n"
154 "\tsection: [%s]\n"
155 "\toption : %s\n"
156 "\tkey : %s\n"
157 "\trawval : %s\n"
158 % (section, option, reference, rawval))
159 InterpolationError.__init__(self, option, section, msg)
160 self.reference = reference
161
162class InterpolationSyntaxError(InterpolationError):
163 """Raised when the source text into which substitutions are made
164 does not conform to the required syntax."""
165
166class InterpolationDepthError(InterpolationError):
167 """Raised when substitutions are nested too deeply."""
168
169 def __init__(self, option, section, rawval):
170 msg = ("Value interpolation too deeply recursive:\n"
171 "\tsection: [%s]\n"
172 "\toption : %s\n"
173 "\trawval : %s\n"
174 % (section, option, rawval))
175 InterpolationError.__init__(self, option, section, msg)
176
177class ParsingError(Error):
178 """Raised when a configuration file does not follow legal syntax."""
179
180 def __init__(self, filename):
181 Error.__init__(self, 'File contains parsing errors: %s' % filename)
182 self.filename = filename
183 self.errors = []
184
185 def append(self, lineno, line):
186 self.errors.append((lineno, line))
187 self.message += '\n\t[line %2d]: %s' % (lineno, line)
188
189class MissingSectionHeaderError(ParsingError):
190 """Raised when a key-value pair is found before any section header."""
191
192 def __init__(self, filename, lineno, line):
193 Error.__init__(
194 self,
195 'File contains no section headers.\nfile: %s, line: %d\n%r' %
196 (filename, lineno, line))
197 self.filename = filename
198 self.lineno = lineno
199 self.line = line
200
201
202
203class RawConfigParser:
204 def __init__(self, defaults=None):
205 self._sections = {}
206 self._defaults = {}
207 if defaults:
208 for key, value in defaults.items():
209 self._defaults[self.optionxform(key)] = value
210
211 def defaults(self):
212 return self._defaults
213
214 def sections(self):
215 """Return a list of section names, excluding [DEFAULT]"""
216 # self._sections will never have [DEFAULT] in it
217 return self._sections.keys()
218
219 def add_section(self, section):
220 """Create a new section in the configuration.
221
222 Raise DuplicateSectionError if a section by the specified name
223 already exists.
224 """
225 if section in self._sections:
226 raise DuplicateSectionError(section)
227 self._sections[section] = {}
228
229 def has_section(self, section):
230 """Indicate whether the named section is present in the configuration.
231
232 The DEFAULT section is not acknowledged.
233 """
234 return section in self._sections
235
236 def options(self, section):
237 """Return a list of option names for the given section name."""
238 try:
239 opts = self._sections[section].copy()
240 except KeyError:
241 raise NoSectionError(section)
242 opts.update(self._defaults)
243 if '__name__' in opts:
244 del opts['__name__']
245 return opts.keys()
246
247 def read(self, filenames):
248 """Read and parse a filename or a list of filenames.
249
250 Files that cannot be opened are silently ignored; this is
251 designed so that you can specify a list of potential
252 configuration file locations (e.g. current directory, user's
253 home directory, systemwide directory), and all existing
254 configuration files in the list will be read. A single
255 filename may also be given.
256
257 Return list of successfully read files.
258 """
259 if isinstance(filenames, basestring):
260 filenames = [filenames]
261 read_ok = []
262 for filename in filenames:
263 try:
264 fp = open(filename)
265 except IOError:
266 continue
267 self._read(fp, filename)
268 fp.close()
269 read_ok.append(filename)
270 return read_ok
271
272 def readfp(self, fp, filename=None):
273 """Like read() but the argument must be a file-like object.
274
275 The `fp' argument must have a `readline' method. Optional
276 second argument is the `filename', which if not given, is
277 taken from fp.name. If fp has no `name' attribute, `<???>' is
278 used.
279
280 """
281 if filename is None:
282 try:
283 filename = fp.name
284 except AttributeError:
285 filename = '<???>'
286 self._read(fp, filename)
287
288 def get(self, section, option):
289 opt = self.optionxform(option)
290 if section not in self._sections:
291 if section != DEFAULTSECT:
292 raise NoSectionError(section)
293 if opt in self._defaults:
294 return self._defaults[opt]
295 else:
296 raise NoOptionError(option, section)
297 elif opt in self._sections[section]:
298 return self._sections[section][opt]
299 elif opt in self._defaults:
300 return self._defaults[opt]
301 else:
302 raise NoOptionError(option, section)
303
304 def items(self, section):
305 try:
306 d2 = self._sections[section]
307 except KeyError:
308 if section != DEFAULTSECT:
309 raise NoSectionError(section)
310 d2 = {}
311 d = self._defaults.copy()
312 d.update(d2)
313 if "__name__" in d:
314 del d["__name__"]
315 return d.items()
316
317 def _get(self, section, conv, option):
318 return conv(self.get(section, option))
319
320 def getint(self, section, option):
321 return self._get(section, int, option)
322
323 def getfloat(self, section, option):
324 return self._get(section, float, option)
325
326 _boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True,
327 '0': False, 'no': False, 'false': False, 'off': False}
328
329 def getboolean(self, section, option):
330 v = self.get(section, option)
331 if v.lower() not in self._boolean_states:
332 raise ValueError, 'Not a boolean: %s' % v
333 return self._boolean_states[v.lower()]
334
335 def optionxform(self, optionstr):
336 return optionstr.lower()
337
338 def has_option(self, section, option):
339 """Check for the existence of a given option in a given section."""
340 if not section or section == DEFAULTSECT:
341 option = self.optionxform(option)
342 return option in self._defaults
343 elif section not in self._sections:
344 return False
345 else:
346 option = self.optionxform(option)
347 return (option in self._sections[section]
348 or option in self._defaults)
349
350 def set(self, section, option, value):
351 """Set an option."""
352 if not section or section == DEFAULTSECT:
353 sectdict = self._defaults
354 else:
355 try:
356 sectdict = self._sections[section]
357 except KeyError:
358 raise NoSectionError(section)
359 sectdict[self.optionxform(option)] = value
360
361 def write(self, fp):
362 """Write an .ini-format representation of the configuration state."""
363 if self._defaults:
364 fp.write("[%s]\n" % DEFAULTSECT)
365 for (key, value) in self._defaults.items():
366 fp.write("%s = %s\n" % (key, str(value).replace('\n', '\n\t')))
367 fp.write("\n")
368 for section in self._sections:
369 fp.write("[%s]\n" % section)
370 for (key, value) in self._sections[section].items():
371 if key != "__name__":
372 fp.write("%s = %s\n" %
373 (key, str(value).replace('\n', '\n\t')))
374 fp.write("\n")
375
376 def remove_option(self, section, option):
377 """Remove an option."""
378 if not section or section == DEFAULTSECT:
379 sectdict = self._defaults
380 else:
381 try:
382 sectdict = self._sections[section]
383 except KeyError:
384 raise NoSectionError(section)
385 option = self.optionxform(option)
386 existed = option in sectdict
387 if existed:
388 del sectdict[option]
389 return existed
390
391 def remove_section(self, section):
392 """Remove a file section."""
393 existed = section in self._sections
394 if existed:
395 del self._sections[section]
396 return existed
397
398 #
399 # Regular expressions for parsing section headers and options.
400 #
401 SECTCRE = re.compile(
402 r'\[' # [
403 r'(?P<header>[^]]+)' # very permissive!
404 r'\]' # ]
405 )
406 OPTCRE = re.compile(
407 r'(?P<option>[^:=\s][^:=]*)' # very permissive!
408 r'\s*(?P<vi>[:=])\s*' # any number of space/tab,
409 # followed by separator
410 # (either : or =), followed
411 # by any # space/tab
412 r'(?P<value>.*)$' # everything up to eol
413 )
414
415 def _read(self, fp, fpname):
416 """Parse a sectioned setup file.
417
418 The sections in setup file contains a title line at the top,
419 indicated by a name in square brackets (`[]'), plus key/value
420 options lines, indicated by `name: value' format lines.
421 Continuations are represented by an embedded newline then
422 leading whitespace. Blank lines, lines beginning with a '#',
423 and just about everything else are ignored.
424 """
425 cursect = None # None, or a dictionary
426 optname = None
427 lineno = 0
428 e = None # None, or an exception
429 while True:
430 line = fp.readline()
431 if not line:
432 break
433 lineno = lineno + 1
434 # comment or blank line?
435 if line.strip() == '' or line[0] in '#;':
436 continue
437 if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR":
438 # no leading whitespace
439 continue
440 # continuation line?
441 if line[0].isspace() and cursect is not None and optname:
442 value = line.strip()
443 if value:
444 cursect[optname] = "%s\n%s" % (cursect[optname], value)
445 # a section header or option header?
446 else:
447 # is it a section header?
448 mo = self.SECTCRE.match(line)
449 if mo:
450 sectname = mo.group('header')
451 if sectname in self._sections:
452 cursect = self._sections[sectname]
453 elif sectname == DEFAULTSECT:
454 cursect = self._defaults
455 else:
456 cursect = {'__name__': sectname}
457 self._sections[sectname] = cursect
458 # So sections can't start with a continuation line
459 optname = None
460 # no section header in the file?
461 elif cursect is None:
462 raise MissingSectionHeaderError(fpname, lineno, line)
463 # an option line?
464 else:
465 mo = self.OPTCRE.match(line)
466 if mo:
467 optname, vi, optval = mo.group('option', 'vi', 'value')
468 if vi in ('=', ':') and ';' in optval:
469 # ';' is a comment delimiter only if it follows
470 # a spacing character
471 pos = optval.find(';')
472 if pos != -1 and optval[pos-1].isspace():
473 optval = optval[:pos]
474 optval = optval.strip()
475 # allow empty values
476 if optval == '""':
477 optval = ''
478 optname = self.optionxform(optname.rstrip())
479 cursect[optname] = optval
480 else:
481 # a non-fatal parsing error occurred. set up the
482 # exception but keep going. the exception will be
483 # raised at the end of the file and will contain a
484 # list of all bogus lines
485 if not e:
486 e = ParsingError(fpname)
487 e.append(lineno, repr(line))
488 # if any parsing errors occurred, raise an exception
489 if e:
490 raise e
491
492
493class ConfigParser(RawConfigParser):
494
495 def get(self, section, option, raw=False, vars=None):
496 """Get an option value for a given section.
497
498 All % interpolations are expanded in the return values, based on the
499 defaults passed into the constructor, unless the optional argument
500 `raw' is true. Additional substitutions may be provided using the
501 `vars' argument, which must be a dictionary whose contents overrides
502 any pre-existing defaults.
503
504 The section DEFAULT is special.
505 """
506 d = self._defaults.copy()
507 try:
508 d.update(self._sections[section])
509 except KeyError:
510 if section != DEFAULTSECT:
511 raise NoSectionError(section)
512 # Update with the entry specific variables
513 if vars:
514 for key, value in vars.items():
515 d[self.optionxform(key)] = value
516 option = self.optionxform(option)
517 try:
518 value = d[option]
519 except KeyError:
520 raise NoOptionError(option, section)
521
522 if raw:
523 return value
524 else:
525 return self._interpolate(section, option, value, d)
526
527 def items(self, section, raw=False, vars=None):
528 """Return a list of tuples with (name, value) for each option
529 in the section.
530
531 All % interpolations are expanded in the return values, based on the
532 defaults passed into the constructor, unless the optional argument
533 `raw' is true. Additional substitutions may be provided using the
534 `vars' argument, which must be a dictionary whose contents overrides
535 any pre-existing defaults.
536
537 The section DEFAULT is special.
538 """
539 d = self._defaults.copy()
540 try:
541 d.update(self._sections[section])
542 except KeyError:
543 if section != DEFAULTSECT:
544 raise NoSectionError(section)
545 # Update with the entry specific variables
546 if vars:
547 for key, value in vars.items():
548 d[self.optionxform(key)] = value
549 options = d.keys()
550 if "__name__" in options:
551 options.remove("__name__")
552 if raw:
553 return [(option, d[option])
554 for option in options]
555 else:
556 return [(option, self._interpolate(section, option, d[option], d))
557 for option in options]
558
559 def _interpolate(self, section, option, rawval, vars):
560 # do the string interpolation
561 value = rawval
562 depth = MAX_INTERPOLATION_DEPTH
563 while depth: # Loop through this until it's done
564 depth -= 1
565 if "%(" in value:
566 value = self._KEYCRE.sub(self._interpolation_replace, value)
567 try:
568 value = value % vars
569 except KeyError, e:
570 raise InterpolationMissingOptionError(
571 option, section, rawval, e[0])
572 else:
573 break
574 if "%(" in value:
575 raise InterpolationDepthError(option, section, rawval)
576 return value
577
578 _KEYCRE = re.compile(r"%\(([^)]*)\)s|.")
579
580 def _interpolation_replace(self, match):
581 s = match.group(1)
582 if s is None:
583 return match.group()
584 else:
585 return "%%(%s)s" % self.optionxform(s)
586
587
588class SafeConfigParser(ConfigParser):
589
590 def _interpolate(self, section, option, rawval, vars):
591 # do the string interpolation
592 L = []
593 self._interpolate_some(option, L, rawval, section, vars, 1)
594 return ''.join(L)
595
596 _interpvar_match = re.compile(r"%\(([^)]+)\)s").match
597
598 def _interpolate_some(self, option, accum, rest, section, map, depth):
599 if depth > MAX_INTERPOLATION_DEPTH:
600 raise InterpolationDepthError(option, section, rest)
601 while rest:
602 p = rest.find("%")
603 if p < 0:
604 accum.append(rest)
605 return
606 if p > 0:
607 accum.append(rest[:p])
608 rest = rest[p:]
609 # p is no longer used
610 c = rest[1:2]
611 if c == "%":
612 accum.append("%")
613 rest = rest[2:]
614 elif c == "(":
615 m = self._interpvar_match(rest)
616 if m is None:
617 raise InterpolationSyntaxError(option, section,
618 "bad interpolation variable reference %r" % rest)
619 var = self.optionxform(m.group(1))
620 rest = rest[m.end():]
621 try:
622 v = map[var]
623 except KeyError:
624 raise InterpolationMissingOptionError(
625 option, section, rest, var)
626 if "%" in v:
627 self._interpolate_some(option, accum, v,
628 section, map, depth + 1)
629 else:
630 accum.append(v)
631 else:
632 raise InterpolationSyntaxError(
633 option, section,
634 "'%%' must be followed by '%%' or '(', found: %r" % (rest,))
635
636 def set(self, section, option, value):
637 """Set an option. Extend ConfigParser.set: check for string values."""
638 if not isinstance(value, basestring):
639 raise TypeError("option values must be strings")
640 ConfigParser.set(self, section, option, value)