regex: throw an exception when contructing a regex returns an error
authorArjen Baart <arjen@andromeda.nl>
Sat, 12 Sep 2020 08:22:40 +0000 (10:22 +0200)
committerArjen Baart <arjen@andromeda.nl>
Sat, 12 Sep 2020 08:22:40 +0000 (10:22 +0200)
TODO
src/String.h
src/regex.cpp
test/string_basics.cpp
test/string_regex.cpp
test/string_regex.exp

diff --git a/TODO b/TODO
index 8d34e6e..e3ebf5a 100644 (file)
--- a/TODO
+++ b/TODO
@@ -6,7 +6,6 @@ Things to do:
 - String: format operator % like in python
 - String: assign fstream objects to read and write a file
 - String: convert to and from std::sstream and std::string
-- regex:  throw an exception when contructing a regex returns an error
 
 - date: test parser for invalid dates and syntax errors
 - date: Parser for stream input
index 2aac0d0..bd8a354 100644 (file)
@@ -392,23 +392,6 @@ public:
    friend bool operator == (const regex &r, const String &s);
 };
 
-class StringException
-{
-   String message;
-
-public:
-
-   StringException(String m)
-   {
-      message = m;
-   }
-
-   String what()
-   {
-      return message;
-   }
-};
-
 class SuperString
 {
    std::vector<String> _ss;
@@ -488,4 +471,48 @@ public:
    String join(const String &separator);
 };
 
+/*
+ *  Exception classes
+ */
+
+
+class StringException
+{
+   String message;
+
+public:
+
+   StringException(String m)
+   {
+      message = m;
+   }
+
+   String what()
+   {
+      return message;
+   }
+};
+
+#define ERROR_MSG_SIZE 200
+
+class RegexException
+{
+   String message;
+
+public:
+
+   RegexException(int errcode, regex_t *preg)
+   {
+      char errbuf[ERROR_MSG_SIZE];
+
+      regerror(errcode, preg, errbuf, ERROR_MSG_SIZE);
+      message = errbuf;
+   }
+
+   String what()
+   {
+      return message;
+   }
+};
+
 #endif  /* STRING_H */
index ae4de84..3f7a675 100644 (file)
@@ -39,6 +39,7 @@
 #include <ctype.h>
 #include "String.h"
 
+
  //  Constructors and destructors for the regex class
 
 regex::regex(const String &reg)
@@ -46,7 +47,10 @@ regex::regex(const String &reg)
    original = reg;
    int error = regcomp (&expression, reg.p->s, REG_EXTENDED);
 
-   //TODO: Handle error
+   if (error != 0)
+   {
+      throw RegexException(error, &expression);
+   }
 }
 
 regex::regex(const char *reg)
@@ -54,7 +58,10 @@ regex::regex(const char *reg)
    original = reg;
    int error = regcomp (&expression, reg, REG_EXTENDED);
 
-   //TODO: Handle error
+   if (error != 0)
+   {
+      throw RegexException(error, &expression);
+   }
 }
 
 regex::regex(const regex & reg)
@@ -62,7 +69,10 @@ regex::regex(const regex & reg)
    original = reg.original;
    int error = regcomp (&expression, reg.original, REG_EXTENDED);
 
-   //TODO: Handle error
+   if (error != 0)
+   {
+      throw RegexException(error, &expression);
+   }
 }
 
 regex::~regex()
@@ -75,6 +85,10 @@ regex& regex::operator=(const regex& x)
    original = x.original;
    int error = regcomp (&expression, x.original, REG_EXTENDED);
 
+   if (error != 0)
+   {
+      throw RegexException(error, &expression);
+   }
    return *this;
 }
 
index 6b75ad6..0458cd2 100644 (file)
@@ -72,6 +72,8 @@ int main()
    assert(c == 'd');
 
    // Out of bounds
+   bool exception_caught = false;
+
    try
    {
       c = s1[7];
@@ -80,13 +82,15 @@ int main()
    catch (StringException se)
    {
       std::cout << "String exception: " << se.what() << "\n";
+      exception_caught = true;
    }
-   //assert(c == 'a');
+   assert(exception_caught);
 
    s1[2] = 'Z';
    std::cout << "After \"abcde\"[2] = 'Z' : " << s1 << "\n";
    assert(s1 == "abZde");
 
+   exception_caught = false;
    try
    {
       s1[5] = 'X';
@@ -94,9 +98,11 @@ int main()
    catch (StringException se)
    {
       std::cout << "String exception: " << se.what() << "\n";
+      exception_caught = true;
    }
    std::cout << "After \"abcde\"[5] = 'X' : " << s1 << "\n";
    assert(s1 == "abZde");
+   assert(exception_caught);
 
    return 0;
 }
index 86ba26d..4723ad1 100644 (file)
@@ -11,7 +11,7 @@
 
 int main()
 {
-   // TODO: test regex coinstructors
+   // TODO: test regex constructors
 
    // A simple regular expression
    regex nr("[0-9]+");
@@ -32,6 +32,23 @@ int main()
    std::cout << "The matching part of \"" << s2 << "\" is \"" << match << "\"\n";
    assert(match == "123");
 
+   // Test a regex with an error
+
+   bool exception_caught = false;
+
+   try
+   {
+      regex wrong_nr("[0-9+");
+      std::cout << "No regex error detected.\n";
+   }
+   catch (RegexException rexc)
+   {
+      std::cout << "Regex exception: " << rexc.what() << "\n";
+      exception_caught = true;
+   }
+
+   assert(exception_caught);
+
    return 0;
 }
 
index 5b5c94b..aa85a41 100644 (file)
@@ -1,3 +1,4 @@
 Regular expression matching.
 The matching part of "abd123def" is "123"
+Regex exception: Unmatched [ or [^
 PASS string_regex (exit status: 0)