Populate a list with Modules and display it in a Dialogbox in DOORS - ibm-doors

I need a DXL script that fill a DialogBox with returned Module names'. I have several modules within a project.
Below is my current progress. My idea is to put all Module names in a List and then display the list in a DialogBox.
Can you help me write ´´´fillModulelist()´´´
// This DXL script iterates through all formal modules of the folder
DB dbMain = null
DBE dbeModuleList = null
DBE dbeExport = null
DBE dbeExportPath = null
Folder currFolder = null
string startFolder="/Project/Folder";
int moduleCount=0;
void forAllModulesInFolder(Folder f)
{
Item itemRef;
string shType;
string sItemNameFull;
string sItemName;
Module moduleReference;
for itemRef in f do
{
shType = type(itemRef);
print shType "\t";
sItemNameFull = fullName(itemRef);
print sItemNameFull "\t";
sItemName = name(itemRef);
print sItemName "\n";
if(shType=="Folder")
{
string selectedFolder = sItemNameFull;
Folder f = folder selectedFolder;
forAllModulesInFolder(f);
}
if(shType=="Formal")
{
moduleReference = read(sItemNameFull,false,true);
filtering off;
// do s.th. with the moduleReference
close(moduleReference);
moduleCount++;
}
}}
void fillModuleList()
{
//........... HELP NEEDED........
}
// Main-Method
void main(void)
{
string selectedFolder = startFolder;
Folder f = folder selectedFolder;
forAllModulesInFolder(f);
print "Affected Modules: " moduleCount "\n";
}
main();
Any help provided I would be very thankful.

As the list of modules is for displaying it to the user (and perhaps let them select from that list), it is best to display the full name of the modules, thus I would not store the module reference. You can open the module later, when the user has selected/double clicked the module (supposing that this is what you want). Thus, I fill a Skip list with sItemNameFull, sItemNameFull, but if it suits your script better, you can also fill it with moduleReference, sItemNameFull (use create instead of createString in this case). The changes to your script are marked with //->> and //<<-
// This DXL script iterates through all formal modules of the folder
DB dbMain = null
DBE dbeModuleList = null
DBE dbeExport = null
DBE dbeExportPath = null
Folder currFolder = null
string startFolder="/testtrunk";
int moduleCount=0;
//->>
Skip skModules = createString()
//<<-
void forAllModulesInFolder(Folder f)
{
Item itemRef;
string shType;
string sItemNameFull;
string sItemName;
Module moduleReference;
for itemRef in f do
{
shType = type(itemRef);
print shType "\t";
sItemNameFull = fullName(itemRef);
print sItemNameFull "\t";
sItemName = name(itemRef);
print sItemName "\n";
if(shType=="Folder")
{
string selectedFolder = sItemNameFull;
Folder f = folder selectedFolder;
forAllModulesInFolder(f);
}
if(shType=="Formal")
{
//->>
put (skModules, sItemNameFull, sItemNameFull)
//moduleReference = read(sItemNameFull,false,true);
//filtering off;
// do s.th. with the moduleReference
//close(moduleReference);
//<<-
moduleCount++;
}
}}
//->>
void fillModuleList(Skip skContent, DBE dbeList)
{
empty dbeList
int cnt=0
string sLine
for sLine in skContent do {
insert (dbeList, cnt, sLine)
cnt++
}
}
//<<-
//->>
void DoSomethingWithDoubleClickedModule (DBE x) {
string sModName = get(x)
print "doing something with " sModName "<---\n"
}
void canvasDummyCB( DBE dummy ) { }
void doNothing(DBE x) {}
void prepareGui()
{
const string sArEmpty[] = {}
dbMain = create ("mytitle", styleCentered)
DBE spaceLeft = canvas(dbMain, 0, 0, canvasDummyCB)
spaceLeft->"top"->"form"; spaceLeft->"left"->"form"
spaceLeft->"right"->"unattached"; spaceLeft->"bottom"->"unattached"
DBE spaceRight = canvas(dbMain, 0, 0, canvasDummyCB)
spaceRight->"top"->"form"; spaceRight->"right"->"form"
spaceRight->"left"->"unattached"; spaceRight->"bottom"->"unattached"
DBE dInfoTextLabel = label(dbMain, "choose a module")
dInfoTextLabel->"top"->"form"
dInfoTextLabel->"left"->"flush"->spaceLeft
dInfoTextLabel->"right"->"flush"->spaceRight
dbeModuleList = list( dbMain, "Modules", 200, 15, sArEmpty)
dbeModuleList->"top"->"flush"->dInfoTextLabel
dbeModuleList->"left"->"flush"->spaceLeft
dbeModuleList->"right"->"flush"->spaceRight
realize dbMain
set( dbeModuleList, doNothing, DoSomethingWithDoubleClickedModule)
}
//<<-
// Main-Method
void main(void)
{
//->>
prepareGui()
//<<-
string selectedFolder = startFolder;
Folder f = folder selectedFolder;
setempty(skModules)
forAllModulesInFolder(f);
//->>
fillModuleList (skModules, dbeModuleList)
//<<-
print "Affected Modules: " moduleCount "\n";
}
main();

