topology-read: replace regex.h implementation with C++ regex
This commit is contained in:
@@ -13,6 +13,5 @@ build_lib(
|
||||
model/rocketfuel-topology-reader.h
|
||||
model/topology-reader.h
|
||||
LIBRARIES_TO_LINK ${libnetwork}
|
||||
${PCRE_LIBRARIES}
|
||||
TEST_SOURCES test/rocketfuel-topology-reader-test-suite.cc
|
||||
)
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
if(PCRE_FOUND)
|
||||
build_lib_example(
|
||||
NAME topology-example-sim
|
||||
SOURCE_FILES topology-example-sim.cc
|
||||
LIBRARIES_TO_LINK
|
||||
${libtopology-read}
|
||||
${libinternet}
|
||||
${libnix-vector-routing}
|
||||
${libpoint-to-point}
|
||||
${libapplications}
|
||||
)
|
||||
endif()
|
||||
build_lib_example(
|
||||
NAME topology-example-sim
|
||||
SOURCE_FILES topology-example-sim.cc
|
||||
LIBRARIES_TO_LINK
|
||||
${libtopology-read}
|
||||
${libinternet}
|
||||
${libnix-vector-routing}
|
||||
${libpoint-to-point}
|
||||
${libapplications}
|
||||
)
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
#include <fstream>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <regex.h>
|
||||
#include <string>
|
||||
#include <regex>
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/node-container.h"
|
||||
#include "rocketfuel-topology-reader.h"
|
||||
@@ -64,9 +64,6 @@ RocketfuelTopologyReader::~RocketfuelTopologyReader ()
|
||||
/* uid @loc [+] [bb] (num_neigh) [&ext] -> <nuid-1> <nuid-2> ... {-euid} ... =name[!] rn */
|
||||
|
||||
|
||||
/// Maximum nuber of matches in a regex query
|
||||
#define REGMATCH_MAX 16
|
||||
|
||||
/// Start of a line
|
||||
#define START "^"
|
||||
/// End of a line
|
||||
@@ -90,6 +87,16 @@ RocketfuelTopologyReader::~RocketfuelTopologyReader ()
|
||||
#define ROCKETFUEL_WEIGHTS_LINE \
|
||||
START "([^ \t]+)" SPACE "([^ \t]+)" SPACE "([0-9.]+)" MAYSPACE END
|
||||
|
||||
/**
|
||||
* Regex object for RocketFuel topology maps file type
|
||||
*/
|
||||
static const std::regex rocketfuel_maps_regex (ROCKETFUEL_MAPS_LINE, std::regex::extended);
|
||||
|
||||
/**
|
||||
* Regex object for RocketFuel topology weights file type
|
||||
*/
|
||||
static const std::regex rocketfuel_weights_regex (ROCKETFUEL_WEIGHTS_LINE, std::regex::extended);
|
||||
|
||||
/**
|
||||
* \brief Print node info
|
||||
* \param uid node ID
|
||||
@@ -113,13 +120,12 @@ PrintNodeInfo (std::string & uid, std::string & loc, bool dns, bool bb,
|
||||
}
|
||||
|
||||
NodeContainer
|
||||
RocketfuelTopologyReader::GenerateFromMapsFile (int argc, char *argv[])
|
||||
RocketfuelTopologyReader::GenerateFromMapsFile (const std::vector<std::string> &argv)
|
||||
{
|
||||
std::string uid;
|
||||
std::string loc;
|
||||
std::string ptr;
|
||||
std::string name;
|
||||
std::string nuid;
|
||||
bool dns = false;
|
||||
bool bb = false;
|
||||
int num_neigh_s = 0;
|
||||
@@ -131,17 +137,17 @@ RocketfuelTopologyReader::GenerateFromMapsFile (int argc, char *argv[])
|
||||
uid = argv[0];
|
||||
loc = argv[1];
|
||||
|
||||
if (argv[2])
|
||||
if (!argv[2].empty ())
|
||||
{
|
||||
dns = true;
|
||||
}
|
||||
|
||||
if (argv[3])
|
||||
if (!argv[3].empty ())
|
||||
{
|
||||
bb = true;
|
||||
}
|
||||
|
||||
num_neigh_s = ::atoi (argv[4]);
|
||||
num_neigh_s = std::stoi (argv[4]);
|
||||
if (num_neigh_s < 0)
|
||||
{
|
||||
num_neigh = 0;
|
||||
@@ -153,15 +159,18 @@ RocketfuelTopologyReader::GenerateFromMapsFile (int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* neighbors */
|
||||
if (argv[6])
|
||||
if (!argv[6].empty ())
|
||||
{
|
||||
char *nbr;
|
||||
char *stringp = argv[6];
|
||||
while ((nbr = strsep (&stringp, " \t")) != NULL)
|
||||
{
|
||||
nbr[strlen (nbr) - 1] = '\0';
|
||||
neigh_list.push_back (nbr + 1);
|
||||
}
|
||||
// Each line contains a list <.*>[ |\t]<.*>[ |\t]<.*>[ |\t]
|
||||
// First remove < and >
|
||||
std::string temp;
|
||||
std::regex replace_regex ("[<|>]");
|
||||
std::regex_replace (std::back_inserter (temp), argv[6].begin (), argv[6].end (), replace_regex, "");
|
||||
|
||||
// Then split list
|
||||
std::regex split_regex ("[ |\t]");
|
||||
std::sregex_token_iterator first{temp.begin (), temp.end (), split_regex, -1}, last;
|
||||
neigh_list = std::vector<std::string>{first, last};
|
||||
}
|
||||
if (num_neigh != neigh_list.size ())
|
||||
{
|
||||
@@ -169,18 +178,18 @@ RocketfuelTopologyReader::GenerateFromMapsFile (int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* externs */
|
||||
if (argv[7])
|
||||
if (!argv[7].empty ())
|
||||
{
|
||||
// euid = argv[7];
|
||||
}
|
||||
|
||||
/* name */
|
||||
if (argv[8])
|
||||
if (!argv[8].empty ())
|
||||
{
|
||||
name = argv[8];
|
||||
}
|
||||
|
||||
radius = ::atoi (&argv[9][1]);
|
||||
radius = std::atoi (&argv[9][1]);
|
||||
if (radius > 0)
|
||||
{
|
||||
return nodes;
|
||||
@@ -191,7 +200,7 @@ RocketfuelTopologyReader::GenerateFromMapsFile (int argc, char *argv[])
|
||||
// Create node and link
|
||||
if (!uid.empty ())
|
||||
{
|
||||
if (m_nodeMap[uid] == 0)
|
||||
if (m_nodeMap[uid] == nullptr)
|
||||
{
|
||||
Ptr<Node> tmpNode = CreateObject<Node> ();
|
||||
m_nodeMap[uid] = tmpNode;
|
||||
@@ -199,16 +208,14 @@ RocketfuelTopologyReader::GenerateFromMapsFile (int argc, char *argv[])
|
||||
m_nodesNumber++;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < neigh_list.size (); ++i)
|
||||
for (auto & nuid : neigh_list)
|
||||
{
|
||||
nuid = neigh_list[i];
|
||||
|
||||
if (nuid.empty ())
|
||||
{
|
||||
return nodes;
|
||||
}
|
||||
|
||||
if (m_nodeMap[nuid] == 0)
|
||||
if (m_nodeMap[nuid] == nullptr)
|
||||
{
|
||||
Ptr<Node> tmpNode = CreateObject<Node> ();
|
||||
m_nodeMap[nuid] = tmpNode;
|
||||
@@ -228,19 +235,19 @@ RocketfuelTopologyReader::GenerateFromMapsFile (int argc, char *argv[])
|
||||
}
|
||||
|
||||
NodeContainer
|
||||
RocketfuelTopologyReader::GenerateFromWeightsFile (int argc, char *argv[])
|
||||
RocketfuelTopologyReader::GenerateFromWeightsFile (const std::vector<std::string>& argv)
|
||||
{
|
||||
/* uid @loc [+] [bb] (num_neigh) [&ext] -> <nuid-1> <nuid-2> ... {-euid} ... =name[!] rn */
|
||||
std::string sname;
|
||||
std::string tname;
|
||||
char *endptr;
|
||||
std::string::size_type endptr;
|
||||
NodeContainer nodes;
|
||||
|
||||
sname = argv[0];
|
||||
tname = argv[1];
|
||||
[[maybe_unused]] double v = strtod (argv[2], &endptr); // weight
|
||||
double v [[maybe_unused]] = std::stod (argv[2], &endptr); // weight
|
||||
|
||||
if (*endptr != '\0')
|
||||
if (argv[2].size () != endptr)
|
||||
{
|
||||
NS_LOG_WARN ("invalid weight: " << argv[2]);
|
||||
return nodes;
|
||||
@@ -249,7 +256,7 @@ RocketfuelTopologyReader::GenerateFromWeightsFile (int argc, char *argv[])
|
||||
// Create node and link
|
||||
if (!sname.empty () && !tname.empty ())
|
||||
{
|
||||
if (m_nodeMap[sname] == 0)
|
||||
if (m_nodeMap[sname] == nullptr)
|
||||
{
|
||||
Ptr<Node> tmpNode = CreateObject<Node> ();
|
||||
m_nodeMap[sname] = tmpNode;
|
||||
@@ -257,7 +264,7 @@ RocketfuelTopologyReader::GenerateFromWeightsFile (int argc, char *argv[])
|
||||
m_nodesNumber++;
|
||||
}
|
||||
|
||||
if (m_nodeMap[tname] == 0)
|
||||
if (m_nodeMap[tname] == nullptr)
|
||||
{
|
||||
Ptr<Node> tmpNode = CreateObject<Node> ();
|
||||
m_nodeMap[tname] = tmpNode;
|
||||
@@ -291,42 +298,24 @@ RocketfuelTopologyReader::GenerateFromWeightsFile (int argc, char *argv[])
|
||||
}
|
||||
|
||||
enum RocketfuelTopologyReader::RF_FileType
|
||||
RocketfuelTopologyReader::GetFileType (const char *line)
|
||||
RocketfuelTopologyReader::GetFileType (const std::string& line)
|
||||
{
|
||||
int ret;
|
||||
regmatch_t regmatch[REGMATCH_MAX];
|
||||
regex_t regex;
|
||||
char errbuf[512];
|
||||
|
||||
// Check whether MAPS file or not
|
||||
ret = regcomp (®ex, ROCKETFUEL_MAPS_LINE, REG_EXTENDED | REG_NEWLINE);
|
||||
if (ret != 0)
|
||||
// Check whether Maps file or not
|
||||
std::smatch matches;
|
||||
ret = std::regex_match (line, matches, rocketfuel_maps_regex);
|
||||
if (ret)
|
||||
{
|
||||
regerror (ret, ®ex, errbuf, sizeof (errbuf));
|
||||
return RF_UNKNOWN;
|
||||
}
|
||||
ret = regexec (®ex, line, REGMATCH_MAX, regmatch, 0);
|
||||
if (ret != REG_NOMATCH)
|
||||
{
|
||||
regfree (®ex);
|
||||
return RF_MAPS;
|
||||
}
|
||||
regfree (®ex);
|
||||
|
||||
// Check whether Weights file or not
|
||||
ret = regcomp (®ex, ROCKETFUEL_WEIGHTS_LINE, REG_EXTENDED | REG_NEWLINE);
|
||||
if (ret != 0)
|
||||
ret = std::regex_match (line, matches, rocketfuel_weights_regex);
|
||||
if (ret)
|
||||
{
|
||||
regerror (ret, ®ex, errbuf, sizeof (errbuf));
|
||||
return RF_UNKNOWN;
|
||||
}
|
||||
ret = regexec (®ex, line, REGMATCH_MAX, regmatch, 0);
|
||||
if (ret != REG_NOMATCH)
|
||||
{
|
||||
regfree (®ex);
|
||||
return RF_WEIGHTS;
|
||||
}
|
||||
regfree (®ex);
|
||||
|
||||
return RF_UNKNOWN;
|
||||
}
|
||||
@@ -343,7 +332,6 @@ RocketfuelTopologyReader::Read (void)
|
||||
std::string line;
|
||||
int lineNumber = 0;
|
||||
enum RF_FileType ftype = RF_UNKNOWN;
|
||||
char errbuf[512];
|
||||
|
||||
if (!topgen.is_open ())
|
||||
{
|
||||
@@ -354,20 +342,17 @@ RocketfuelTopologyReader::Read (void)
|
||||
while (!topgen.eof ())
|
||||
{
|
||||
int ret;
|
||||
int argc;
|
||||
char *argv[REGMATCH_MAX];
|
||||
char *buf;
|
||||
std::vector<std::string> argv;
|
||||
|
||||
lineNumber++;
|
||||
line.clear ();
|
||||
lineBuffer.clear ();
|
||||
|
||||
getline (topgen, line);
|
||||
buf = (char *)line.c_str ();
|
||||
|
||||
if (lineNumber == 1)
|
||||
{
|
||||
ftype = GetFileType (buf);
|
||||
ftype = GetFileType (line);
|
||||
if (ftype == RF_UNKNOWN)
|
||||
{
|
||||
NS_LOG_INFO ("Unknown File Format (" << GetFileName () << ")");
|
||||
@@ -375,78 +360,54 @@ RocketfuelTopologyReader::Read (void)
|
||||
}
|
||||
}
|
||||
|
||||
regmatch_t regmatch[REGMATCH_MAX];
|
||||
regex_t regex;
|
||||
std::smatch matches;
|
||||
|
||||
if (ftype == RF_MAPS)
|
||||
{
|
||||
ret = regcomp (®ex, ROCKETFUEL_MAPS_LINE, REG_EXTENDED | REG_NEWLINE);
|
||||
if (ret != 0)
|
||||
ret = std::regex_match (line, matches, rocketfuel_maps_regex);
|
||||
if (ret != true || matches.empty ())
|
||||
{
|
||||
regerror (ret, ®ex, errbuf, sizeof (errbuf));
|
||||
regfree (®ex);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = regexec (®ex, buf, REGMATCH_MAX, regmatch, 0);
|
||||
if (ret == REG_NOMATCH)
|
||||
{
|
||||
NS_LOG_WARN ("match failed (maps file): %s" << buf);
|
||||
regfree (®ex);
|
||||
NS_LOG_WARN ("match failed (maps file): %s" << line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (ftype == RF_WEIGHTS)
|
||||
{
|
||||
ret = regcomp (®ex, ROCKETFUEL_WEIGHTS_LINE, REG_EXTENDED | REG_NEWLINE);
|
||||
if (ret != 0)
|
||||
ret = std::regex_match (line, matches, rocketfuel_weights_regex);
|
||||
if (ret != true || matches.empty ())
|
||||
{
|
||||
regerror (ret, ®ex, errbuf, sizeof (errbuf));
|
||||
regfree (®ex);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = regexec (®ex, buf, REGMATCH_MAX, regmatch, 0);
|
||||
if (ret == REG_NOMATCH)
|
||||
{
|
||||
NS_LOG_WARN ("match failed (weights file): %s" << buf);
|
||||
regfree (®ex);
|
||||
NS_LOG_WARN ("match failed (weights file): %s" << line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
line = buf;
|
||||
argc = 0;
|
||||
std::string matched_string;
|
||||
|
||||
/* regmatch[0] is the entire strings that matched */
|
||||
for (int i = 1; i < REGMATCH_MAX; i++)
|
||||
for (auto it = matches.begin ()+1; it != matches.end (); it++)
|
||||
{
|
||||
if (regmatch[i].rm_so == -1)
|
||||
if (it->matched)
|
||||
{
|
||||
argv[i - 1] = NULL;
|
||||
matched_string = it->str ();
|
||||
}
|
||||
else
|
||||
{
|
||||
line[regmatch[i].rm_eo] = '\0';
|
||||
argv[i - 1] = &line[regmatch[i].rm_so];
|
||||
argc = i;
|
||||
matched_string = "";
|
||||
}
|
||||
argv.push_back (matched_string);
|
||||
}
|
||||
|
||||
if (ftype == RF_MAPS)
|
||||
{
|
||||
nodes.Add (GenerateFromMapsFile (argc, argv));
|
||||
nodes.Add (GenerateFromMapsFile (argv));
|
||||
}
|
||||
else if (ftype == RF_WEIGHTS)
|
||||
{
|
||||
nodes.Add (GenerateFromWeightsFile (argc, argv));
|
||||
nodes.Add (GenerateFromWeightsFile (argv));
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_WARN ("Unsupported file format (only Maps/Weights are supported)");
|
||||
}
|
||||
|
||||
regfree (®ex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -80,11 +80,10 @@ private:
|
||||
* Parser for the *.cch file available at:
|
||||
* http://www.cs.washington.edu/research/networking/rocketfuel/maps/rocketfuel_maps_cch.tar.gz
|
||||
*
|
||||
* \param [in] argc Argument counter.
|
||||
* \param [in] argv Argument vector.
|
||||
* \return The container of the nodes created (or empty container if there was an error).
|
||||
*/
|
||||
NodeContainer GenerateFromMapsFile (int argc, char *argv[]);
|
||||
NodeContainer GenerateFromMapsFile (const std::vector<std::string>& argv);
|
||||
|
||||
/**
|
||||
* \brief Topology read function from a file containing the nodes weights.
|
||||
@@ -92,11 +91,10 @@ private:
|
||||
* Parser for the weights.* file available at:
|
||||
* http://www.cs.washington.edu/research/networking/rocketfuel/maps/weights-dist.tar.gz
|
||||
*
|
||||
* \param [in] argc Argument counter.
|
||||
* \param [in] argv Argument vector.
|
||||
* \return The container of the nodes created (or empty container if there was an error).
|
||||
*/
|
||||
NodeContainer GenerateFromWeightsFile (int argc, char *argv[]);
|
||||
NodeContainer GenerateFromWeightsFile (const std::vector<std::string>& argv);
|
||||
|
||||
/**
|
||||
* \brief Enum of the possible file types.
|
||||
@@ -115,7 +113,7 @@ private:
|
||||
* \param buf the first line of the file being read
|
||||
* \return The file type (RF_MAPS, RF_WEIGHTS, or RF_UNKNOWN)
|
||||
*/
|
||||
enum RF_FileType GetFileType (const char *buf);
|
||||
enum RF_FileType GetFileType (const std::string& buf);
|
||||
|
||||
int m_linksNumber; //!< Number of links.
|
||||
int m_nodesNumber; //!< Number of nodes.
|
||||
|
||||
Reference in New Issue
Block a user