private LNode ApplyMacrosFound(CurNodeState s) { var foundMacros = s.FoundMacros; // if any of the macros use a priority flag, group by priority. if (foundMacros.Count > 1) { var p = foundMacros[0].Mode & MacroMode.PriorityMask; for (int x = 1; x < foundMacros.Count; x++) { if ((foundMacros[x].Mode & MacroMode.PriorityMask) != p) { // need to make an independent list because _s.foundMacros may be cleared and re-used for descendant nodes foundMacros = new List <MacroInfo>(foundMacros); foundMacros.Sort(); for (int i = 0, j; i < foundMacros.Count; i = j) { p = foundMacros[i].Mode & MacroMode.PriorityMask; for (j = i + 1; j < foundMacros.Count; j++) { if ((foundMacros[j].Mode & MacroMode.PriorityMask) != p) { break; } } var newNode = ApplyMacrosFound2(s, foundMacros.Slice(i, j - i)); if (newNode != null) { return(newNode); } } return(null); } } } return(ApplyMacrosFound2(s, foundMacros.Slice(0))); }
private LNode ApplyMacrosFound3(CurNodeState s, ListSlice <MacroInfo> foundMacros) { LNode input = s.Input; Debug.Assert(s.Results.IsEmpty && s.MessageHolder.List.Count == 0); IList <MessageHolder.Message> messageList = s.MessageHolder.List; int accepted = 0, acceptedIndex = -1; for (int i = 0; i < foundMacros.Count; i++) { var macro = foundMacros[i]; var macroInput = input; if ((macro.Mode & MacroMode.ProcessChildrenBefore) != 0) { macroInput = ProcessChildrenOfCurrentNode(); } LNode output = null; s.DropRemainingNodes = (macro.Mode & MacroMode.DropRemainingListItems) != 0; int mhi = messageList.Count; try { Scope scope = AutoInitScope(); MacrosInvoked++; output = macro.Macro(macroInput, scope); if (output != null) { accepted++; acceptedIndex = i; } } catch (ThreadAbortException e) { _sink.Write(Severity.Error, input, "Macro-processing thread aborted in {0}", QualifiedName(macro.Macro.Method)); _sink.Write(Severity.Detail, input, e.StackTrace); s.Results.Add(new MacroResult(macro, output, messageList.Slice(mhi, messageList.Count - mhi), s.DropRemainingNodes)); PrintMessages(s.Results, input, accepted, Severity.Error); throw; } catch (Exception e) { s.MessageHolder.Write(Severity.Error, input, "{0}: {1}", e.GetType().Name, e.Message); s.MessageHolder.Write(Severity.Detail, input, e.StackTrace); } s.Results.Add(new MacroResult(macro, output, messageList.Slice(mhi, messageList.Count - mhi), s.DropRemainingNodes)); } s.DropRemainingNodes = false; PrintMessages(s.Results, input, accepted, s.MessageHolder.List.MaxOrDefault(msg => (int)msg.Severity).Severity); if (accepted >= 1) { var result = s.Results[acceptedIndex]; NodesReplaced++; Debug.Assert(result.NewNode != null); if ((result.Macro.Mode & MacroMode.ProcessChildrenBefore) != 0) { s.MaxExpansions--; } LNode result2; if ((result.Macro.Mode & MacroMode.Normal) != 0) { if (result.NewNode == input) { result2 = ApplyMacrosToChildrenOf(result.NewNode, s.MaxExpansions - 1); } else { result2 = ApplyMacros(result.NewNode, s.MaxExpansions - 1, s.IsTarget); if (result2 != null) { result.DropRemainingNodes |= _s.DropRemainingNodes; } } } else if ((result.Macro.Mode & MacroMode.ProcessChildrenAfter) != 0) { result2 = ApplyMacrosToChildrenOf(result.NewNode, s.MaxExpansions - 1); } else { return(result.NewNode); } s.DropRemainingNodes = result.DropRemainingNodes; return(result2 ?? result.NewNode); } else { return(s.Preprocessed ?? ApplyMacrosToChildrenOf(input, s.MaxExpansions)); } }
LNode Process(ref RVList <LNode> list, LNode single, bool asRoot, bool resetOpenNamespaces, bool areAttributesOrIsTarget) { if (single == null && list.Count == 0) { return(null); // no-op requested } var oldS = _s; var oldAncestors = _ancestorStack; var oldMP = MacroProcessor._current; MacroProcessor._current = _parent; bool newScope = false; try { bool reentrant = _reentrancyCounter++ != 0; if (!reentrant) { asRoot = true; } Debug.Assert(reentrant || _scopes.Count == 0); Debug.Assert(reentrant || _ancestorStack == null); if (asRoot) { _ancestorStack = new DList <LNode>(); } _s = new CurNodeState(); if (asRoot || resetOpenNamespaces) { var namespaces = !reentrant || resetOpenNamespaces?_parent.PreOpenedNamespaces.Clone() : _curScope.OpenNamespaces.Clone(); var properties = asRoot ? new MMap <object, object>() : _curScope.ScopedProperties; newScope = true; _curScope = new Scope(namespaces, properties, this, true); _scopes.Add(_curScope); } int maxExpansions = asRoot ? MaxExpansions : _s.MaxExpansions - 1; if (single != null) { return(ApplyMacros(single, maxExpansions, areAttributesOrIsTarget)); } else { int oldStackCount = _ancestorStack.Count; LNode splice = null; if (asRoot) { splice = list.AsLNode(S.Splice); _ancestorStack.PushLast(splice); } list = ApplyMacrosToList(list, maxExpansions, areAttributesOrIsTarget); _ancestorStack.PopLast(); Debug.Assert(_ancestorStack.Count == oldStackCount); return(splice); } } finally { _reentrancyCounter--; MacroProcessor._current = oldMP; _ancestorStack = oldAncestors; _s = oldS; if (newScope) { PopScope(); } } }
private MacroResult?ApplyMacrosFound2(CurNodeState s, ListSlice <MacroInfo> foundMacros) { s.BeforeApplyMacros(); LNode input = s.Input; Debug.Assert(s.Results.IsEmpty && s.MessageHolder.List.Count == 0); IList <LogMessage> messageList = s.MessageHolder.List; int accepted = 0, acceptedIndex = -1; for (int i = 0; i < foundMacros.Count; i++) { var macro = foundMacros[i]; var macroInput = input; if ((macro.Mode & MacroMode.ProcessChildrenBefore) != 0) { macroInput = ProcessChildrenOfCurrentNode(); } LNode output = null; s.DropRemainingNodesRequested = (macro.Mode & MacroMode.DropRemainingListItems) != 0; int mhi = messageList.Count; try { Scope scope = AutoInitScope(); MacrosInvoked++; // CALL THE MACRO! output = macro.Macro(macroInput, scope); if (output != null) { accepted++; acceptedIndex = i; } } catch (ThreadAbortException e) { _sink.Write(Severity.Error, input, "Macro-processing thread aborted in {0}", QualifiedName(macro.Macro.Method)); _sink.Write(Severity.Detail, input, e.StackTrace); s.Results.Add(new MacroResult(macro, output, messageList.Slice(mhi, messageList.Count - mhi), s.DropRemainingNodesRequested)); PrintMessages(s.Results, input, accepted, Severity.Error); throw; } catch (LogException e) { e.Msg.WriteTo(s.MessageHolder); } catch (Exception e) { s.MessageHolder.Write(Severity.Error, input, "{0}: {1}", e.GetType().Name, e.Message); s.MessageHolder.Write(Severity.Detail, input, e.StackTrace); } s.Results.Add(new MacroResult(macro, output, messageList.Slice(mhi, messageList.Count - mhi), s.DropRemainingNodesRequested)); } s.DropRemainingNodesRequested = false; PrintMessages(s.Results, input, accepted, s.MessageHolder.List.MaxOrDefault(msg => (int)msg.Severity).Severity); if (accepted >= 1) { var result = s.Results[acceptedIndex]; return(result); } else { return(null); } }