From 3c434960a680c459d526bee483a2bc79ce767473 Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Wed, 29 Apr 2009 19:52:50 +0200 Subject: Refactor StapParser into its own files * grapher/StapParser.cxx: new file * grapher/StapParser.hxx: new file * grapher/grapher.cxx: Use external StapParser class. --- grapher/StapParser.cxx | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 grapher/StapParser.cxx (limited to 'grapher/StapParser.cxx') diff --git a/grapher/StapParser.cxx b/grapher/StapParser.cxx new file mode 100644 index 00000000..2bf26324 --- /dev/null +++ b/grapher/StapParser.cxx @@ -0,0 +1,81 @@ +#include "StapParser.hxx" + +#include + +namespace systemtap +{ +bool StapParser::ioCallback(Glib::IOCondition ioCondition) +{ + if ((ioCondition & Glib::IO_IN) == 0) + return true; + char buf[256]; + ssize_t bytes_read = 0; + bytes_read = read(0, buf, sizeof(buf) - 1); + if (bytes_read <= 0) + { + _win.hide(); + return true; + } + buf[bytes_read] = '\0'; + _buffer += buf; + std::string::size_type ret = std::string::npos; + while ((ret = _buffer.find('\n')) != std::string::npos) + { + Glib::ustring dataString(_buffer, 0, ret); + if (dataString[0] == '%') + { + size_t found; + if ((found = dataString.find("%Title:") == 0)) + { + std::string title = dataString.substr(7); + _widget.setTitle(title); + } + else if ((found = dataString.find("%XAxisTitle:") == 0)) + { + _widget.setXAxisText(dataString.substr(12)); + } + else if ((found = dataString.find("%YAxisTitle:") == 0)) + { + _widget.setYAxisText(dataString.substr(12)); + } + else if ((found = dataString.find("%YMax:") == 0)) + { + double ymax; + std::istringstream stream(dataString.substr(6)); + stream >> ymax; + // _gdata->scale = ymax; + } + else if ((found = dataString.find("%DataSet:") == 0)) + { + std::tr1::shared_ptr dataSet(new GraphData); + std::string setName; + int hexColor; + std::string style; + std::istringstream stream(dataString.substr(9)); + stream >> setName >> dataSet->scale >> std::hex >> hexColor + >> style; + dataSet->color[0] = (hexColor >> 16) / 255.0; + dataSet->color[1] = ((hexColor >> 8) & 0xff) / 255.0; + dataSet->color[2] = (hexColor & 0xff) / 255.0; + if (style == "dot") + dataSet->style = GraphData::DOT; + _dataSets.insert(std::make_pair(setName, dataSet)); + _widget.addGraphData(dataSet); + } + } + else + { + std::string dataSet; + double time; + double data; + std::istringstream stream(dataString); + stream >> dataSet >> time >> data; + DataMap::iterator itr = _dataSets.find(dataSet); + if (itr != _dataSets.end()) + itr->second->data.push_back(std::make_pair(time, data)); + } + _buffer.erase(0, ret + 1); + } + return true; +} +} -- cgit From 0f262fd10d337db0ec435d840b541d629879ce9f Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Wed, 20 May 2009 13:29:54 +0200 Subject: Add CSV syntax support to the grapher * grapher/GraphData.hxx (CSVData): new class * grapher/GraphData.cxx (commaSplit): new function (ioCallback): handle CSV definition and data --- grapher/StapParser.cxx | 80 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 10 deletions(-) (limited to 'grapher/StapParser.cxx') diff --git a/grapher/StapParser.cxx b/grapher/StapParser.cxx index 2bf26324..c973b0aa 100644 --- a/grapher/StapParser.cxx +++ b/grapher/StapParser.cxx @@ -4,8 +4,32 @@ namespace systemtap { +using namespace std; + +vector commaSplit(const string& inStr, size_t pos = 0) +{ + size_t found = pos; + vector result; + while (1) + { + + size_t commaPos = inStr.find(',', found); + string token + = inStr.substr(found, (commaPos == string::npos + ? string::npos + : commaPos - 1 - found)); + result.push_back(token); + if (commaPos != string::npos) + found = commaPos + 1; + else + break; + } + return result; +} + bool StapParser::ioCallback(Glib::IOCondition ioCondition) { + using namespace std; if ((ioCondition & Glib::IO_IN) == 0) return true; char buf[256]; @@ -18,8 +42,8 @@ bool StapParser::ioCallback(Glib::IOCondition ioCondition) } buf[bytes_read] = '\0'; _buffer += buf; - std::string::size_type ret = std::string::npos; - while ((ret = _buffer.find('\n')) != std::string::npos) + string::size_type ret = string::npos; + while ((ret = _buffer.find('\n')) != string::npos) { Glib::ustring dataString(_buffer, 0, ret); if (dataString[0] == '%') @@ -62,17 +86,53 @@ bool StapParser::ioCallback(Glib::IOCondition ioCondition) _dataSets.insert(std::make_pair(setName, dataSet)); _widget.addGraphData(dataSet); } + else if ((found = dataString.find("%CSV:") == 0)) + { + vector tokens = commaSplit(dataString, found + 5); + for (vector::iterator tokIter = tokens.begin(), + e = tokens.end(); + tokIter != e; + ++tokIter) + { + DataMap::iterator setIter = _dataSets.find(*tokIter); + if (setIter != _dataSets.end()) + _csv.elements.push_back(CSVData::Element(*tokIter, + setIter->second)); + } + } } else { - std::string dataSet; - double time; - double data; - std::istringstream stream(dataString); - stream >> dataSet >> time >> data; - DataMap::iterator itr = _dataSets.find(dataSet); - if (itr != _dataSets.end()) - itr->second->data.push_back(std::make_pair(time, data)); + if (!_csv.elements.empty()) + { + vector tokens = commaSplit(dataString); + int i = 0; + double time; + vector::iterator tokIter = tokens.begin(); + std::istringstream timeStream(*tokIter++); + timeStream >> time; + for (vector::iterator e = tokens.end(); + tokIter != e; + ++tokIter, ++i) + { + std::istringstream stream(*tokIter); + double data; + stream >> data; + _csv.elements[i].second + ->data.push_back(std::make_pair(time, data)); + } + } + else + { + std::string dataSet; + double time; + double data; + std::istringstream stream(dataString); + stream >> dataSet >> time >> data; + DataMap::iterator itr = _dataSets.find(dataSet); + if (itr != _dataSets.end()) + itr->second->data.push_back(std::make_pair(time, data)); + } } _buffer.erase(0, ret + 1); } -- cgit From 5f4f8b1129659adb2015ce42821faccf8fe6d8d5 Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Wed, 27 May 2009 10:32:51 +0200 Subject: Templatize GraphData * grapher/GraphData.hxx (GraphDataBase): new superclass for GraphData. Split time data out as a separate vector. (GraphData): Rewrite as template. * grapher/GraphWidget.cxx (on_expose_event): Reflect GraphData templatization. Handle events with string values. * grapher/GraphWidget.hxx (GraphWidget): Keep pointers to GraphDataBase objects instead of GraphData. * grapher/StapParser.cxx (parseData): new member function (ioCallback): Handle new discreet event * grapher/StapParser.hxx (StapParser): keep pointers to GraphDataBase objects instead of GraphData * testsuite/systemtap.examples/general/grapher.stp: Display actual key pressed for keyboard event --- grapher/StapParser.cxx | 77 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 59 insertions(+), 18 deletions(-) (limited to 'grapher/StapParser.cxx') diff --git a/grapher/StapParser.cxx b/grapher/StapParser.cxx index c973b0aa..8b72f93b 100644 --- a/grapher/StapParser.cxx +++ b/grapher/StapParser.cxx @@ -1,6 +1,7 @@ #include "StapParser.hxx" #include +#include namespace systemtap { @@ -27,6 +28,29 @@ vector commaSplit(const string& inStr, size_t pos = 0) return result; } + void StapParser::parseData(std::tr1::shared_ptr gdata, + double time, const string& dataString) + { + std::istringstream stream(dataString); + std::tr1::shared_ptr > dblptr; + std::tr1::shared_ptr > strptr; + dblptr = std::tr1::dynamic_pointer_cast >(gdata); + if (dblptr) + { + double data; + stream >> data; + dblptr->times.push_back(time); + dblptr->data.push_back(data); + } + else if ((strptr = std::tr1 + ::dynamic_pointer_cast >(gdata)) + != 0) + { + strptr->times.push_back(time); + strptr->data.push_back(dataString); + } + } + bool StapParser::ioCallback(Glib::IOCondition ioCondition) { using namespace std; @@ -71,20 +95,38 @@ bool StapParser::ioCallback(Glib::IOCondition ioCondition) } else if ((found = dataString.find("%DataSet:") == 0)) { - std::tr1::shared_ptr dataSet(new GraphData); std::string setName; int hexColor; + double scale; std::string style; std::istringstream stream(dataString.substr(9)); - stream >> setName >> dataSet->scale >> std::hex >> hexColor + stream >> setName >> scale >> std::hex >> hexColor >> style; - dataSet->color[0] = (hexColor >> 16) / 255.0; - dataSet->color[1] = ((hexColor >> 8) & 0xff) / 255.0; - dataSet->color[2] = (hexColor & 0xff) / 255.0; - if (style == "dot") - dataSet->style = GraphData::DOT; - _dataSets.insert(std::make_pair(setName, dataSet)); - _widget.addGraphData(dataSet); + if (style == "bar" || style == "dot") + { + std::tr1::shared_ptr > + dataSet(new GraphData); + if (style == "dot") + dataSet->style = GraphDataBase::DOT; + dataSet->color[0] = (hexColor >> 16) / 255.0; + dataSet->color[1] = ((hexColor >> 8) & 0xff) / 255.0; + dataSet->color[2] = (hexColor & 0xff) / 255.0; + dataSet->scale = scale; + _dataSets.insert(std::make_pair(setName, dataSet)); + _widget.addGraphData(dataSet); + } + else if (style == "discreet") + { + std::tr1::shared_ptr > + dataSet(new GraphData); + dataSet->style = GraphDataBase::EVENT; + dataSet->color[0] = (hexColor >> 16) / 255.0; + dataSet->color[1] = ((hexColor >> 8) & 0xff) / 255.0; + dataSet->color[2] = (hexColor & 0xff) / 255.0; + dataSet->scale = scale; + _dataSets.insert(std::make_pair(setName, dataSet)); + _widget.addGraphData(dataSet); + } } else if ((found = dataString.find("%CSV:") == 0)) { @@ -96,8 +138,9 @@ bool StapParser::ioCallback(Glib::IOCondition ioCondition) { DataMap::iterator setIter = _dataSets.find(*tokIter); if (setIter != _dataSets.end()) - _csv.elements.push_back(CSVData::Element(*tokIter, - setIter->second)); + _csv.elements + .push_back(CSVData::Element(*tokIter, + setIter->second)); } } } @@ -115,23 +158,21 @@ bool StapParser::ioCallback(Glib::IOCondition ioCondition) tokIter != e; ++tokIter, ++i) { - std::istringstream stream(*tokIter); - double data; - stream >> data; - _csv.elements[i].second - ->data.push_back(std::make_pair(time, data)); + parseData(_csv.elements[i].second, time, *tokIter); } } else { std::string dataSet; double time; - double data; + string data; std::istringstream stream(dataString); stream >> dataSet >> time >> data; DataMap::iterator itr = _dataSets.find(dataSet); if (itr != _dataSets.end()) - itr->second->data.push_back(std::make_pair(time, data)); + { + parseData(itr->second, time, data); + } } } _buffer.erase(0, ret + 1); -- cgit From 364ad890e341bb60ae169af69933a382d4bf9f81 Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Mon, 27 Jul 2009 12:46:30 +0200 Subject: Support for presenting multiple graphs * grapher/Graph.hxx: New file; class for single graph display. * grapher/Graph.cxx: New file. * grapher/GraphData.hxx: Associate title and axis labels with graph data and not a graph display. * grapher/GraphWidget.hxx: Move graph-related members to Graph class. * grapher/GraphWidget.cxx (getExtents, setExtents): Move to Graph class (on_expose_event): Move graph rendering to Graph. (on_button_press_event): Delegate to Graph. (on_motion_notify_event, on_scroll_event): Modify "active" graph. * grapher/StapParser.cxx (findTaggedValue): New parsing helper function. (io_callback): Support new syntax where properties are attached to graph data and not the entire graph. * grapher/grapher.cxx (GrapherWindow): Don't set graph values. * grapher/Makefile.am: Add Graph.cxx. * testsuite/systemtap.examples/general/grapher.stp: New property syntax. --- grapher/StapParser.cxx | 248 +++++++++++++++++++++++++++---------------------- 1 file changed, 135 insertions(+), 113 deletions(-) (limited to 'grapher/StapParser.cxx') diff --git a/grapher/StapParser.cxx b/grapher/StapParser.cxx index 8b72f93b..1c865614 100644 --- a/grapher/StapParser.cxx +++ b/grapher/StapParser.cxx @@ -5,7 +5,8 @@ namespace systemtap { -using namespace std; + using namespace std; + using namespace std::tr1; vector commaSplit(const string& inStr, size_t pos = 0) { @@ -28,13 +29,13 @@ vector commaSplit(const string& inStr, size_t pos = 0) return result; } - void StapParser::parseData(std::tr1::shared_ptr gdata, + void StapParser::parseData(shared_ptr gdata, double time, const string& dataString) { std::istringstream stream(dataString); - std::tr1::shared_ptr > dblptr; - std::tr1::shared_ptr > strptr; - dblptr = std::tr1::dynamic_pointer_cast >(gdata); + shared_ptr > dblptr; + shared_ptr > strptr; + dblptr = dynamic_pointer_cast >(gdata); if (dblptr) { double data; @@ -51,132 +52,153 @@ vector commaSplit(const string& inStr, size_t pos = 0) } } -bool StapParser::ioCallback(Glib::IOCondition ioCondition) -{ - using namespace std; - if ((ioCondition & Glib::IO_IN) == 0) - return true; - char buf[256]; - ssize_t bytes_read = 0; - bytes_read = read(0, buf, sizeof(buf) - 1); - if (bytes_read <= 0) - { - _win.hide(); - return true; - } - buf[bytes_read] = '\0'; - _buffer += buf; - string::size_type ret = string::npos; - while ((ret = _buffer.find('\n')) != string::npos) + size_t findTaggedValue(const string& src, const char* tag, string& result) + { + size_t found; + if ((found = src.find(tag)) != string::npos) + result = src.substr(strlen(tag)); + return found; + } + + bool StapParser::ioCallback(Glib::IOCondition ioCondition) { - Glib::ustring dataString(_buffer, 0, ret); - if (dataString[0] == '%') + using namespace std; + if ((ioCondition & Glib::IO_IN) == 0) + return true; + char buf[256]; + ssize_t bytes_read = 0; + bytes_read = read(0, buf, sizeof(buf) - 1); + if (bytes_read <= 0) + { + _win.hide(); + return true; + } + buf[bytes_read] = '\0'; + _buffer += buf; + string::size_type ret = string::npos; + while ((ret = _buffer.find('\n')) != string::npos) { + Glib::ustring dataString(_buffer, 0, ret); + // %DataSet and %CSV declare a data set; all other statements begin with + // the name of a data set. size_t found; - if ((found = dataString.find("%Title:") == 0)) - { - std::string title = dataString.substr(7); - _widget.setTitle(title); - } - else if ((found = dataString.find("%XAxisTitle:") == 0)) - { - _widget.setXAxisText(dataString.substr(12)); - } - else if ((found = dataString.find("%YAxisTitle:") == 0)) + if (dataString[0] == '%') { - _widget.setYAxisText(dataString.substr(12)); - } - else if ((found = dataString.find("%YMax:") == 0)) - { - double ymax; - std::istringstream stream(dataString.substr(6)); - stream >> ymax; - // _gdata->scale = ymax; - } - else if ((found = dataString.find("%DataSet:") == 0)) - { - std::string setName; - int hexColor; - double scale; - std::string style; - std::istringstream stream(dataString.substr(9)); - stream >> setName >> scale >> std::hex >> hexColor - >> style; - if (style == "bar" || style == "dot") + if ((found = dataString.find("%DataSet:") == 0)) { - std::tr1::shared_ptr > - dataSet(new GraphData); - if (style == "dot") - dataSet->style = GraphDataBase::DOT; - dataSet->color[0] = (hexColor >> 16) / 255.0; - dataSet->color[1] = ((hexColor >> 8) & 0xff) / 255.0; - dataSet->color[2] = (hexColor & 0xff) / 255.0; - dataSet->scale = scale; - _dataSets.insert(std::make_pair(setName, dataSet)); - _widget.addGraphData(dataSet); + std::string setName; + int hexColor; + double scale; + std::string style; + std::istringstream stream(dataString.substr(9)); + stream >> setName >> scale >> std::hex >> hexColor + >> style; + if (style == "bar" || style == "dot") + { + shared_ptr > + dataSet(new GraphData); + if (style == "dot") + dataSet->style = GraphDataBase::DOT; + dataSet->color[0] = (hexColor >> 16) / 255.0; + dataSet->color[1] = ((hexColor >> 8) & 0xff) / 255.0; + dataSet->color[2] = (hexColor & 0xff) / 255.0; + dataSet->scale = scale; + _dataSets.insert(std::make_pair(setName, dataSet)); + _widget.addGraphData(dataSet); + } + else if (style == "discreet") + { + shared_ptr > + dataSet(new GraphData); + dataSet->style = GraphDataBase::EVENT; + dataSet->color[0] = (hexColor >> 16) / 255.0; + dataSet->color[1] = ((hexColor >> 8) & 0xff) / 255.0; + dataSet->color[2] = (hexColor & 0xff) / 255.0; + dataSet->scale = scale; + _dataSets.insert(std::make_pair(setName, dataSet)); + _widget.addGraphData(dataSet); + } } - else if (style == "discreet") + else if ((found = dataString.find("%CSV:") == 0)) { - std::tr1::shared_ptr > - dataSet(new GraphData); - dataSet->style = GraphDataBase::EVENT; - dataSet->color[0] = (hexColor >> 16) / 255.0; - dataSet->color[1] = ((hexColor >> 8) & 0xff) / 255.0; - dataSet->color[2] = (hexColor & 0xff) / 255.0; - dataSet->scale = scale; - _dataSets.insert(std::make_pair(setName, dataSet)); - _widget.addGraphData(dataSet); + vector tokens = commaSplit(dataString, found + 5); + for (vector::iterator tokIter = tokens.begin(), + e = tokens.end(); + tokIter != e; + ++tokIter) + { + DataMap::iterator setIter = _dataSets.find(*tokIter); + if (setIter != _dataSets.end()) + _csv.elements + .push_back(CSVData::Element(*tokIter, + setIter->second)); + } } - } - else if ((found = dataString.find("%CSV:") == 0)) - { - vector tokens = commaSplit(dataString, found + 5); - for (vector::iterator tokIter = tokens.begin(), - e = tokens.end(); - tokIter != e; - ++tokIter) + else { - DataMap::iterator setIter = _dataSets.find(*tokIter); - if (setIter != _dataSets.end()) - _csv.elements - .push_back(CSVData::Element(*tokIter, - setIter->second)); - } - } - } - else - { - if (!_csv.elements.empty()) - { - vector tokens = commaSplit(dataString); - int i = 0; - double time; - vector::iterator tokIter = tokens.begin(); - std::istringstream timeStream(*tokIter++); - timeStream >> time; - for (vector::iterator e = tokens.end(); - tokIter != e; - ++tokIter, ++i) - { - parseData(_csv.elements[i].second, time, *tokIter); + cerr << "Unknown declaration " << dataString << endl; } } else { - std::string dataSet; - double time; - string data; std::istringstream stream(dataString); - stream >> dataSet >> time >> data; - DataMap::iterator itr = _dataSets.find(dataSet); + string setName; + stream >> setName; + DataMap::iterator itr = _dataSets.find(setName); if (itr != _dataSets.end()) { - parseData(itr->second, time, data); + shared_ptr gdata = itr->second; + string decl; + // Hack: scan from the beginning of dataString again + if (findTaggedValue(dataString, "%Title", decl) + != string::npos) + { + gdata->title = decl; + } + else if (findTaggedValue(dataString, "%XAxisTitle:", decl) + != string::npos) + { + gdata->xAxisText = decl; + } + else if (findTaggedValue(dataString, "%YAxisTitle:", decl) + != string::npos) + { + gdata->yAxisText = decl; + } + else if ((found = dataString.find("%YMax:")) != string::npos) + { + double ymax; + std::istringstream stream(dataString.substr(found)); + stream >> ymax; + gdata->scale = ymax; + } + + if (!_csv.elements.empty()) + { + vector tokens = commaSplit(dataString); + int i = 0; + double time; + vector::iterator tokIter = tokens.begin(); + std::istringstream timeStream(*tokIter++); + timeStream >> time; + for (vector::iterator e = tokens.end(); + tokIter != e; + ++tokIter, ++i) + { + parseData(_csv.elements[i].second, time, *tokIter); + } + } + else + { + double time; + string data; + stream >> time >> data; + parseData(itr->second, time, data); + } } } + _buffer.erase(0, ret + 1); } - _buffer.erase(0, ret + 1); + return true; } - return true; -} } -- cgit