~allsymes/vineyard/fixes

« back to all changes in this revision

Viewing changes to python-wine/wine/parsers.py

  • Committer: Christian Dannie Storgaard
  • Date: 2010-02-17 22:04:59 UTC
  • Revision ID: cybolic@gmail.com-20100217220459-tg3owv2zl8wx5g9o
Rewrote registry file parser, doesn't fall over any more and is faster. Fixed various bugs in vineyard-preferences. Completed the functionality for adding unlisted programs. Added the files for exe-helper (probably doesn't work right now, doesn't detect paths right).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
# -*- coding: utf-8 -*-
 
3
#
 
4
# Copyright (c) 2007-2008 Christian Dannie Storgaard
 
5
#
 
6
# AUTHOR:
 
7
# Christian Dannie Storgaard <cybolic@gmail.com>
 
8
 
 
9
import os, re
 
10
from collections import defaultdict
 
11
import util
 
12
 
 
13
def parseRegistry(registry, base_path=None):
 
14
    registry = parseInput(registry)
 
15
    registry_dict = multidict()
 
16
    sections = re.findall(r'(?ms)^\[(?P<path>[^\]]+)\](?:\s\d+)?\s+(?P<section>.*?)(?=^\[)', registry+'\n[')
 
17
    for path, section in sections:
 
18
        values = re.findall(r'(?ms)^(?P<key>\"[^\"]*?\"|@)=(?P<value>.*?)(?=^\")', section+'"')
 
19
        section_dict = multidict()
 
20
        for key, value in values:
 
21
            """ Strip the start and end quotes """
 
22
            if key != '@':
 
23
                key = key[1:-1]
 
24
            value = parseValue(value)
 
25
            if type(value) == tuple:
 
26
                section_dict['_%s' % key] = value[0]
 
27
                section_dict[key] = value[1]
 
28
            else:
 
29
                section_dict[key] = value
 
30
        exec('registry_dict%s = section_dict' % ''.join([ '[\'%s\']' % i.encode('string_escape') for i in filter(len,path.split('\\'))]))
 
31
        #registry_dict = __set_branch_values(path, registry_dict, section_dict)
 
32
        #registry_dict[path] = section_dict
 
33
    if base_path:
 
34
        return {base_path: registry_dict.get_dict()}
 
35
    else:
 
36
        return registry_dict.get_dict()
 
37
 
 
38
def parseValue(value):
 
39
    """ See what type of value this is.
 
40
        For more info, see http://technet.microsoft.com/en-us/library/bb727154.aspx
 
41
    """
 
42
    original_value = None
 
43
    value_is_string = True
 
44
    value_type = value.split(':')[0].lower()
 
45
    if value_type.startswith('hex(2)'):
 
46
        """ Expanded String """
 
47
        try:
 
48
            new_value = util.hextoutf8(value)
 
49
            original_value = value
 
50
            value = new_value
 
51
        except UnicodeDecodeError:
 
52
            value_is_string = False
 
53
            print "Couldn't read registry! This is a serious error, please report this error along with this text at https://bugs.launchpad.net/vineyard"
 
54
            print path, key, value_type, value
 
55
            exit(1)
 
56
    elif value_type.startswith('hex(7)'):
 
57
        """ Multi String """
 
58
        value_is_string = False
 
59
        try:
 
60
            value = filter(len, util.hextoutf8(value).split('\x00'))
 
61
        except TypeError:
 
62
            print "Couldn't read registry! This is a serious error, please report this error along with this text at https://bugs.launchpad.net/vineyard"
 
63
            print path, key, value_type, value
 
64
            exit(1)
 
65
    elif value_type.startswith('hex'):
 
66
        """ HEX Value """
 
67
        value_is_string = False
 
68
        value = '%s:%s' % (value.split(':')[0], re.sub(r'(?i)[^a-z0-9,]','', ''.join(value.split(':')[1:])))
 
69
    elif value_type.startswith('dword'):
 
70
        """ Double Word (displayed as HEX usually) """
 
71
        value_is_string = False
 
72
        value = value.strip()
 
73
    elif value_type.startswith('null'):
 
74
        value_is_string = False
 
75
        value = None
 
76
    elif value_type.startswith('str(2)'):
 
77
        """ Expandable String """
 
78
        value = ':'.join(value.strip().split(':')[1:])
 
79
    elif value_type.startswith('quote') or value.startswith('str'):
 
80
        value = ':'.join(value.strip().split(':')[1:])
 
81
    if value_is_string:
 
82
        if value.strip().startswith('"') and value.replace('\x00','').strip().endswith('"'):
 
83
            value = '"'.join(value.strip().split('"')[1:-1])
 
84
        try:
 
85
            if type(value) == list:
 
86
                value = [ util.stringtoutf8(i) for i in value ]
 
87
            else:
 
88
                value = util.stringtoutf8(value)
 
89
        except UnicodeDecodeError:
 
90
            print "Couldn't read registry! This is a serious error, please report this error along with this text at https://bugs.launchpad.net/vineyard"
 
91
            print path, key, value_type, value.encode('hex')
 
92
            exit(1)
 
93
    if original_value != None:
 
94
        return (original_value, value)
 
95
    else:
 
96
        return value
 
97
 
 
98
def parseInput(input_object):
 
99
    """
 
100
        Takes either a file descriptor object, a file name or the contents of a
 
101
        file as an argument and returns the contents of it.
 
102
    """
 
103
    if type(input_object) == file:
 
104
        output = input_object.read()
 
105
    elif '\n' not in input_object and os.path.isfile(input_object):
 
106
        file_object = open(input_object, 'r')
 
107
        output = file_object.read()
 
108
        file_object.close()
 
109
    else:
 
110
        return input_object
 
111
    return output
 
112
 
 
113
class multidict(defaultdict):
 
114
    def __init__(self):
 
115
        self.default_factory = type(self)
 
116
    def get_dict(self):
 
117
        return self.__convert_to_dict(self)
 
118
    def __convert_to_dict(self, mdict):
 
119
        return_dict = {}
 
120
        for key,value in mdict.iteritems():
 
121
            if type(value) == type(self):
 
122
                return_dict[key] = self.__convert_to_dict(value)
 
123
            else:
 
124
                return_dict[key] = value
 
125
        return return_dict