Give a more informative exception on SubRip parse failures.
authorCarl Hetherington <cth@carlh.net>
Tue, 20 Sep 2016 20:07:57 +0000 (21:07 +0100)
committerCarl Hetherington <cth@carlh.net>
Tue, 20 Sep 2016 20:07:57 +0000 (21:07 +0100)
src/exceptions.cc
src/exceptions.h
src/subrip_reader.cc
src/subrip_reader.h
src/wscript
test/subrip_reader_test.cc

index 4d9d29f027b1775c6fc7f0f0bb282b9cbe7a5332..d59d32ac5dda10a74f74ded5b8f021604c7a8634 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2014-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
 
 #include "compose.hpp"
 #include "exceptions.h"
+#include <boost/foreach.hpp>
 
 using std::string;
+using std::list;
 using namespace sub;
 
 ProgrammingError::ProgrammingError (string file, int line)
@@ -28,3 +30,10 @@ ProgrammingError::ProgrammingError (string file, int line)
 {
 
 }
+
+SubripError::SubripError (string saw, string expecting, list<string> context)
+       : runtime_error ("Error in SubRip file: saw " + (saw.empty() ? "an empty string" : saw) + " when expecting " + expecting)
+       , _context (context)
+{
+
+}
index c6f7f1a668d3af6a76c1b39003713c33a86cd262..c7a3c71ac7091de2ea8f6b7be7bfc917a6399380 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2014-2016 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -22,6 +22,7 @@
 
 #include <stdexcept>
 #include <string>
+#include <list>
 
 namespace sub {
 
@@ -53,9 +54,14 @@ public:
 class SubripError : public std::runtime_error
 {
 public:
-       SubripError (std::string saw, std::string expecting)
-               : std::runtime_error ("Error in SubRip file: saw " + saw + " while expecting " + expecting)
-       {}
+       SubripError (std::string saw, std::string expecting, std::list<std::string> context);
+
+       std::list<std::string> context () const {
+               return _context;
+       }
+
+private:
+       std::list<std::string> _context;
 };
 
 class MXFError : public std::runtime_error
index 94a48c09bf4d06741c6cbf931f585537babb8ba4..6fab0ffcbdcfed813a7207dbbcda35d513daa115 100644 (file)
@@ -83,6 +83,12 @@ SubripReader::read (function<optional<string> ()> get_line)
                trim_right_if (*line, boost::is_any_of ("\n\r"));
                remove_unicode_bom (line);
 
+               /* Keep some history in case there is an error to report */
+               _context.push_back (*line);
+               if (_context.size() > 5) {
+                       _context.pop_front ();
+               }
+
                switch (state) {
                case COUNTER:
                {
@@ -109,7 +115,13 @@ SubripReader::read (function<optional<string> ()> get_line)
 
                        boost::algorithm::split (p, *line, boost::algorithm::is_any_of (" "));
                        if (p.size() != 3 && p.size() != 7) {
-                               throw SubripError (*line, "a time/position line");
+                               for (int i = 0; i < 2; ++i) {
+                                       optional<string> ex = get_line ();
+                                       if (ex) {
+                                               _context.push_back (*ex);
+                                       }
+                               }
+                               throw SubripError (*line, "a time/position line", _context);
                        }
 
                        rs.from = convert_time (p[0]);
@@ -138,7 +150,7 @@ SubripReader::convert_time (string t)
        vector<string> a;
        boost::algorithm::split (a, t, boost::is_any_of (":"));
        if (a.size() != 3) {
-               throw SubripError (t, "time in the format h:m:s,ms");
+               throw SubripError (t, "time in the format h:m:s,ms", _context);
        }
 
        vector<string> b;
index 5f5f343f48ca7e56f46d7571785ae8d014a6a4e9..138d703c148b16dfec8d5f9fab9a760d14861504 100644 (file)
@@ -44,10 +44,12 @@ private:
        friend struct ::subrip_reader_convert_time_test;
        SubripReader () {}
 
-       static Time convert_time (std::string t);
+       Time convert_time (std::string t);
        void convert_line (std::string t, RawSubtitle& p);
        void maybe_content (RawSubtitle& p);
        void read (boost::function<boost::optional<std::string> ()> get_line);
+
+       std::list<std::string> _context;
 };
 
 }
index 9136ea1324149c46f886d577ddecb63718ed2463..a22c7123d19b86c340a46108c61b363d7d7f3a81 100644 (file)
@@ -49,6 +49,7 @@ def build(bld):
               colour.h
               dcp_reader.h
               effect.h
+              exceptions.h
               font_size.h
               interop_dcp_reader.h
               rational.h
index c06cf256aaa92d43fe4dd059c96f1f2cb38deb10..58cf46ba40f596e4921dd8edda5096e3406b37d4 100644 (file)
@@ -353,8 +353,9 @@ BOOST_AUTO_TEST_CASE (subrip_reader_convert_line_test)
 /** Test SubripReader::convert_time */
 BOOST_AUTO_TEST_CASE (subrip_reader_convert_time_test)
 {
-       BOOST_CHECK_EQUAL (sub::SubripReader::convert_time ("00:03:10,500"), sub::Time::from_hms (0, 3, 10, 500));
-       BOOST_CHECK_EQUAL (sub::SubripReader::convert_time ("04:19:51,782"), sub::Time::from_hms (4, 19, 51, 782));
+       sub::SubripReader reader;
+       BOOST_CHECK_EQUAL (reader.convert_time ("00:03:10,500"), sub::Time::from_hms (0, 3, 10, 500));
+       BOOST_CHECK_EQUAL (reader.convert_time ("04:19:51,782"), sub::Time::from_hms (4, 19, 51, 782));
 }
 
 static void