Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(291)

Side by Side Diff: visual_studio/NativeClientVSAddIn/InstallerResources/xml_patch.py

Issue 10831030: NaCl settings and completed install scripts. (Closed) Base URL: https://nativeclient-sdk.googlecode.com/svn/trunk/src
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """ This module is a utility for applying an xml patch to an xml file. 6 """ This module is a utility for applying an xml patch to an xml file.
7 7
8 The format of the patch is described in the documentation for 8 The format of the patch is described in the documentation for
9 the patch_xml() function. 9 the patch_xml() function.
10 """ 10 """
11 11
12 import collections 12 import collections
13 import copy 13 import copy
14 import xml.etree.ElementTree as ElementTree 14 import third_party.etree.ElementTree as ElementTree
15 15
16 16
17 def PatchXML(source_xml_tree, patch_xml_tree): 17 def PatchXML(source_xml_tree, patch_xml_tree):
18 """Applies a patch to the source xml and returns a new merged xml tree. 18 """Applies a patch to the source xml and returns a new merged xml tree.
19 19
20 Given a patch xml tree, it applies the patch to the source xml tree 20 Given a patch xml tree, it applies the patch to the source xml tree
21 and returns the resulting modified xml tree. 21 and returns the resulting modified xml tree.
22 22
23 Patching is done by reading the patch_xml_tree for an element and then 23 Patching is done by reading the patch_xml_tree for an element and then
24 finding the in-order matching element in the source_xml_tree. Both elements 24 finding the in-order matching element in the source_xml_tree. Both elements
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 89
90 Raises: 90 Raises:
91 General Exception indicating a merge error has occured. 91 General Exception indicating a merge error has occured.
92 """ 92 """
93 assert ElementMatch(source_elem, patch_elem), 'Mismatched merge' 93 assert ElementMatch(source_elem, patch_elem), 'Mismatched merge'
94 94
95 # Create a new element by copying tags from source. Below we will merge 95 # Create a new element by copying tags from source. Below we will merge
96 # the subelements of source with the patch and put them in new_element. 96 # the subelements of source with the patch and put them in new_element.
97 new_element = ElementTree.Element(source_elem.tag, source_elem.attrib) 97 new_element = ElementTree.Element(source_elem.tag, source_elem.attrib)
98 98
99 patch_children = patch_elem.getchildren() 99 patch_children = list(patch_elem)
100 patch_index = 0 100 patch_index = 0
101 remove_targets = collections.deque() 101 remove_targets = collections.deque()
102 find_target = None 102 find_target = None
103 for source_child in source_elem.getchildren(): 103 for source_child in source_elem:
104 # If we have no current patch operation then read the next patch element. 104 # If we have no current patch operation then read the next patch element.
105 while (len(remove_targets) == 0 and find_target is None and 105 while (len(remove_targets) == 0 and find_target is None and
106 patch_index < len(patch_children)): 106 patch_index < len(patch_children)):
107 107
108 # PatchAdd operation. 108 # PatchAdd operation.
109 if IsPatchAddTag(patch_children[patch_index].tag): 109 if IsPatchAddTag(patch_children[patch_index].tag):
110 for addition in patch_children[patch_index].getchildren(): 110 for addition in patch_children[patch_index]:
111 new_element.append(copy.deepcopy(addition)) 111 new_element.append(copy.deepcopy(addition))
112 112
113 # Start a remove operation by creating a list of elements to skip adding. 113 # Start a remove operation by creating a list of elements to skip adding.
114 elif IsPatchRemoveTag(patch_children[patch_index].tag): 114 elif IsPatchRemoveTag(patch_children[patch_index].tag):
115 remove_targets = collections.deque( 115 remove_targets = collections.deque(
116 patch_children[patch_index].getchildren()) 116 patch_children[patch_index])
117 117
118 # Not an Add or Remove, must be a find target (find operation). 118 # Not an Add or Remove, must be a find target (find operation).
119 else: 119 else:
120 find_target = patch_children[patch_index] 120 find_target = patch_children[patch_index]
121 patch_index += 1 121 patch_index += 1
122 122
123 # A remove operation means skipping adding the element to new_element. 123 # A remove operation means skipping adding the element to new_element.
124 if (len(remove_targets) > 0 and 124 if (len(remove_targets) > 0 and
125 ElementMatch(source_child, remove_targets[0])): 125 ElementMatch(source_child, remove_targets[0])):
126 remove_targets.popleft() 126 remove_targets.popleft()
(...skipping 10 matching lines...) Expand all
137 137
138 # Raise exceptions if find/remove didn't finish before the end of the source. 138 # Raise exceptions if find/remove didn't finish before the end of the source.
139 if find_target is not None: 139 if find_target is not None:
140 raise Exception('Find operation never matched:' + find_target.tag) 140 raise Exception('Find operation never matched:' + find_target.tag)
141 elif len(remove_targets) != 0: 141 elif len(remove_targets) != 0:
142 raise Exception('Remove operation never matched: ' + remove_targets) 142 raise Exception('Remove operation never matched: ' + remove_targets)
143 143
144 # We may have more add operations after source has run empty: 144 # We may have more add operations after source has run empty:
145 while patch_index < len(patch_children): 145 while patch_index < len(patch_children):
146 if IsPatchAddTag(patch_children[patch_index].tag): 146 if IsPatchAddTag(patch_children[patch_index].tag):
147 for addition in patch_children[patch_index].getchildren(): 147 for addition in patch_children[patch_index]:
148 new_element.append(copy.deepcopy(addition)) 148 new_element.append(copy.deepcopy(addition))
149 patch_index += 1 149 patch_index += 1
150 else: 150 else:
151 raise Exception('Non-add operation attempted after source end. ' + 151 raise Exception('Non-add operation attempted after source end. ' +
152 'Tag: %s, Children %s' % 152 'Tag: %s, Children %s' %
153 (patch_children[patch_index].tag, 153 (patch_children[patch_index].tag,
154 patch_children[patch_index].get_children())) 154 list(patch_children[patch_index])))
155 155
156 return new_element 156 return new_element
157 157
158 158
159 def ElementMatch(elem1, elem2): 159 def ElementMatch(elem1, elem2):
160 return elem1.tag == elem2.tag and elem1.attrib == elem2.attrib 160 return elem1.tag == elem2.tag and elem1.attrib == elem2.attrib
161 161
162 162
163 def IsPatchAddTag(tag): 163 def IsPatchAddTag(tag):
164 # We look at the end of the tag because we need to ignore the namespace. 164 # We look at the end of the tag because we need to ignore the namespace.
165 # Because the tag can be a sub-element of arbitrary elements it could inherit 165 # Because the tag can be a sub-element of arbitrary elements it could inherit
166 # any default namespace. 166 # any default namespace.
167 return tag.endswith('PatchAdd') 167 return tag.endswith('PatchAdd')
168 168
169 169
170 def IsPatchRemoveTag(tag): 170 def IsPatchRemoveTag(tag):
171 # We look at the end of the tag because we need to ignore the namespace. 171 # We look at the end of the tag because we need to ignore the namespace.
172 # Because the tag can be a sub-element of arbitrary elements it could inherit 172 # Because the tag can be a sub-element of arbitrary elements it could inherit
173 # any default namespace. 173 # any default namespace.
174 return tag.endswith('PatchRemove') 174 return tag.endswith('PatchRemove')
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698