]> git.tdb.fi Git - libs/datafile.git/commitdiff
Add a prepare() hook to Loader
authorMikko Rasa <tdb@tdb.fi>
Tue, 9 Jul 2024 13:29:16 +0000 (16:29 +0300)
committerMikko Rasa <tdb@tdb.fi>
Tue, 9 Jul 2024 13:29:16 +0000 (16:29 +0300)
Also add an overload of finish() which is called even when an exception
occurs and receives a bool parameter to indicate if loading was
successful.

source/loader.cpp
source/loader.h

index b09fa87a1d10f87e373cbf7a5dc8a213583ef6d1..5b39569cc77a10007ba251183a72a40a53f569f8 100644 (file)
@@ -1,3 +1,4 @@
+#include <exception>
 #include <msp/core/algorithm.h>
 #include <msp/core/raii.h>
 #include <msp/fs/utils.h>
@@ -56,6 +57,7 @@ void Loader::load(Parser &p)
 
        context = FS::basename(p.get_source());
 
+       Activator activate(*this);
        while(p)
        {
                if(p.peek(0))
@@ -68,9 +70,6 @@ void Loader::load(Parser &p)
                                load_statement(st);
                }
        }
-       finish();
-       for(Loader *l: aux_loaders)
-               l->finish();
 }
 
 void Loader::load(const Statement &st)
@@ -78,11 +77,9 @@ void Loader::load(const Statement &st)
        if(!actions)
                throw logic_error("no actions");
 
+       Activator activate(*this);
        for(const Statement &s: st.sub)
                load_statement(s);
-       finish();
-       for(Loader *l: aux_loaders)
-               l->finish();
 }
 
 void Loader::load_direct(Parser &p, unsigned l)
@@ -146,10 +143,8 @@ void Loader::load_sub_with(Loader &ldr)
 {
        if(direct)
        {
+               Activator activate(ldr);
                ldr.load_direct(*cur_parser, cur_level+1);
-               ldr.finish();
-               for(Loader *l: ldr.aux_loaders)
-                       l->finish();
        }
        else if(cur_st)
        {
@@ -258,5 +253,23 @@ const string &Loader::get_keyword() const
        return cur_st->keyword;
 }
 
+
+Loader::Activator::Activator(Loader &l):
+       ldr(l),
+       exc_count(uncaught_exceptions())
+{
+       ldr.prepare();
+       for(Loader *a: ldr.aux_loaders)
+               a->prepare();
+}
+
+Loader::Activator::~Activator()
+{
+       bool success = (uncaught_exceptions()==exc_count);
+       ldr.finish(success);
+       for(Loader *a: ldr.aux_loaders)
+               a->finish(success);
+}
+
 } // namespace DataFile
 } // namespace Msp
index abad2f1c4b1cffe023b60aaab06674ce41725e1b..c759f597535962bfb99fc6c3cf702b241d7b9695 100644 (file)
@@ -76,6 +76,15 @@ protected:
        };
 
 private:
+       struct Activator
+       {
+               Loader &ldr;
+               int exc_count = 0;
+
+               Activator(Loader &);
+               ~Activator();
+       };
+
        ActionMap local_actions;
        ActionMap *actions = nullptr;
        std::string context;
@@ -202,7 +211,9 @@ protected:
        implement dynamic keywords. */
        const std::string &get_keyword() const;
 
+       virtual void prepare() { }
        virtual void finish() { }
+       virtual void finish(bool s) { if(s) finish(); }
 };