Skip to content
Snippets Groups Projects
Commit 2c7a6a7a authored by Marco Biasini's avatar Marco Biasini
Browse files

introduce FormatDiagnostic routine

parent b15acf69
Branches
Tags
No related merge requests found
......@@ -28,12 +28,45 @@
namespace ost { namespace io {
StarParser::StarParser(std::istream& stream, bool items_as_row):
stream_(stream), line_num_(0), has_current_line_(false), current_line_(),
stream_(stream), filename_("<stream>"), line_num_(0),
has_current_line_(false), current_line_(),
items_row_header_(), items_row_columns_(),
items_row_values_()
{
items_as_row_ = items_as_row;
}
StarParser::StarParser(const String& filename, bool items_as_row):
fstream_(filename.c_str()), stream_(fstream_), filename_(filename),
line_num_(0), has_current_line_(false), current_line_(),
items_row_header_(), items_row_columns_(), items_row_values_()
{
items_as_row_ = items_as_row;
}
String StarParser::FormatDiagnostic(StarDiagType type, const String& message,
int line)
{
std::stringstream ss;
ss << filename_ << ":";
if (line!=-1) {
ss << line << ": ";
} else {
ss << " ";
}
switch (type) {
case STAR_DIAG_ERROR:
ss << "error: ";
break;
case STAR_DIAG_WARNING:
ss << "warning: ";
break;
}
ss << message;
return ss.str();
}
bool StarParser::SplitLine(const StringRef& line,
std::vector<StringRef>& parts, bool clear)
{
......@@ -363,10 +396,9 @@ void StarParser::DiagnoseUnknown()
StringRef line;
bool r=this->GetLine(line);
assert(r);r=r;
ss << "unknown control structure '"<< line.rtrim() << "' on line "
<< line_num_ << "." << std::endl;
throw IOException(ss.str());
ss << "unknown control structure '"<< line.rtrim() << "'";
throw IOException(this->FormatDiagnostic(STAR_DIAG_ERROR, ss.str(),
line_num_));
}
void StarParser::ParseGlobal()
......@@ -400,8 +432,7 @@ void StarParser::Parse()
this->ConsumeLine();
break;
default:
ss << "Missing 'data_' control structure." << std::endl;
throw IOException(ss.str());
throw IOException("Missing 'data_' control structure");
break;
}
}
......
......@@ -24,6 +24,7 @@
Author: Marco Biasini
*/
#include <iostream>
#include <fstream>
#include <vector>
#include <map>
#include <ost/string_ref.hh>
......@@ -31,6 +32,13 @@
namespace ost { namespace io {
typedef enum {
STAR_DIAG_WARNING,
STAR_DIAG_ERROR
} StarDiagType;
class DLLEXPORT_OST_IO StarDataItem {
public:
StarDataItem(const StringRef& category, const StringRef& name,
......@@ -108,7 +116,7 @@ public:
/// header, values as row) and then parsed like a loop
/// (OnBeginLoop(), OnDataRow(), OnEndLoop())
explicit StarParser(std::istream& stream, bool items_as_row=false);
explicit StarParser(const String& filename, bool items_as_row=false);
virtual ~StarParser() { }
// callback interface
public:
......@@ -139,6 +147,10 @@ public:
/// \brief called when leaving a datasection. Will only be invoked when
/// OnBeginData() returned true.
virtual void OnEndData() { }
/// \brief format diagnostic and returns it as a string.
String FormatDiagnostic(StarDiagType type, const String& message,
int line=-1);
public:
void Parse();
......@@ -187,7 +199,9 @@ private:
void ParseDataItem();
void DiagnoseUnknown();
bool ParseMultilineValue(String& value, bool skip=false);
std::ifstream fstream_;
std::istream& stream_;
String filename_;
int line_num_;
bool has_current_line_;
String current_line_;
......
......@@ -37,6 +37,9 @@ class DataItemTestParser: public StarParser {
public:
DataItemTestParser(std::istream& stream): StarParser(stream)
{ }
DataItemTestParser(const String& filename): StarParser(filename)
{ }
virtual void OnDataItem(const StarDataItem& item)
{
BOOST_CHECK_EQUAL(item.GetCategory().str(), "data-item");
......@@ -242,6 +245,31 @@ BOOST_AUTO_TEST_CASE(star_data_item)
BOOST_CHECK_EQUAL(star_p.s4, "a'b");
}
BOOST_AUTO_TEST_CASE(format_diag_stream)
{
BOOST_MESSAGE(" Running star_data_item tests...");
std::ifstream s("testfiles/data-item.cif");
DataItemTestParser star_p(s);
BOOST_CHECK_EQUAL(star_p.FormatDiagnostic(STAR_DIAG_WARNING, "bad", -1),
"<stream>: warning: bad");
BOOST_CHECK_EQUAL(star_p.FormatDiagnostic(STAR_DIAG_ERROR, "really bad", -1),
"<stream>: error: really bad");
BOOST_CHECK_EQUAL(star_p.FormatDiagnostic(STAR_DIAG_ERROR, "bad", 55),
"<stream>:55: error: bad");
}
BOOST_AUTO_TEST_CASE(format_diag_filename)
{
BOOST_MESSAGE(" Running star_data_item tests...");
DataItemTestParser star_p("testfiles/data-item.cif");
BOOST_CHECK_EQUAL(star_p.FormatDiagnostic(STAR_DIAG_WARNING, "bad", -1),
"testfiles/data-item.cif: warning: bad");
BOOST_CHECK_EQUAL(star_p.FormatDiagnostic(STAR_DIAG_ERROR, "really bad", -1),
"testfiles/data-item.cif: error: really bad");
BOOST_CHECK_EQUAL(star_p.FormatDiagnostic(STAR_DIAG_ERROR, "bad", 55),
"testfiles/data-item.cif:55: error: bad");
}
BOOST_AUTO_TEST_CASE(star_multi)
{
std::ifstream s("testfiles/multi-data.cif");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment