|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2007 - 2009 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 # This is a script to patch pyxml to correct a bug. |
|
6 |
|
7 """ |
|
8 Script to patch pyXML to correct a bug. |
|
9 """ |
|
10 |
|
11 import sys |
|
12 import os |
|
13 import shutil |
|
14 import py_compile |
|
15 import distutils.sysconfig |
|
16 |
|
17 # Define the globals. |
|
18 progName = None |
|
19 pyxmlModDir = None |
|
20 |
|
21 def usage(rcode = 2): |
|
22 """ |
|
23 Display a usage message and exit. |
|
24 |
|
25 rcode is the return code passed back to the calling process. |
|
26 """ |
|
27 global progName, pyxmlModDir |
|
28 |
|
29 print "Usage:" |
|
30 print " %s [-h] [-d dir]" % (progName) |
|
31 print "where:" |
|
32 print " -h display this help message" |
|
33 print " -d dir where pyXML is installed [default %s]" % \ |
|
34 (pyxmlModDir) |
|
35 print |
|
36 print "This script patches the file _xmlplus/parsers/xmlproc/xmlutils.py" |
|
37 print "of the pyXML distribution to fix a bug causing it to fail" |
|
38 print "for XML files containing non ASCII characters." |
|
39 print |
|
40 |
|
41 sys.exit(rcode) |
|
42 |
|
43 |
|
44 def initGlobals(): |
|
45 """ |
|
46 Sets the values of globals that need more than a simple assignment. |
|
47 """ |
|
48 global pyxmlModDir |
|
49 |
|
50 pyxmlModDir = os.path.join(distutils.sysconfig.get_python_lib(True), "_xmlplus") |
|
51 |
|
52 def isPatched(): |
|
53 """ |
|
54 Function to check, if pyXML is already patched. |
|
55 |
|
56 @return flag indicating patch status (boolean) |
|
57 """ |
|
58 global pyxmlModDir |
|
59 |
|
60 initGlobals() |
|
61 |
|
62 try: |
|
63 filename = \ |
|
64 os.path.join(pyxmlModDir, "parsers", "xmlproc", "xmlutils.py") |
|
65 f = open(filename, "r") |
|
66 except EnvironmentError: |
|
67 print "Could not find the pyXML distribution. Please use the patch_pyxml.py" |
|
68 print "script to apply a patch needed to fix a bug causing it to fail for" |
|
69 print "XML files containing non ASCII characters." |
|
70 return True # fake a found patch |
|
71 |
|
72 lines = f.readlines() |
|
73 f.close() |
|
74 |
|
75 patchPositionFound = False |
|
76 |
|
77 for line in lines: |
|
78 if patchPositionFound and \ |
|
79 (line.startswith(\ |
|
80 " # patched by eric4 install script.") or \ |
|
81 line.startswith(\ |
|
82 " self.datasize = len(self.data)")): |
|
83 return True |
|
84 if line.startswith(\ |
|
85 " self.data = self.charset_converter(self.data)"): |
|
86 patchPositionFound = True |
|
87 continue |
|
88 |
|
89 return False |
|
90 |
|
91 def patchPyXML(): |
|
92 """ |
|
93 The patch function. |
|
94 """ |
|
95 global pyxmlModDir |
|
96 |
|
97 initGlobals() |
|
98 |
|
99 try: |
|
100 filename = \ |
|
101 os.path.join(pyxmlModDir, "parsers", "xmlproc", "xmlutils.py") |
|
102 f = open(filename, "r") |
|
103 except EnvironmentError: |
|
104 print "The file %s does not exist. Aborting." % filename |
|
105 sys.exit(1) |
|
106 |
|
107 lines = f.readlines() |
|
108 f.close() |
|
109 |
|
110 patchPositionFound = False |
|
111 patched = False |
|
112 |
|
113 sn = "xmlutils.py" |
|
114 s = open(sn, "w") |
|
115 for line in lines: |
|
116 if patchPositionFound: |
|
117 if not line.startswith(\ |
|
118 " # patched by eric4 install script.") and \ |
|
119 not line.startswith(\ |
|
120 " self.datasize = len(self.data)"): |
|
121 s.write(" # patched by eric4 install script.\n") |
|
122 s.write(" self.datasize = len(self.data)\n") |
|
123 patched = True |
|
124 patchPositionFound = False |
|
125 s.write(line) |
|
126 if line.startswith(\ |
|
127 " self.data = self.charset_converter(self.data)"): |
|
128 patchPositionFound = True |
|
129 continue |
|
130 s.close() |
|
131 |
|
132 if not patched: |
|
133 print "xmlutils.py is already patched." |
|
134 os.remove(sn) |
|
135 else: |
|
136 try: |
|
137 py_compile.compile(sn) |
|
138 except py_compile.PyCompileError, e: |
|
139 print "Error compiling %s. Aborting" % sn |
|
140 print e |
|
141 os.remove(sn) |
|
142 sys.exit(1) |
|
143 except SyntaxError, e: |
|
144 print "Error compiling %s. Aborting" % sn |
|
145 print e |
|
146 os.remove(sn) |
|
147 sys.exit(1) |
|
148 |
|
149 shutil.copy(filename, "%s.orig" % filename) |
|
150 shutil.copy(sn, filename) |
|
151 os.remove(sn) |
|
152 if os.path.exists("%sc" % sn): |
|
153 shutil.copy("%sc" % sn, "%sc" % filename) |
|
154 os.remove("%sc" % sn) |
|
155 if os.path.exists("%so" % sn): |
|
156 shutil.copy("%so" % sn, "%so" % filename) |
|
157 os.remove("%so" % sn) |
|
158 |
|
159 print "xmlutils.py patched successfully." |
|
160 print "Unpatched file copied to %s.orig." % filename |
|
161 |
|
162 def main(argv): |
|
163 """ |
|
164 The main function of the script. |
|
165 |
|
166 argv is the list of command line arguments. |
|
167 """ |
|
168 import getopt |
|
169 |
|
170 # Parse the command line. |
|
171 global progName, pyxmlModDir |
|
172 progName = os.path.basename(argv[0]) |
|
173 |
|
174 initGlobals() |
|
175 |
|
176 try: |
|
177 optlist, args = getopt.getopt(argv[1:],"hd:") |
|
178 except getopt.GetoptError: |
|
179 usage() |
|
180 |
|
181 for opt, arg in optlist: |
|
182 if opt == "-h": |
|
183 usage(0) |
|
184 elif opt == "-d": |
|
185 global pyxmlModDir |
|
186 pyxmlModDir = arg |
|
187 |
|
188 patchPyXML() |
|
189 |
|
190 if __name__ == "__main__": |
|
191 main() |