From d11d3efe3e16b77d08f89635f533b6d35dc1127e Mon Sep 17 00:00:00 2001
From: Lauri Himanen <lauri.himanen@aalto.fi>
Date: Thu, 25 Aug 2016 23:31:31 +0300
Subject: [PATCH] Added some convenience functions to
 CachingBackend/CachingSectionManager, added new 'endAction' argument for
 SimpleMatchers.

---
 common/python/nomadcore/baseclasses.py     |  2 +-
 common/python/nomadcore/caching_backend.py | 14 ++++++++++++++
 common/python/nomadcore/simple_parser.py   | 13 +++++++++++--
 3 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/common/python/nomadcore/baseclasses.py b/common/python/nomadcore/baseclasses.py
index 2459e81..8702fe0 100644
--- a/common/python/nomadcore/baseclasses.py
+++ b/common/python/nomadcore/baseclasses.py
@@ -272,7 +272,7 @@ class RegexService(object):
     Stores basic regex definitions that can be reused on multiple parsers.
     """
     def __init__(self):
-        self.float = "-?\d+\.\d+(?:E(?:\+|-)\d+)?"  # Regex for a floating point value
+        self.float = "-?\d+\.\d+(?:[ED](?:\+|-)\d+)?"  # Regex for a floating point value
         self.int = "-?\d+"  # Regex for an integer
         self.word = "[\S]+"  # Regex for a single word. Can contain anything else but whitespace
         self.letter = "[^\W\d_]"  # Regex for a single alphabetical letter
diff --git a/common/python/nomadcore/caching_backend.py b/common/python/nomadcore/caching_backend.py
index 78eeb87..2e4019a 100644
--- a/common/python/nomadcore/caching_backend.py
+++ b/common/python/nomadcore/caching_backend.py
@@ -178,6 +178,12 @@ class CachingSectionManager(object):
     def setSectionInfo(self, gIndex, references):
         self.openSections[gIndex].references = [reference[x] for x in self.parentSectionNames]
 
+    def get_latest_section(self):
+        """Returns the latest opened section if it is still open.
+        """
+        section = self.openSections.get(self.lastSectionGIndex)
+        return section
+
     def openSection(self, backend):
         newGIndex = self.lastSectionGIndex + 1
         self.openSectionWithGIndex(backend, newGIndex)
@@ -317,6 +323,14 @@ class ActiveBackend(object):
     def appendOnClose(self, sectionName, onClose):
         self.sectionManagers.onClose.append(onClose)
 
+    def get_latest_section(self, metaname):
+        """Returns the latest opened section with the given metaname if it has
+        not been closed.
+        """
+        manager = self.sectionManagers.get(metaname)
+        if manager:
+            return manager.get_latest_section()
+
     def appendOnOpen(self, sectionName, onOpen):
         self.sectionManagers.onOpen.append(onOpen)
 
diff --git a/common/python/nomadcore/simple_parser.py b/common/python/nomadcore/simple_parser.py
index 3d77c67..81ff106 100644
--- a/common/python/nomadcore/simple_parser.py
+++ b/common/python/nomadcore/simple_parser.py
@@ -74,6 +74,7 @@ class SimpleMatcher(object):
                  defLine=0,
                  defFile='',
                  coverageIgnore=False, # mark line as ignored in coverage analysis
+                 endAction = None,
                  ):
         self.index = -1
         self.startReStr = startReStr
@@ -118,6 +119,7 @@ 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):
@@ -679,10 +681,12 @@ class CompiledMatcher(object):
             parser.skipped += 1
 
     def findNextMatch(self, parser):
+        nextI = None
         if self.matcher.adHoc:
             nextI = self.matcher.adHoc(parser)
-            if nextI is not None:
-                return nextI
+
+        if nextI is not None:
+            return nextI
         return self.findNextWithRe(self.possibleNextsRe, self.possibleNexts, parser)
 
     def findNextMatchEnd(self, parser):
@@ -1088,6 +1092,11 @@ class SimpleParser(object):
         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())):
                 self.backend.closeSection(s, gIndex)
-- 
GitLab