Lines Matching +full:child +full:- +full:node
1 //===-- WindowsManifestMerger.cpp ------------------------------*- C++ -*-===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===---------------------------------------------------------------------===//
11 //===---------------------------------------------------------------------===//
60 {"urn:schemas-microsoft-com:asm.v1", "ms_asmv1"},
61 {"urn:schemas-microsoft-com:asm.v2", "ms_asmv2"},
62 {"urn:schemas-microsoft-com:asm.v3", "ms_asmv3"},
65 {"urn:schemas-microsoft-com:compatibility.v1", "ms_compatibilityv1"}};
88 for (xmlNodePtr Child = Parent->children; Child; Child = Child->next) {
89 if (xmlStringsEqual(Child->name, ElementName)) {
90 return Child;
96 static xmlAttrPtr getAttribute(xmlNodePtr Node,
98 for (xmlAttrPtr Attribute = Node->properties; Attribute != nullptr;
99 Attribute = Attribute->next) {
100 if (xmlStringsEqual(Attribute->name, AttributeName)) {
121 // Search for prefix-defined namespace specified by HRef, starting on Node and
124 static xmlNsPtr search(const unsigned char *HRef, xmlNodePtr Node) {
125 for (xmlNsPtr Def = Node->nsDef; Def; Def = Def->next) {
126 if (Def->prefix && xmlStringsEqual(Def->href, HRef)) {
130 if (Node->parent) {
131 return search(HRef, Node->parent);
147 // Search for prefix-defined namespace specified by HRef, starting on Node and
149 // not found, then prefix-define that namespace on the node and return a
152 xmlNodePtr Node) {
153 if (xmlNsPtr Def = search(HRef, Node))
155 if (xmlNsPtr Def = xmlNewNs(Node, HRef, getPrefixForHref(HRef)))
167 searchOrDefine(AdditionalAttribute->ns->href, OriginalNode);
170 OriginalAttribute->ns = std::move(ExplicitOrError.get());
175 // given Node. Returns nullptr if there is no such definition.
177 xmlNodePtr Node) {
178 if (Node == nullptr)
180 for (xmlNsPtr Def = Node->nsDef; Def; Def = Def->next) {
181 if (xmlStringsEqual(Def->prefix, Prefix)) {
189 // including) the Node and traveling upwards through parent nodes. Returns
191 static xmlNsPtr getClosestDefault(xmlNodePtr Node) {
192 if (xmlNsPtr Ret = getNamespaceWithPrefix(nullptr, Node))
194 if (Node->parent == nullptr)
196 return getClosestDefault(Node->parent);
208 for (xmlAttrPtr Attribute = AdditionalNode->properties; Attribute;
209 Attribute = Attribute->next) {
211 getAttribute(OriginalNode, Attribute->name)) {
212 if (!xmlStringsEqual(OriginalAttribute->children->content,
213 Attribute->children->content)) {
216 FROM_XML_CHAR(OriginalNode->name));
218 if (!Attribute->ns) {
221 if (!OriginalAttribute->ns) {
228 if (namespaceOverrides(OriginalAttribute->ns->href,
229 Attribute->ns->href)) {
234 if (!OriginalAttribute->ns->prefix && !Attribute->ns->prefix &&
236 xmlStringsEqual(Attribute->ns->href, ClosestDefault->href)) {
249 if (Attribute->ns->prefix || OriginalAttribute->ns->prefix ||
250 (ClosestDefault && !xmlStringsEqual(OriginalAttribute->ns->href,
251 ClosestDefault->href))) {
260 // If the incoming attribute is not already found on the node, append it
265 xmlNewProp(OriginalNode, Attribute->name, Attribute->children->content);
267 searchOrDefine(Attribute->ns->href, OriginalNode);
270 NewProp->ns = std::move(ExplicitOrError.get());
278 if (!Node1 || !Node1->ns)
280 if (!Node2 || !Node2->ns)
282 if (namespaceOverrides(Node1->ns->href, Node2->ns->href))
287 // Checks if this Node's namespace is inherited or one it defined itself.
288 static bool hasInheritedNs(xmlNodePtr Node) {
289 return Node->ns && Node->ns != getNamespaceWithPrefix(Node->ns->prefix, Node);
292 // Check if this Node's namespace is a default namespace that it inherited, as
294 static bool hasInheritedDefaultNs(xmlNodePtr Node) {
295 return hasInheritedNs(Node) && Node->ns->prefix == nullptr;
298 // Check if this Node's namespace is a default namespace it defined itself.
299 static bool hasDefinedDefaultNamespace(xmlNodePtr Node) {
300 return Node->ns && (Node->ns == getNamespaceWithPrefix(nullptr, Node));
303 // For the given explicit prefix-definition of a namespace, travel downwards
304 // from a node recursively, and for every implicit, inherited default usage of
308 static void explicateNamespace(xmlNsPtr PrefixDef, xmlNodePtr Node) {
309 // If a node as its own default namespace definition it clearly cannot have
312 if (hasDefinedDefaultNamespace(Node))
314 if (Node->ns && xmlStringsEqual(Node->ns->href, PrefixDef->href) &&
315 hasInheritedDefaultNs(Node))
316 Node->ns = PrefixDef;
317 for (xmlAttrPtr Attribute = Node->properties; Attribute;
318 Attribute = Attribute->next) {
319 if (Attribute->ns &&
320 xmlStringsEqual(Attribute->ns->href, PrefixDef->href)) {
321 Attribute->ns = PrefixDef;
324 for (xmlNodePtr Child = Node->children; Child; Child = Child->next) {
325 explicateNamespace(PrefixDef, Child);
332 // Save the original default namespace definition in case the incoming node
337 OriginalDefinedDefaultHref = xmlStrdup(OriginalDefinedDefaultNs->href);
341 // definition per node, so the higher priority one takes precedence in the
343 for (xmlNsPtr Def = AdditionalNode->nsDef; Def; Def = Def->next) {
345 getNamespaceWithPrefix(Def->prefix, OriginalNode)) {
346 if (!Def->prefix) {
347 if (namespaceOverrides(Def->href, OriginalNsDef->href)) {
348 NewDefinedDefaultHref = TO_XML_CHAR(strdup(FROM_XML_CHAR(Def->href)));
350 } else if (!xmlStringsEqual(OriginalNsDef->href, Def->href)) {
353 FROM_XML_CHAR(Def->prefix));
357 NewDef->next = OriginalNode->nsDef;
358 OriginalNode->nsDef = NewDef;
362 // Check whether the original node or the incoming node has the higher
365 // node.
374 // the lower priority node ended up having a higher priority default
375 // definition. This can occur if the higher priority node is prefix
380 namespaceOverrides(NonDominantDefinedDefault->href,
390 // In this case the node with a higher priority namespace did not have a
391 // default namespace definition, but the lower priority node did. In this
398 if (DominantNode->parent) {
399 xmlNsPtr ClosestDefault = getClosestDefault(DominantNode->parent);
401 searchOrDefine(ClosestDefault->href, DominantNode);
410 // Covers case where the incoming node has a default namespace definition
411 // that overrides the original node's namespace. This always leads to
412 // the original node receiving that new default namespace.
414 NonDominantNode->ns = getNamespaceWithPrefix(nullptr, NonDominantNode);
416 // This covers the case where the incoming node either has a prefix
421 searchOrDefine(DominantNode->ns->href, NonDominantNode);
426 NonDominantNode->ns = Explicit;
428 // This covers cases where the incoming dominant node HAS a default
433 if (namespaceOverrides(DominantDefaultDefined->href,
435 // In this case, the incoming node's default definition overrides
453 searchOrDefine(ClosestDefault->href, NonDominantNode);
464 xmlFree(const_cast<unsigned char *>(OriginalNsDef->href));
465 OriginalNsDef->href = NewDefinedDefaultHref;
480 static bool hasRecognizedNamespace(xmlNodePtr Node) {
481 return isRecognizedNamespace(Node->ns->href);
484 // Ensure a node's inherited namespace is actually defined in the tree it
486 static Error reconcileNamespaces(xmlNodePtr Node) {
487 if (!Node) {
490 if (hasInheritedNs(Node)) {
491 Expected<xmlNsPtr> ExplicitOrError = searchOrDefine(Node->ns->href, Node);
496 Node->ns = Explicit;
498 for (xmlNodePtr Child = Node->children; Child; Child = Child->next) {
499 if (auto E = reconcileNamespaces(Child)) {
514 xmlNodePtr AdditionalFirstChild = AdditionalRoot->children;
516 for (xmlNodePtr Child = AdditionalFirstChild; Child; Child = Child->next) {
518 if (!isMergeableElement(Child->name) ||
520 getChildWithName(OriginalRoot, Child->name)) ||
521 !hasRecognizedNamespace(Child)) {
522 StoreNext.next = Child->next;
523 xmlUnlinkNode(Child);
524 if (!xmlAddChild(OriginalRoot, Child)) {
526 FROM_XML_CHAR(Child->name));
528 if (auto E = reconcileNamespaces(Child)) {
531 Child = &StoreNext;
532 } else if (auto E = treeMerge(OriginalChildWithName, Child)) {
541 for (xmlNodePtr Child = Root->children; Child; Child = Child->next) {
542 if (!xmlStringsEqual(Child->name, TO_XML_CHAR("comment"))) {
543 stripComments(Child);
546 StoreNext.next = Child->next;
547 xmlNodePtr Remove = Child;
548 Child = &StoreNext;
557 static void setAttributeNamespaces(xmlNodePtr Node) {
558 for (xmlAttrPtr Attribute = Node->properties; Attribute;
559 Attribute = Attribute->next) {
560 if (!Attribute->ns) {
561 Attribute->ns = getClosestDefault(Node);
564 for (xmlNodePtr Child = Node->children; Child; Child = Child->next) {
565 setAttributeNamespaces(Child);
571 static void checkAndStripPrefixes(xmlNodePtr Node,
573 for (xmlNodePtr Child = Node->children; Child; Child = Child->next) {
574 checkAndStripPrefixes(Child, RequiredPrefixes);
576 if (Node->ns && Node->ns->prefix != nullptr) {
577 xmlNsPtr ClosestDefault = getClosestDefault(Node);
579 xmlStringsEqual(ClosestDefault->href, Node->ns->href)) {
580 Node->ns = ClosestDefault;
581 } else if (!llvm::is_contained(RequiredPrefixes, Node->ns)) {
582 RequiredPrefixes.push_back(Node->ns);
585 for (xmlAttrPtr Attribute = Node->properties; Attribute;
586 Attribute = Attribute->next) {
587 if (Attribute->ns && Attribute->ns->prefix != nullptr) {
588 xmlNsPtr ClosestDefault = getClosestDefault(Node);
590 xmlStringsEqual(ClosestDefault->href, Attribute->ns->href)) {
591 Attribute->ns = ClosestDefault;
592 } else if (!llvm::is_contained(RequiredPrefixes, Node->ns)) {
593 RequiredPrefixes.push_back(Attribute->ns);
599 for (xmlNsPtr Def = Node->nsDef; Def; Def = Def->next) {
600 if (!Def->prefix || llvm::is_contained(RequiredPrefixes, Def)) {
604 if (Def == Node->nsDef) {
605 Node->nsDef = Def->next;
607 Prev->next = Def->next;
609 Temp.next = Def->next;
643 if (!xmlStringsEqual(CombinedRoot->name, AdditionalRoot->name) ||
644 !isMergeableElement(AdditionalRoot->name) ||
673 xmlDocDumpFormatMemoryEnc(OutputDoc.get(), &Buff, &BufferSize, "UTF-8", 1);
709 return Impl->merge(Manifest);
713 return Impl->getMergedManifest();
719 Merger->ParseErrorOccurred = true;