Related

Why does assignment not work the same in Dart as it does in Python?

When I run this code:
void readCard(db, [int card_id = -1]) {
if (card_id == -1) {
final ResultSet result = db.select('SELECT * FROM cards');
}
else {
final ResultSet result = db.select("""
SELECT * FROM cards
WHERE card_id=(?)
"""); // this doesn't work yet
}
for (final Row card in result) {
print(
"Card {'card_id': ${card['card_id']}, "
"'due': ${card['due']}, "
"'content': ${card['content']}}"
);
}
}
I get this error:
memotext.dart:66:25: Error: Getter not found: 'result'.
for (final Row card in result) {
^^^^^^
Because result is assigned regardless of whether the if statement or the the else statement runs shouldn't there be no error? Is this something to do with the way dart does assignment?
The result is declared in their respective blocks, it doesn't exist outside. Do this:
void readCard(db, [int card_id = -1]) {
ResultSet result;
if (card_id == -1) {
result = db.select('SELECT * FROM cards');
}
else {
result = db.select("""
SELECT * FROM cards
WHERE card_id=(?)
"""); // this doesn't work yet
}
for (final Row card in result) {
print(
"Card {'card_id': ${card['card_id']}, "
"'due': ${card['due']}, "
"'content': ${card['content']}}"
);
}
}

Reading a file in dart and split the string has different results in console that in vscode

I'm new in dart, I'm trying to read information from a txt file and use the data to create objects from a class (in this case about pokemon), but when I run my program in the terminal it doesn't prints the correct information, and when I run the program in vscode (whit the dart extension, the "run" button) it prints in the debug console the correct information. What is the problem?
When I run the program in vscode I get in my print method (printP) this (which is what I want)
vscode:
Print method:
1+: Bulbasaur GRASS | POISON
but when I run the program in the terminal I get this.
Terminal:
Print method:
| POISONsaur
Here is the dart code.
main.dart
import 'dart:io';
import 'pokemon.dart';
void main() {
var file = new File("/home/ariel/Documents/script/pokemon.txt");
String str = file.readAsStringSync();
var pokes = str.split("[");
pokes = pokes.sublist(1, pokes.length);
getPokemon(pokes[0]).printP();
}
Pokemon getPokemon(String str) {
Pokemon p = new Pokemon();
print("string: " + str);
var aux = str.split("\n");
print(aux.length);
for (var i in aux) {
print("line: " + i);
}
p.number = int.parse(aux[0].split("]")[0]);
p.name = aux[1].split("=")[1];
p.type1 = aux[3].split("=")[1];
p.type2 = aux[4].split("=")[1];
return p;
}
pokemon.dart
class Pokemon {
String _name, _type1, _type2;
int _number;
Pokemon() {
this._name = "";
this._number = 0;
this._type1 = "";
this._type2 = "";
}
void printP() {
print("Print method:");
print("${this._number}+: ${this._name} ${this._type1} | ${this._type2}");
}
void set number(int n) {
this._number = n;
}
void set name(String nm) {
this._name = nm;
}
void set type1(String t) {
this._type1 = t;
}
void set type2(String t) {
this._type2 = t;
}
}
And here is the txt file
pokemon.txt
[1]
Name=Bulbasaur
InternalName=BULBASAUR
Type1=GRASS
Type2=POISON
BaseStats=45,49,49,45,65,65
GenderRate=FemaleOneEighth
GrowthRate=Parabolic
BaseEXP=64
EffortPoints=0,0,0,0,1,0
Rareness=45
Happiness=70
Abilities=OVERGROW
HiddenAbility=CHLOROPHYLL
Moves=1,TACKLE,3,GROWL,7,LEECHSEED,9,VINEWHIP,13,POISONPOWDER,13,SLEEPPOWDER,15,TAKEDOWN,19,RAZORLEAF,21,SWEETSCENT,25,GROWTH,27,DOUBLEEDGE,31,WORRYSEED,33,SYNTHESIS,37,SEEDBOMB
EggMoves=AMNESIA,CHARM,CURSE,ENDURE,GIGADRAIN,GRASSWHISTLE,INGRAIN,LEAFSTORM,MAGICALLEAF,NATUREPOWER,PETALDANCE,POWERWHIP,SKULLBASH,SLUDGE
Compatibility=Monster,Grass
StepsToHatch=5355
Height=0.7
Weight=6.9
Color=Green
Habitat=Grassland
Kind=Seed
Pokedex=Almacena energía en el bulbo de su espalda para alimentarse durante épocas de escasez de recursos o para atacar liberándola de golpe.
BattlerPlayerY=0
BattlerEnemyY=25
BattlerAltitude=0
Evolutions=IVYSAUR,Level,16
Your code are dependent on the newline format of your txt file. I will recommend you are using the LineSplitter class from dart:convert to split your lines.
The problem is that Windows newlines contains both '\n' and '\r' but you are only removing the '\n' part. '\r' are essential meaning the terminal should set the cursor back to the beginning of the line.
You can read this like a typewriter where you first move the head back and set move the paper to the next line. And can read a lot more about is topic here: https://en.wikipedia.org/wiki/Newline
The purpose of the LineSplitter class is to abstract all of this logic and get some behavior which will work on all platforms.
So import dart:convert and change this line:
var aux = str.split("\n");
Into:
var aux = LineSplitter.split(str).toList();

Doors count all inlinks

I want to count all inlinks of all objects in all modules in a IBM Doors Project. (with DXL)
So this is how I did it (in main im calling the function goThroughFolders(current Folder)):
Go through every folder in the project and check if there are modules if there are modules call the function "checkLinks(Module m)"
void goThroughFolders(Folder f)
{
Item itm
if (null f) return
for itm in f do{
print("\nScanning folder...")
if (null itm) continue
if (isDeleted(itm)) continue
else if ((type (itm) == "Project") || (type (itm) == "Folder"))
{
goThroughFolders(folder(itm))
}
else if (type (itm) == "Formal") {
print("\nFound Module")
checkLinks(module(itm))
}
}
}
Check modules for links
void checkLinks(Module m)
{
string objType = ""
Object o = null
Link anyLink
for o in m do {
objType = o."Object Type" ""
// Check if the type is right
if ( ( objType == "Req" ) || ( objType == "Obj" ) ) {
// Check for any outlinks at all
for anyLink in o <- "*" do{
LinkCount++
}
}
}
}
So my problem is the function call checkLinks(module(itm)) in goThroughFolders(Folder f) seems to hand over a null Object.
Error:
-R-E- DXL: <Line:11> null Module do loop parameter was passed
Backtrace:
<Line:69>
<Line:78>
-I- DXL: execution halted
But I dont know why? Can you help me?
Good job spotting the missing step. One other thing you might want to do is close the modules after you finish the analysis, otherwise, you're likely to forget and leave them open, sacrificing memory, until you exit DOORS.
I've made a few modifications and additions below to achieve this - if anything's unclear, please feel free to ask.
Richard
Module m
Skip skLinkSourceMods = create() // Create a skip list to hold references to all modules opened for link analysis
int linkCount = 0
void checkLinks(Item itm, Skip skOpenMods) // Function signature changed to pass in the skip list - not strictly necessary, but clean
{
m = read (fullName(itm), false, true)
put(skOpenMods, m, m) // Add the opened module to the skip list, so we can easily close it later
string objType = ""
Object o = null
Link anyLink
for o in m do {
objType = o."Object Type" ""
// Check if the type is right
if ( ( objType == "Req" ) || ( objType == "Obj" ) ) {
// Check for any outlinks at all
for anyLink in o <- "*" do {
linkCount++
}
}
}
}
void goThroughFolders(Folder f)
{
Item itm
if (null f) return
for itm in f do {
print("\nScanning folder...")
if (null itm) continue
if (isDeleted(itm)) continue
else if ((type (itm) == "Project") || (type (itm) == "Folder"))
{
goThroughFolders(folder(itm))
}
else if (type (itm) == "Formal") {
print("\nFound Module")
checkLinks(itm, skLinkSourceMods) // Function signature changed (see above) to pass in the skip list - not strictly necessary, but clean
}
}
}
void closeModules(Skip skOpenMods)
{
for m in skOpenMods do // Loop through each module in the skip list
{
close(m, false) // Close the module without saving changes (we shouldn't have any - they were opened read-only anyway!)
}
}
goThroughFolders(current Folder)
print "\n" linkCount " links."
closeModules(skLinkSourceMods)
delete(skLinkSourceMods)

How to get function definition/signature as a string in Clang?

How can I get a function's signature (or at least the entire definition?) as a string using Clang/Libclang, assuming I have its CXCursor or so?
I think that the definition may be somehow obtainable by using the cursor's extents, but I don't really know how (what function to use).
You can use this simple code to get prototype of a function ( name, return type, count of arguments and arguments[name,data type]).
string Convert(const CXString& s)
{
string result = clang_getCString(s);
clang_disposeString(s);
return result;
}
void print_function_prototype(CXCursor cursor)
{
// TODO : Print data!
auto type = clang_getCursorType(cursor);
auto function_name = Convert(clang_getCursorSpelling(cursor));
auto return_type = Convert(clang_getTypeSpelling(clang_getResultType(type)));
int num_args = clang_Cursor_getNumArguments(cursor);
for (int i = 0; i < num_args; ++i)
{
auto arg_cursor = clang_Cursor_getArgument(cursor, i);
auto arg_name = Convert(clang_getCursorSpelling(arg_cursor));
if (arg_name.empty())
{
arg_name = "no name!";
}
auto arg_data_type = Convert(clang_getTypeSpelling(clang_getArgType(type, i)));
}
}
CXChildVisitResult functionVisitor(CXCursor cursor, CXCursor /* parent */, CXClientData /* clientData */)
{
if (clang_Location_isFromMainFile(clang_getCursorLocation(cursor)) == 0)
return CXChildVisit_Continue;
CXCursorKind kind = clang_getCursorKind(cursor);
if ((kind == CXCursorKind::CXCursor_FunctionDecl || kind == CXCursorKind::CXCursor_CXXMethod || kind == CXCursorKind::CXCursor_FunctionTemplate || \
kind == CXCursorKind::CXCursor_Constructor))
{
print_function_prototype(cursor);
}
return CXChildVisit_Continue;
}
You could try using clang_Cursor_getMangling() and demangle the result in order to get the complete definition.
I'm using the following for a project I am working on and it works great for the definition. TL&DR clang_getCursorPrettyPrinted with the policy TerseOutput set to true.
std::string getStdString(const CXString &s)
{
std::string rv = clang_getCString(s);
clang_disposeString(s);
return rv;
}
bool isFunctionImplementation(CXCursor &cursor,std::string &decl,std::string &filename,unsigned &lineno)
{
std::string cs = getStdString(clang_getCursorPrettyPrinted(cursor,nullptr));
if (cs.find('{') == std::string::npos) // Just a declaration, not the "meat" of the function, so we dont care
return false;
clang::LangOptions lo;
struct clang::PrintingPolicy pol(lo);
pol.adjustForCPlusPlus();
pol.TerseOutput = true;
pol.FullyQualifiedName = true;
decl = getStdString(clang_getCursorPrettyPrinted(cursor,&pol));
CXSourceLocation location = clang_getCursorLocation( cursor );
CXFile f;
lineno = 0;
filename = "(None)";
clang_getSpellingLocation(location,&f,&lineno,nullptr,nullptr);
if (lineno)
{
filename = getStdString(clang_File_tryGetRealPathName(f));
}
return isAllowedDirectory(filename);
}
This one checks if the function call is "meat" or just a definition. Obviously you can adjust as needed, including writing your own isAllowedDirectory function. Just pass the cursor, two strings and an unsigned into this as you walk your AST when you hit a declaration type.
I use the following, shorter way with clang 10 (though its using a matcher, not a cursor):
The 2 helper functions are general helpers to get the code snippet as a string.
// helper function 1: find position of end of token
SourceLocation
end_of_the_end(SourceLocation const & start_of_end, SourceManager & sm)
{
using namespace clang;
LangOptions lopt;
return Lexer::getLocForEndOfToken(start_of_end, 0, sm, lopt);
}
// helper function 2:
std::string getSymbolString(clang::SourceManager & sm,
const clang::SourceRange & range)
{
return std::string(sm.getCharacterData(range.getBegin()),
sm.getCharacterData(end_of_the_end(range.getEnd(), sm)));
}
The actual code snippet to get the function declaration string is:
// ... in run() of a matcher:
virtual void run(corct::result_t const & result) override
{
using namespace clang;
FunctionDecl * f_decl = const_cast<FunctionDecl *>(
result.Nodes.getNodeAs<FunctionDecl>(fd_bd_name_));
if(f_decl) {
SourceManager & sm(result.Context->getSourceManager());
FunctionDecl * f_decl = const_cast<FunctionDecl *>(
result.Nodes.getNodeAs<FunctionDecl>(fd_bd_name_));
auto full_decl_string =
getSymbolString(sm, f_decl->DeclaratorDecl::getSourceRange());
}
}
This will output inline bool test2(std::string const & str, std::vector<std::string> & sss) for the following function:
inline bool test2(std::string const & str, std::vector<std::string> & sss)
{
return true;
}

Is it right way to make text-protocol interpretation program?

I'm trying to make a program for parsing text protocol.
(I selected text protocol cause I heard that binary packet parsing is more difficult).
Currently, there are really few command and parameters.
each packet can be splited by delimiter(';')
[packet1];[packet2];
Let's break packet1 down.
[Action],[Param1],[Param2],...;
Action : [SET]
Params : [DELAY]
if you send "SET,DELAY,300;" to server,
server will change 'delay' parameter and send "SET,DELAY,300;" to client.
Action : [GET]
Params : [DELAY] [MODE]
if you send "GET,DELAY,MODE;" to server,
server will send "GET,DELAY,300,MODE,2;" to client.
Any way I suceed to make it.
(The code is here. because it is long, I couldn't add it here)
But even if there are only few params and actions, the code is very long and complicated.
I used 'boost::algorithm::split' to split packets.
And I only used 'if','else if','else' to invoke right task corresponding 'action' and 'parameter'.
But I will add more actions and parameters.
But at this rate, I cannot debug or modify code because the comlexity of the code will be more severe.
Is it wrong way to make protocol translation program?
If you know better way, please share with me.
Yes. The better way is to make a grammar, write a parser for it and parse into an AST (abstract syntax tree, or simply strong typed representation of the packets).
A Spirit grammar for this looks like:
I always start out with the AST types:
namespace ast {
struct nil {
friend std::ostream& operator<<(std::ostream& os, nil) { return os << "<nil>"; }
};
using value = boost::variant<nil, double, std::string>;
struct parameter {
std::string _key;
value _val;
};
enum class action {
get,
set,
};
using parameters = std::vector<parameter>;
struct packet {
action _action;
parameters _params;
};
using packets = std::vector<packet>;
}
For simplicity I've
assumed parameters (mode/delay) will have numeric or string values.
used the same packet definition for GET and SET requests (GET requests will just us nil values for the parameters listed)
Next we define a grammar using Boost Spirit Qi:
template <typename It, typename Skipper=qi::space_type>
struct grammar : qi::grammar<It, ast::packets(), Skipper> {
grammar():grammar::base_type(start) {
using qi::raw;
using qi::no_case;
param_key_.add
("delay")
("mode");
start = *(packet_ >> ';');
packet_ =
(no_case["get"] >> qi::attr(ast::action::get) >> *(',' >> get_param_))
| (no_case["set"] >> qi::attr(ast::action::set) >> *(',' >> set_param_))
;
get_param_ = raw[no_case[param_key_]] >> qi::attr(ast::nil());
set_param_ = raw[no_case[param_key_]] >> "," >> value_;
value_ = qi::double_ | string_;
string_ = '"' >> *~qi::char_('"') >> '"';
BOOST_SPIRIT_DEBUG_NODES((start)(packet_)(get_param_)(set_param_)(value_)(string_))
}
// ... field declarations
};
There's a little bit of a learning curve here, but the key point to observe is that it it's possible to create maintainable code that is also debuggable (see here for BOOST_SPIRIT_DEBUG enabled output).
Finally, because the AST is simple we can make a fake request processor that uses a request context (in this case a map to contain the current values of the parameters) to actually process the requests:
struct request_context {
std::map<std::string, ast::value> properties;
request_context()
: properties { { "MODE", 2 }, { "DELAY", 300 } } // defaults
{
}
boost::optional<ast::packet> process_request(ast::packet packet) {
switch (packet._action) {
case ast::action::get:
for(auto& param : packet._params) {
param._val = properties[param._key];
}
return packet;
case ast::action::set:
for(auto& param : packet._params) {
std::cout << "DEBUG: setting property '" << param._key << "' to value '" << param._val << "'\n";
properties[param._key] = param._val;
}
return boost::none;
default:
throw std::runtime_error("bad packet"); // TODO proper exception type
};
}
};
Imagine who much messier this was if you had it mixed with the parsing code, or everything stringly typed
Live On Coliru
//#define BOOST_SPIRIT_DEBUG
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/qi.hpp>
#include <map>
namespace qi = boost::spirit::qi;
namespace ast {
struct nil {
friend std::ostream& operator<<(std::ostream& os, nil) { return os << "<nil>"; }
};
using value = boost::variant<nil, double, std::string>;
struct parameter {
std::string _key;
value _val;
};
enum class action {
get,
set,
};
using parameters = std::vector<parameter>;
struct packet {
action _action;
parameters _params;
};
using packets = std::vector<packet>;
static std::ostream& operator<<(std::ostream& os, action a) {
switch(a) {
case action::get: return os << "GET";
case action::set: return os << "SET";
}
return os << "(other)";
}
}
BOOST_FUSION_ADAPT_STRUCT(ast::parameter,(std::string,_key)(ast::value,_val))
BOOST_FUSION_ADAPT_STRUCT(ast::packet,(ast::action,_action)(ast::parameters,_params))
template <typename It, typename Skipper=qi::space_type>
struct grammar : qi::grammar<It, ast::packets(), Skipper> {
grammar():grammar::base_type(start) {
using qi::raw;
using qi::no_case;
param_key_.add
("delay")
("mode");
start = *(packet_ >> ';');
packet_ =
(no_case["get"] >> qi::attr(ast::action::get) >> *(',' >> get_param_))
| (no_case["set"] >> qi::attr(ast::action::set) >> *(',' >> set_param_))
;
get_param_ = raw[no_case[param_key_]] >> qi::attr(ast::nil());
set_param_ = raw[no_case[param_key_]] >> "," >> value_;
value_ = qi::double_ | string_;
string_ = '"' >> *~qi::char_('"') >> '"';
BOOST_SPIRIT_DEBUG_NODES((start)(packet_)(get_param_)(set_param_)(value_)(string_))
}
private:
qi::symbols<char, std::string> param_key_;
qi::rule<It, ast::parameter(), Skipper> set_param_, get_param_;
qi::rule<It, ast::packets(), Skipper> start;
qi::rule<It, ast::packet(), Skipper> packet_;
qi::rule<It, ast::value(), Skipper> value_;
qi::rule<It, std::string()> string_;
};
struct request_context {
std::map<std::string, ast::value> properties;
request_context()
: properties { { "MODE", 2 }, { "DELAY", 300 } } // defaults
{
}
boost::optional<ast::packet> process_request(ast::packet packet) {
switch (packet._action) {
case ast::action::get:
for(auto& param : packet._params) {
param._val = properties[param._key];
}
return packet;
case ast::action::set:
for(auto& param : packet._params) {
std::cout << "DEBUG: setting property '" << param._key << "' to value '" << param._val << "'\n";
properties[param._key] = param._val;
}
return boost::none;
default:
throw std::runtime_error("bad packet"); // TODO proper exception type
};
}
};
int main()
{
std::string const input =
"GET,DELAY,MODE;"
"SET,DELAY,0,MODE,\"we can have string values too\";GET,MODE;SET,MODE,42;GET,MODE,DELAY;";
using It = std::string::const_iterator;
It f(input.begin()), l(input.end());
grammar<It> p;
ast::packets parsed;
bool ok = qi::phrase_parse(f,l,p,qi::space,parsed);
if (ok) {
std::cout << parsed.size() << " packets successfully parsed\n";
request_context ctx;
for(auto& packet : parsed)
{
auto response = ctx.process_request(packet);
if (response) {
std::cout << "response: " << response->_action;
for(auto& kv : packet._params) {
std::cout << "," << kv._key << "," << kv._val;
}
std::cout << ";\n";
}
}
} else {
std::cout << "Parse error\n";
}
if (f!=l)
std::cout << "Remaining unparsed input: '" << std::string(f,l) << "'\n";
}
Prints:
5 packets successfully parsed
response: GET,DELAY,300,MODE,2;
DEBUG: setting property 'DELAY' to value '0'
DEBUG: setting property 'MODE' to value 'we can have string values too'
response: GET,MODE,we can have string values too;
DEBUG: setting property 'MODE' to value '42'
response: GET,MODE,42,DELAY,0;

Resources