From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from pigeon.gentoo.org ([208.92.234.80] helo=lists.gentoo.org) by finch.gentoo.org with esmtp (Exim 4.60) (envelope-from ) id 1SbZRH-0000O4-8i for garchives@archives.gentoo.org; Mon, 04 Jun 2012 15:43:27 +0000 Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id DC02EE04EB; Mon, 4 Jun 2012 15:43:17 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) by pigeon.gentoo.org (Postfix) with ESMTP id 96290E04EB for ; Mon, 4 Jun 2012 15:43:17 +0000 (UTC) Received: from hornbill.gentoo.org (hornbill.gentoo.org [94.100.119.163]) (using TLSv1 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id B90041B4003 for ; Mon, 4 Jun 2012 15:43:16 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by hornbill.gentoo.org (Postfix) with ESMTP id 82049E5404 for ; Mon, 4 Jun 2012 15:43:15 +0000 (UTC) From: "André Erdmann" To: gentoo-commits@lists.gentoo.org Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "André Erdmann" Message-ID: <1338824570.346f15b80151811fb0813d5f14195ae8d73b4d61.dywi@gentoo> Subject: [gentoo-commits] proj/R_overlay:master commit in: roverlay/ X-VCS-Repository: proj/R_overlay X-VCS-Files: roverlay/config.py X-VCS-Directories: roverlay/ X-VCS-Committer: dywi X-VCS-Committer-Name: André Erdmann X-VCS-Revision: 346f15b80151811fb0813d5f14195ae8d73b4d61 X-VCS-Branch: master Date: Mon, 4 Jun 2012 15:43:15 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: quoted-printable X-Archives-Salt: 6b47c744-994b-4943-b2d4-b12efc718744 X-Archives-Hash: fe9f7fc2e4521f30eb7ba97c1d963b8d commit: 346f15b80151811fb0813d5f14195ae8d73b4d61 Author: Andr=C3=A9 Erdmann mailerd de> AuthorDate: Mon Jun 4 15:42:50 2012 +0000 Commit: Andr=C3=A9 Erdmann mailerd de> CommitDate: Mon Jun 4 15:42:50 2012 +0000 URL: http://git.overlays.gentoo.org/gitweb/?p=3Dproj/R_overlay.git= ;a=3Dcommit;h=3D346f15b8 roverlay, config: fix typo and add main config reader modified: config.py --- roverlay/config.py | 172 ++++++++++++++++++++++++++++++++++++++++++++++= ++---- 1 files changed, 159 insertions(+), 13 deletions(-) diff --git a/roverlay/config.py b/roverlay/config.py index 41a98bf..bce721c 100644 --- a/roverlay/config.py +++ b/roverlay/config.py @@ -2,9 +2,11 @@ # Copyright 2006-2012 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 =20 +import copy +import os +import re import sys import shlex -import copy =20 try: import configparser @@ -13,8 +15,6 @@ except ImportError as running_python2: import ConfigParser as configparser =20 =20 - - from roverlay import descriptionfields from roverlay import const =20 @@ -51,8 +51,8 @@ class InitialLogger: known from the logging module and its output goes directly to sys.stde= rr. This can be used until the real logging has been configured. """ - self.debug =3D lambda x : sys.stderr.write ( "DBG " + str ( x ) += "\n" ) - self.info =3D lambda x : sys.stderr.write ( "INFO " + str ( x ) += "\n" ) + self.debug =3D lambda x : sys.stdout.write ( "DBG " + str ( x ) += "\n" ) + self.info =3D lambda x : sys.stdout.write ( "INFO " + str ( x ) += "\n" ) self.warning =3D lambda x : sys.stderr.write ( "WARN " + str ( x ) += "\n" ) self.error =3D lambda x : sys.stderr.write ( "ERR " + str ( x ) += "\n" ) self.critical =3D lambda x : sys.stderr.write ( "CRIT " + str ( x ) += "\n" ) @@ -64,6 +64,25 @@ class ConfigTree: # static access to the first created ConfigTree instance =3D None =20 + # the list of 'normal' config entries (no special config path) (in lowe= rcase) + # the map of config entries + CONFIG_ENTRY_MAP =3D dict ( + log_level =3D '', + log_console =3D dict ( + value_type =3D 'yesno', + ), + log_file =3D dict ( + value_type =3D 'fs_file', + ), + ebuild_header =3D dict ( + value_type =3D 'fs_file', + ) + + ) + + DEFAULT_LIST_REGEX =3D re.compile ( '\s*[,;]{1}\s*' ) + WHITESPACE =3D re.compile ( '\s+' ) + def __init__ ( self, import_const=3DTrue ): """Initializes an ConfigTree, which is a container for options/config = values. values can be stored directly (such as the field_definitions) or in a @@ -89,19 +108,18 @@ class ConfigTree: # --- end of __init__ (...) --- =20 =20 - def _findpath ( self, path, root=3DNone, create=3DFalse ): + def _findpath ( self, path, root=3DNone, create=3DFalse, value=3DNone )= : if path is None: return root elif isinstance ( path, str ): - path =3D path.split ( '.' ) if key else [] + path =3D path.split ( '.' ) if path else [] =20 config_position =3D self._config if root is None else root =20 for k in path: if not k in config_position: if create: - config_position [k] =3D dict () - + config_position [k] =3D value if k =3D=3D path [-1] and value else = dict () else: return None =20 @@ -134,22 +152,130 @@ class ConfigTree: =20 # --- end of get (...) --- =20 + def _add_entry ( self, option, value=3DNone, config_root=3DNone ): + + def make_and_verify_value ( value_type, value, entryconfig_ref ): + + def to_int ( val, fallback_value=3D-1 ): + try: + ret =3D int ( val ) + return ret + except ValueError as verr: + return fallback_value + # --- end of to_int (...) --- + + def yesno ( val ): + if not val is None: + to_check =3D str ( val ) . lower () + if to_check in [ 'y', 'yes', '1', 'true', 'enabled', 'on' ]: + return 1 + elif to_check in [ 'n', 'no', '0', 'false', 'disabled', 'off' ]: + return 0 + + self.logger.warning ( to_check + " is not a valid yesno value." ) + return -1 + # --- end of yesno (...) --- + + value =3D ConfigTree.WHITESPACE.sub ( ' ', value ) + + if not value_type: + return value + elif isinstance ( value_type, list ): + vtypes =3D value_type + elif isinstance ( value_type, str ): + vtypes =3D value_type.split ( ':' ) + else: + self.logger.error ( "Unknown data type for value type." ) + return value + + retval =3D value + is_list =3D False + for vtype in vtypes: + if vtype =3D=3D 'list': + retval =3D ConfigTree.DEFAULT_LIST_REGEX.split ( retval ) + is_list =3D True + elif vtype =3D=3D 'slist': + retval =3D ConfigTree.WHITESPACE.split ( retval ) + is_list =3D True + elif vtype =3D=3D 'yesno': + retval =3D [ yesno ( x ) for x in retval ] if is_list else yesno (= retval ) + elif vtype =3D=3D 'int': + retval =3D [ to_int ( x ) for x in retval ] if is_list else to_int = ( retval ) + + else: + self.logger.warning ( "unknown value type '" + vtype + "'." ) + + return retval + # --- end of make_and_verify_value (...) --- + + + real_option =3D option + low_option =3D option.lower() + if option and low_option in ConfigTree.CONFIG_ENTRY_MAP: + cref =3D ConfigTree.CONFIG_ENTRY_MAP [low_option] + + if isinstance ( cref, str ) and cref in ConfigTree.CONFIG_ENTRY_MAP: + option =3D low_option =3D cref + cref =3D ConfigTree.CONFIG_ENTRY_MAP [cref] + + if cref is None: + # deftly ignored + return True + + + + path =3D None + if 'path' in cref: + path =3D cref ['path'] + else: + path =3D low_option.split ( '_' ) + for n in range ( len ( path ) - 1 ): + path [n] =3D path [n].upper() + + + if path: + + if 'value_type' in cref: + value =3D make_and_verify_value ( cref ['value_type'], value, cref = ) + + if value: + + self.logger.debug ( + "New config entry " + str ( option ) + + " with path " + str ( path ) + + " and value " + str ( value ) + "." + ) + + self._findpath ( path, config_root, True, value ) + + return True + else: + self.logger.error ( + "Option '" + str ( real_option ) + + "' has an unusable value '" + str ( value ) + "'." + ) + # --- + # --- + + self.logger.warning ( "Option '" + str ( real_option ) + "' is unknown= ." ) + return False + + # --- end of _add_entry (...) --- + def load_config ( self, config_file, start_section=3D'' ): """Loads a config file and integrates its content into the config tree= . Older config entries may be overwritten. =20 arguments: config_file -- path to the file that should be read - start_section -- relative root in the config tree as str or ref + start_section -- relative root in the config tree as str """ =20 config_root =3D None if start_section: if isinstance ( start_section, str ): config_root =3D self._findpath ( start_section, None, True ) - elif isinstance ( start_section, dict ): - config_root =3D start_section - else + else: raise Exception ("bad usage") =20 # load file @@ -157,6 +283,26 @@ class ConfigTree: try: fh =3D open ( config_file, 'r' ) reader =3D shlex.shlex ( fh ) + reader.whitespace_split =3D False + reader.wordchars +=3D ' ./$()[]:+-@*~' + + nextline =3D lambda : ( reader.get_token() for n in range (3) ) + + option, equal, value =3D nextline () + + while equal =3D=3D '=3D' or not ( option =3D=3D value =3D=3D reader.e= of ): + if equal =3D=3D '=3D': + self._add_entry ( option, value, config_root ) + else: + self.logger.warning ( + "In '" + config_file + "', cannot parse this line: '" + + str ( option ) + str ( equal ) + str ( value ) + "'." + ) + + option, equal, value =3D nextline () + + + if fh: fh.close () =20