added field list to find command (solved #1)

This commit is contained in:
john30
2015-09-26 12:40:57 +02:00
parent c0b022782f
commit f3d4bbcc19
3 changed files with 130 additions and 13 deletions
+62 -13
View File
@@ -27,6 +27,22 @@
using namespace std;
/** the known column names (pairs of full length name and short length name). */
static const char* columnNames[] = {
"type", "t",
"circuit", "c",
"name", "n",
"comment", "co",
"qq", "q",
"zz", "z",
"pbsb", "p",
"id", "i",
"fields", "f",
};
/** the number of known column names. */
static const size_t columnCount = sizeof(columnNames) / sizeof(char*);
MainLoop::MainLoop(const struct options opt, Device *device, DataFieldTemplates* templates, MessageMap* messages)
: m_device(device), m_templates(templates), m_messages(messages), m_address(opt.address)
{
@@ -542,6 +558,7 @@ string MainLoop::executeFind(vector<string> &args)
{
size_t argPos = 1;
bool verbose = false, configFormat = false, exact = false, withRead = true, withWrite = false, withPassive = true, first = true, onlyWithData = false;
vector<size_t> columns;
string circuit;
short pb = -1;
while (args.size() > argPos && args[argPos][0] == '-') {
@@ -549,7 +566,33 @@ string MainLoop::executeFind(vector<string> &args)
verbose = true;
else if (args[argPos] == "-f")
configFormat = true;
else if (args[argPos] == "-e")
else if (args[argPos] == "-F") {
argPos++;
if (argPos >= args.size()) {
argPos = 0; // print usage
break;
}
istringstream input(args[argPos]);
string column;
while (getline(input, column, ',') != 0) {
size_t idx = columnCount;
for (size_t i = 0; i < columnCount; i++) {
if (strcasecmp(columnNames[i], column.c_str()) == 0) {
idx = i;
break;
}
}
if (idx==columnCount) {
argPos = 0; // print usage
break;
}
columns.push_back(idx/2);
}
if (columns.empty()) {
argPos = 0; // print usage
break;
}
} else if (args[argPos] == "-e")
exact = true;
else if (args[argPos] == "-r") {
if (first) {
@@ -605,18 +648,20 @@ string MainLoop::executeFind(vector<string> &args)
argPos++;
}
if (argPos == 0 || args.size() < argPos || args.size() > argPos + 1)
return "usage: find [-v] [-r] [-w] [-p] [-d] [-i PB] [-f] [-e] [-c CIRCUIT] [NAME]\n"
return "usage: find [-v] [-r] [-w] [-p] [-d] [-i PB] [-f] [-F COL[,COL]*] [-e] [-c CIRCUIT] [NAME]\n"
" Find message(s).\n"
" -v be verbose (append destination address and update time)\n"
" -r limit to active read messages (default: read + passive)\n"
" -w limit to active write messages (default: read + passive)\n"
" -p limit to passive messages (default: read + passive)\n"
" -d only include messages with actual data\n"
" -i PB limit to messages with primary command byte PB ('0xPB' for hex)\n"
" -f list messages in CSV configuration file format\n"
" -e match NAME and optional CIRCUIT exactly (ignoring case)\n"
" -c CIRCUIT limit to messages of CIRCUIT (or a part thereof without '-e')\n"
" NAME the NAME of the messages to find (or a part thereof without '-e')";
" -v be verbose (append destination address and update time)\n"
" -r limit to active read messages (default: read + passive)\n"
" -w limit to active write messages (default: read + passive)\n"
" -p limit to passive messages (default: read + passive)\n"
" -d only include messages with actual data\n"
" -i PB limit to messages with primary command byte PB ('0xPB' for hex)\n"
" -f list messages in CSV configuration file format\n"
" -F COL[,COL]* list messages in the specified format\n"
" (COL: type,circuit,name,comment,qq,zz,pbsb,id,fields)\n"
" -e match NAME and optional CIRCUIT exactly (ignoring case)\n"
" -c CIRCUIT limit to messages of CIRCUIT (or a part thereof without '-e')\n"
" NAME the NAME of the messages to find (or a part thereof without '-e')";
deque<Message*> messages;
if (args.size() == argPos)
@@ -636,6 +681,10 @@ string MainLoop::executeFind(vector<string> &args)
if (found)
result << endl;
message->dump(result);
} else if (!columns.empty()) {
if (found)
result << endl;
message->dump(result, columns);
} else {
unsigned char dstAddress = message->getDstAddress();
if (dstAddress == SYN)
@@ -869,7 +918,7 @@ string MainLoop::executeHelp()
" Read hex message: read [-f] [-m SECONDS] [-c CIRCUIT] -h ZZPBSBNNDx\n"
" write|w Write value(s): write [-c] CIRCUIT NAME [VALUE[;VALUE]*]\n"
" Write hex message: write -h ZZPBSBNNDx\n"
" find|f Find message(s): find [-v] [-r] [-w] [-p] [-d] [-i PB] [-f] [-c CIRCUIT] [NAME]\n"
" find|f Find message(s): find [-v] [-r] [-w] [-p] [-d] [-i PB] [-f] [-F COL[,COL]*] [-e] [-c CIRCUIT] [NAME]\n"
" listen|l Listen for updates: listen [stop]\n"
" state|s Report bus state\n"
" grab|g Grab unknown messages: grab [stop]\n"
+61
View File
@@ -508,6 +508,67 @@ void Message::dump(ostream& output)
m_data->dump(output);
}
void Message::dump(ostream& output, vector<size_t>& columns)
{
bool first = true;
unsigned int cnt = 0;
for (vector<size_t>::const_iterator it = columns.begin(); it < columns.end(); it++) {
if (first) {
first = false;
} else {
output << FIELD_SEPARATOR;
}
size_t column = *it;
switch (column) {
case 0: // type
if (m_isPassive) {
output << "u";
if (m_isWrite)
output << "w";
} else if (m_isWrite)
output << "w";
else {
output << "r";
if (m_pollPriority>0)
output << static_cast<unsigned>(m_pollPriority);
}
break;
case 1: // circuit
DataField::dumpString(output, m_circuit, false);
break;
case 2: // name
DataField::dumpString(output, m_name, false);
break;
case 3: // comment
DataField::dumpString(output, m_comment, false);
break;
case 4: // QQ
if (m_srcAddress != SYN)
output << hex << setw(2) << setfill('0') << static_cast<unsigned>(m_srcAddress);
break;
case 5: // ZZ
if (m_dstAddress != SYN)
output << hex << setw(2) << setfill('0') << static_cast<unsigned>(m_dstAddress);
break;
case 6: // PBSB
case 7: // ID
for (vector<unsigned char>::const_iterator it = m_id.begin(); it < m_id.end(); it++) {
cnt++;
if (column == 6) {
if (cnt == 2)
break;
} else if (cnt < 2) {
continue;
}
output << hex << setw(2) << setfill('0') << static_cast<unsigned>(*it);
}
break;
case 8: // fields
m_data->dump(output);
break;
}
}
}
string strtolower(const string& str)
{
+7
View File
@@ -260,6 +260,13 @@ public:
*/
void dump(ostream& output);
/**
* Write parts of the message definition to the @a ostream.
* @param output the @a ostream to append the formatted value to.
* @param columns the list of column indexes to write.
*/
void dump(ostream& output, vector<size_t>& columns);
private:
/** the optional circuit name. */