added field list to find command (solved #1)
This commit is contained in:
+52
-3
@@ -27,6 +27,22 @@
|
|||||||
|
|
||||||
using namespace std;
|
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)
|
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)
|
: 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;
|
size_t argPos = 1;
|
||||||
bool verbose = false, configFormat = false, exact = false, withRead = true, withWrite = false, withPassive = true, first = true, onlyWithData = false;
|
bool verbose = false, configFormat = false, exact = false, withRead = true, withWrite = false, withPassive = true, first = true, onlyWithData = false;
|
||||||
|
vector<size_t> columns;
|
||||||
string circuit;
|
string circuit;
|
||||||
short pb = -1;
|
short pb = -1;
|
||||||
while (args.size() > argPos && args[argPos][0] == '-') {
|
while (args.size() > argPos && args[argPos][0] == '-') {
|
||||||
@@ -549,7 +566,33 @@ string MainLoop::executeFind(vector<string> &args)
|
|||||||
verbose = true;
|
verbose = true;
|
||||||
else if (args[argPos] == "-f")
|
else if (args[argPos] == "-f")
|
||||||
configFormat = true;
|
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;
|
exact = true;
|
||||||
else if (args[argPos] == "-r") {
|
else if (args[argPos] == "-r") {
|
||||||
if (first) {
|
if (first) {
|
||||||
@@ -605,7 +648,7 @@ string MainLoop::executeFind(vector<string> &args)
|
|||||||
argPos++;
|
argPos++;
|
||||||
}
|
}
|
||||||
if (argPos == 0 || args.size() < argPos || args.size() > argPos + 1)
|
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"
|
" Find message(s).\n"
|
||||||
" -v be verbose (append destination address and update time)\n"
|
" -v be verbose (append destination address and update time)\n"
|
||||||
" -r limit to active read messages (default: read + passive)\n"
|
" -r limit to active read messages (default: read + passive)\n"
|
||||||
@@ -614,6 +657,8 @@ string MainLoop::executeFind(vector<string> &args)
|
|||||||
" -d only include messages with actual data\n"
|
" -d only include messages with actual data\n"
|
||||||
" -i PB limit to messages with primary command byte PB ('0xPB' for hex)\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 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"
|
" -e match NAME and optional CIRCUIT exactly (ignoring case)\n"
|
||||||
" -c CIRCUIT limit to messages of CIRCUIT (or a part thereof without '-e')\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')";
|
" NAME the NAME of the messages to find (or a part thereof without '-e')";
|
||||||
@@ -636,6 +681,10 @@ string MainLoop::executeFind(vector<string> &args)
|
|||||||
if (found)
|
if (found)
|
||||||
result << endl;
|
result << endl;
|
||||||
message->dump(result);
|
message->dump(result);
|
||||||
|
} else if (!columns.empty()) {
|
||||||
|
if (found)
|
||||||
|
result << endl;
|
||||||
|
message->dump(result, columns);
|
||||||
} else {
|
} else {
|
||||||
unsigned char dstAddress = message->getDstAddress();
|
unsigned char dstAddress = message->getDstAddress();
|
||||||
if (dstAddress == SYN)
|
if (dstAddress == SYN)
|
||||||
@@ -869,7 +918,7 @@ string MainLoop::executeHelp()
|
|||||||
" Read hex message: read [-f] [-m SECONDS] [-c CIRCUIT] -h ZZPBSBNNDx\n"
|
" 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|w Write value(s): write [-c] CIRCUIT NAME [VALUE[;VALUE]*]\n"
|
||||||
" Write hex message: write -h ZZPBSBNNDx\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"
|
" listen|l Listen for updates: listen [stop]\n"
|
||||||
" state|s Report bus state\n"
|
" state|s Report bus state\n"
|
||||||
" grab|g Grab unknown messages: grab [stop]\n"
|
" grab|g Grab unknown messages: grab [stop]\n"
|
||||||
|
|||||||
@@ -508,6 +508,67 @@ void Message::dump(ostream& output)
|
|||||||
m_data->dump(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)
|
string strtolower(const string& str)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -260,6 +260,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
void dump(ostream& output);
|
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:
|
private:
|
||||||
|
|
||||||
/** the optional circuit name. */
|
/** the optional circuit name. */
|
||||||
|
|||||||
Reference in New Issue
Block a user