added field list to find command (solved #1)
This commit is contained in:
+62
-13
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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. */
|
||||
|
||||
Reference in New Issue
Block a user