Changeset 1453

Show
Ignore:
Timestamp:
06/06/08 10:46:11 (7 months ago)
Author:
astormont
Message:

RegParser? with full read/write support

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • sandbox/astormont/RegParser.py

    r1452 r1453  
    11# astormont: I've subclassed the python ConfigParser and tweaked it to read .reg files 
    22 
    3 import ConfigParser 
     3import re 
     4from ConfigParser import ConfigParser, ParsingError, DEFAULTSECT 
    45 
    5 DEFAULTSECT = "DEFAULT" 
     6( REG_PLAIN, REG_STR, REG_HEX, REG_WORD, REG_DWORD ) = range( 5 ) 
    67 
    7 class RegParser( ConfigParser.ConfigParser ): 
     8class RegParser( ConfigParser ): 
     9 
     10    header = "REGEDIT 4" 
     11 
     12    # Fixed regex for .regs. Handles quotes better than the default class, too.  
     13    OPTCRE = re.compile( r'"?(?P<option>[^:=\s][^="]*)"?\s*(?P<vi>[:=])\s*"?(?P<value>.*)"?$' ) 
     14 
     15    # Disable case-insensitivty 
     16    def optionxform(self, optionstr): 
     17        return optionstr 
     18 
     19    def type( self, val ): 
     20        if val.startswith( "str(" ): 
     21            return REG_STR 
     22        elif val.startswith( "hex:" ): 
     23            return REG_HEX 
     24        elif val.startswith( "word:" ): 
     25            return REG_WORD 
     26        elif val.startswith( "dword:" ): 
     27            return REG_DWORD 
     28        else: 
     29            return REG_PLAIN 
    830 
    931    def _read(self, fp, fpname): 
    1032        """Parse a sectioned setup file. 
    11  
    1233        The sections in setup file contains a title line at the top, 
    1334        indicated by a name in square brackets (`[]'), plus key/value 
     
    1738        and just about everything else are ignored. 
    1839        """ 
    19         cursect = None                            # None, or a dictionary 
     40        cursect = None # None, or a dictionary 
    2041        optname = None 
    2142        lineno = 0 
    22         e = None                                  # None, or an exception 
     43        e = None       # None, or an exception 
    2344        while True: 
    2445            line = fp.readline() 
     
    2748            lineno = lineno + 1 
    2849            # skip first line (contains file header like: REGEDIT 4, or WINE REGISTRY 2) 
    29             if lineno == 1: 
     50            if lineno == 1 and not line.startswith(";") and not line.startswith("["): 
     51                self.header = line 
    3052                continue 
    3153            # comment or blank line? 
     
    5779                # no section header in the file? 
    5880                elif cursect is None: 
    59                     raise MissingSectionHeaderError(fpname, lineno, line) 
     81                    continue 
    6082                # an option line? 
    6183                else: 
     
    6385                    if mo: 
    6486                        optname, vi, optval = mo.group('option', 'vi', 'value') 
    65                         # Strip the quotes off the name & val 
    66                         optname = optname[1:-1] 
    67                         optval = optval[1:-1] 
    6887                        if vi in ('=', ':') and ';' in optval: 
    6988                            # ';' is a comment delimiter only if it follows 
     
    7392                                optval = optval[:pos] 
    7493                        optval = optval.strip() 
    75                         # allow empty values 
    76                         if optval == '""': 
    77                             optval = '' 
    78                         optname = self.optionxform(optname.rstrip()) 
     94                        # Strip the quotes off the name & val, fix @ 
     95                        #if optname == "@": 
     96                        #    optname = "" 
     97                        #elif optname.startswith("\"") and optname.endswith("\""): 
     98                        #    optname = optname[1:-1] 
     99                        #if optval.startswith("\"") and optval.endswith("\""): 
     100                        #    optval = optval[1:-1] 
    79101                        cursect[optname] = optval 
    80102                    else: 
     
    90112            raise e 
    91113 
     114    def write(self, fp): 
     115        """Write an .reg-format representation of the configuration state.""" 
     116        # Put back header 
     117        fp.write( self.header + "\n" ) 
     118        if self._defaults: 
     119            fp.write("[%s]\n" % DEFAULTSECT) 
     120            for (key, value) in self._defaults.items(): 
     121                if key == "": 
     122                    key = "@" 
     123                else: 
     124                    key = "\"%s\"" % key 
     125                if self.type( value ) == REG_PLAIN: 
     126                    value = "\"%s\"" % value 
     127                fp.write("%s=%s\n" % (key, str(value).replace('\n', '\n\t'))) 
     128            fp.write("\n") 
     129        for section in self._sections: 
     130            fp.write("[%s]\n" % section) 
     131            for (key, value) in self._sections[section].items(): 
     132                if key != "__name__": 
     133                    if key == "": 
     134                        key = "@" 
     135                    else: 
     136                        key = "\"%s\"" % key 
     137                    if self.type( value ) == REG_PLAIN: 
     138                        value = "\"%s\"" % value 
     139                    fp.write("%s=%s\n" % (key, str(value).replace('\n', '\n\t'))) 
     140            fp.write("\n")