dump: remove dependency on Boost.Regex

Use std::regex instead.

Change-Id: Icb0f88a3f01d16ca53089cdc764d529687eaca81
diff --git a/tools/dump/main.cpp b/tools/dump/main.cpp
index 7e23ef9..351d76f 100644
--- a/tools/dump/main.cpp
+++ b/tools/dump/main.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017,  Regents of the University of California.
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California.
  *
  * This file is part of ndn-tools (Named Data Networking Essential Tools).
  * See AUTHORS.md for complete list of ndn-tools authors and contributors.
@@ -16,7 +16,7 @@
  * You should have received a copy of the GNU General Public License along with
  * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  */
-/**
+/*
  * Copyright (c) 2011-2014, Regents of the University of California,
  *
  * This file is part of ndndump, the packet capture and analysis tool for Named Data
@@ -43,26 +43,12 @@
 
 #include <sstream>
 
-namespace po = boost::program_options;
-
-namespace boost {
-
-void
-validate(boost::any& v,
-         const std::vector<std::string>& values,
-         boost::regex*, int)
-{
-  po::validators::check_first_occurrence(v);
-  const std::string& str = po::validators::get_single_string(values);
-  v = boost::any(boost::regex(str));
-}
-
-} // namespace boost
-
 namespace ndn {
 namespace dump {
 
-void
+namespace po = boost::program_options;
+
+static void
 usage(std::ostream& os, const std::string& appName, const po::options_description& options)
 {
   os << "Usage:\n"
@@ -74,25 +60,25 @@
   os << options;
 }
 
-int
+static int
 main(int argc, char* argv[])
 {
   Ndndump instance;
+  std::string filter;
 
   po::options_description visibleOptions;
   visibleOptions.add_options()
     ("help,h", "Produce this help message")
-    ("version,V", "display version and exit")
+    ("version,V", "Display version and exit")
     ("interface,i", po::value<std::string>(&instance.interface),
-     "Interface from which to dump packets")
+                    "Interface from which to dump packets")
     ("read,r", po::value<std::string>(&instance.inputFile),
-     "Read  packets  from file")
-    ("verbose,v",
-     "When  parsing  and  printing, produce verbose output")
+               "Read packets from file")
+    ("verbose,v", "When parsing and printing, produce verbose output")
     // ("write,w", po::value<std::string>(&instance.outputFile),
     //  "Write the raw packets to file rather than parsing and printing them out")
-    ("filter,f", po::value<boost::regex>(&instance.nameFilter),
-     "Regular expression to filter out Interest and Data packets")
+    ("filter,f", po::value<std::string>(&filter),
+                 "Regular expression to filter out Interest and Data packets")
     ;
 
   po::options_description hiddenOptions;
@@ -136,6 +122,16 @@
     instance.isVerbose = true;
   }
 
+  if (vm.count("filter") > 0) {
+    try {
+      instance.nameFilter = std::regex(filter);
+    }
+    catch (const std::regex_error& e) {
+      std::cerr << "ERROR: Invalid filter expression: " << e.what() << std::endl;
+      return 2;
+    }
+  }
+
   if (vm.count("pcap-program") > 0) {
     const auto& items = vm["pcap-program"].as<std::vector<std::string>>();
 
@@ -145,7 +141,7 @@
   }
 
   if (vm.count("read") > 0 && vm.count("interface") > 0) {
-    std::cerr << "ERROR: Conflicting -r and -i options\n";
+    std::cerr << "ERROR: Conflicting -r and -i options\n\n";
     usage(std::cerr, argv[0], visibleOptions);
     return 2;
   }
@@ -154,7 +150,7 @@
     instance.run();
   }
   catch (const std::exception& e) {
-    std::cerr << "ERROR: " << e.what() << "\n\n";
+    std::cerr << "ERROR: " << e.what() << "\n";
   }
 
   return 0;
diff --git a/tools/dump/ndndump.cpp b/tools/dump/ndndump.cpp
index 1fec4f1..9e0d5d4 100644
--- a/tools/dump/ndndump.cpp
+++ b/tools/dump/ndndump.cpp
@@ -95,22 +95,18 @@
     else {
       std::cerr << "ndndump: reading from " << inputFile << std::endl;
     }
-
-    if (!nameFilter.empty()) {
-      std::cerr << "ndndump: using name filter " << nameFilter << std::endl;
-    }
   }
 
   if (!interface.empty()) {
     char errbuf[PCAP_ERRBUF_SIZE];
-    m_pcap = pcap_open_live(interface.c_str(), MAX_SNAPLEN, 0, 1000, errbuf);
+    m_pcap = pcap_open_live(interface.data(), MAX_SNAPLEN, 0, 1000, errbuf);
     if (m_pcap == nullptr) {
       BOOST_THROW_EXCEPTION(Error("Cannot open interface " + interface + " (" + errbuf + ")"));
     }
   }
   else {
     char errbuf[PCAP_ERRBUF_SIZE];
-    m_pcap = pcap_open_offline(inputFile.c_str(), errbuf);
+    m_pcap = pcap_open_offline(inputFile.data(), errbuf);
     if (m_pcap == nullptr) {
       BOOST_THROW_EXCEPTION(Error("Cannot open file " + inputFile + " for reading (" + errbuf + ")"));
     }
@@ -122,7 +118,7 @@
     }
 
     bpf_program program;
-    int res = pcap_compile(m_pcap, &program, pcapProgram.c_str(), 0, PCAP_NETMASK_UNKNOWN);
+    int res = pcap_compile(m_pcap, &program, pcapProgram.data(), 0, PCAP_NETMASK_UNKNOWN);
 
     if (res < 0) {
       BOOST_THROW_EXCEPTION(Error("Cannot parse tcpdump expression '" + pcapProgram +
@@ -145,7 +141,6 @@
   pcap_loop(m_pcap, -1, &Ndndump::onCapturedPacket, reinterpret_cast<uint8_t*>(this));
 }
 
-
 void
 Ndndump::onCapturedPacket(const pcap_pkthdr* header, const uint8_t* packet) const
 {
@@ -408,12 +403,11 @@
 bool
 Ndndump::matchesFilter(const Name& name) const
 {
-  if (nameFilter.empty())
+  if (!nameFilter)
     return true;
 
   /// \todo Switch to NDN regular expressions
-
-  return boost::regex_match(name.toUri(), nameFilter);
+  return std::regex_match(name.toUri(), *nameFilter);
 }
 
 } // namespace dump
diff --git a/tools/dump/ndndump.hpp b/tools/dump/ndndump.hpp
index 6961a73..bf1ff55 100644
--- a/tools/dump/ndndump.hpp
+++ b/tools/dump/ndndump.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016,  Regents of the University of California.
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California.
  *
  * This file is part of ndn-tools (Named Data Networking Essential Tools).
  * See AUTHORS.md for complete list of ndn-tools authors and contributors.
@@ -16,7 +16,7 @@
  * You should have received a copy of the GNU General Public License along with
  * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  */
-/**
+/*
  * Copyright (c) 2011-2014, Regents of the University of California,
  *
  * This file is part of ndndump, the packet capture and analysis tool for Named Data
@@ -40,9 +40,8 @@
 #include "core/common.hpp"
 
 #include <pcap.h>
-
+#include <regex>
 #include <ndn-cxx/name.hpp>
-#include <boost/regex.hpp>
 
 namespace ndn {
 namespace dump {
@@ -100,7 +99,7 @@
 
   std::string pcapProgram;
   std::string interface;
-  boost::regex nameFilter;
+  optional<std::regex> nameFilter;
   std::string inputFile;
   // std::string outputFile;
 
@@ -111,7 +110,6 @@
   int m_dataLinkType;
 };
 
-
 } // namespace dump
 } // namespace ndn