From dccab3232f3a9264fe4b4bca63552267e6c6bf23 Mon Sep 17 00:00:00 2001
From: Lauri Himanen <lauri.himanen@aalto.fi>
Date: Fri, 26 Aug 2016 22:44:33 +0300
Subject: [PATCH] Added possibility for SimpleMatcher specific onClose and
 onOpen callbacks.

---
 common/python/nomadcore/simple_parser.py | 34 +++++++++++++++++++++---
 1 file changed, 30 insertions(+), 4 deletions(-)

diff --git a/common/python/nomadcore/simple_parser.py b/common/python/nomadcore/simple_parser.py
index 6883b79..445649a 100644
--- a/common/python/nomadcore/simple_parser.py
+++ b/common/python/nomadcore/simple_parser.py
@@ -74,7 +74,9 @@ class SimpleMatcher(object):
                  defLine=0,
                  defFile='',
                  coverageIgnore=False, # mark line as ignored in coverage analysis
-                 endAction = None,
+                 endAction = None, # A function that is called when this SimpleMatcher finishes
+                 onClose = None,   # A dictionary of onClose callbacks that are specific to this SimpleMatcher
+                 onOpen = None,   # A dictionary of onClose callbacks that are specific to this SimpleMatcher
                  ):
         self.index = -1
         self.startReStr = startReStr
@@ -94,6 +96,9 @@ class SimpleMatcher(object):
         self.name = name
         self.fixedStartValues = fixedStartValues
         self.fixedEndValues = fixedEndValues
+        self.endAction = endAction
+        self.onClose = onClose
+        self.onOpen = onOpen
         self.keep = False   # Boolean flag used by the ParserOptimizer to determine which SimpleMatchers to keep
         # boolean flag to signal that this SimpleMatcher does not have any
         # effect (besides progressing input file):
@@ -119,7 +124,6 @@ class SimpleMatcher(object):
                 "and is marked as coverageIgnore", name)
 
         self.coverageIgnore = coverageIgnore
-        self.endAction = endAction
         caller=inspect.currentframe()
         if (defFile == '') and (defLine == 0):
             if (caller is not None) and (caller.f_back is not None):
@@ -1089,18 +1093,40 @@ class SimpleParser(object):
         compiledMatcher = self.parserBuilder.compiledMatchers[stateIndex]
         sects = OrderedDict()
         for s in compiledMatcher.matcher.sections:
-            sects[s] = self.backend.openSection(s)
+            gIndex = self.backend.openSection(s)
+            sects[s] = gIndex
+
+            # Call the matcher specific onOpen callbacks
+            if compiledMatcher.matcher.onOpen:
+                callback = compiledMatcher.matcher.onOpen.get(s)
+                if callback:
+                    section_manager = self.backend.sectionManagers[s]
+                    section = section_manager.openSections[gIndex]
+                    callback(self.backend, gIndex, section)
+
         self.context.append(ParsingContext(stateIndex, sects, compiledMatcher, ParsingContext.Start))
 
     def contextClose(self, cNow):
+
         # Handle end action before closing sections
         # Call the end action
         if cNow.compiledMatcher.matcher.endAction:
             cNow.compiledMatcher.matcher.endAction()
 
         if cNow.startEnd == ParsingContext.Start:
-            for s,gIndex in reversed(list(cNow.sections.items())):
+            for s, gIndex in reversed(list(cNow.sections.items())):
+
+                # Call the matcher specific onClose callbacks
+                if cNow.compiledMatcher.matcher.onClose:
+                    callback = cNow.compiledMatcher.matcher.onClose.get(s)
+                    if callback:
+                        section_manager = self.backend.sectionManagers[s]
+                        section = section_manager.openSections[gIndex]
+                        callback(self.backend, gIndex, section)
+
+                # Call the global onClose callbacks
                 self.backend.closeSection(s, gIndex)
+
             cNow.startEnd = ParsingContext.End
             return True
         else:
-- 
GitLab