Add fields argument to dbgrep() (#613)
This allows optionally printing out the value of one or more fields for each record found.
This commit is contained in:
@@ -235,14 +235,16 @@ static void dblaCallFunc(const iocshArgBuf *args) { iocshSetError(dbla(args[0].s
|
||||
|
||||
/* dbgrep */
|
||||
static const iocshArg dbgrepArg0 = { "pattern",iocshArgStringRecord};
|
||||
static const iocshArg * const dbgrepArgs[1] = {&dbgrepArg0};
|
||||
static const iocshFuncDef dbgrepFuncDef = {"dbgrep",1,dbgrepArgs,
|
||||
"List record names matching pattern.\n"
|
||||
static const iocshArg dbgrepArg1 = { "fields",iocshArgString};
|
||||
static const iocshArg * const dbgrepArgs[2] = {&dbgrepArg0,&dbgrepArg1};
|
||||
static const iocshFuncDef dbgrepFuncDef = {"dbgrep",2,dbgrepArgs,
|
||||
"List record names matching pattern and optionally print field values. \n"
|
||||
"The pattern can contain any characters that are legal in record names as well as:\n"
|
||||
" - \"?\", which matches 0 or one characters.\n"
|
||||
" - \"*\", which matches 0 or more characters.\n\n"
|
||||
"Example: dbgrep(\"*gpibAi*\")\n"};
|
||||
static void dbgrepCallFunc(const iocshArgBuf *args) { iocshSetError(dbgrep(args[0].sval));}
|
||||
"Example: dbgrep(\"*gpibAi*\")\n"
|
||||
" dbgrep(\"*gpibAi*\",\"VAL DESC\")\n"};
|
||||
static void dbgrepCallFunc(const iocshArgBuf *args) { iocshSetError(dbgrep(args[0].sval,args[1].sval));}
|
||||
|
||||
/* dbgf */
|
||||
static const iocshArg dbgfArg0 = { "record name",iocshArgStringRecord};
|
||||
|
||||
@@ -100,13 +100,59 @@ long dba(const char*pname)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* split a space separated list of field names and return the number of
|
||||
fields with each field an element of papfields. These elements
|
||||
point to within the fieldnames variable which is modified
|
||||
by the function. memory is allocated for *ppapfields and needs
|
||||
to be freed later by the calling routine */
|
||||
static int splitFieldsList(char *fieldnames, char ***ppapfields)
|
||||
{
|
||||
char *pnext = fieldnames;
|
||||
int nfields = 0, maxfields = 1;
|
||||
char* saveptr = NULL;
|
||||
/* this may overcount real fields e.g. " VAL " hence maxfields */
|
||||
while (*pnext && (pnext = strchr(pnext, ' '))) {
|
||||
maxfields++;
|
||||
while (*pnext == ' ') pnext++;
|
||||
}
|
||||
*ppapfields = dbCalloc(maxfields, sizeof(char *));
|
||||
pnext = epicsStrtok_r(fieldnames, " ", &saveptr);
|
||||
while(pnext != NULL) {
|
||||
(*ppapfields)[nfields++] = pnext;
|
||||
pnext = epicsStrtok_r(NULL, " ", &saveptr);
|
||||
}
|
||||
return nfields;
|
||||
}
|
||||
|
||||
static void printFieldsList(DBENTRY *pdbentry, char** papfields, int nfields)
|
||||
{
|
||||
int ifield;
|
||||
for (ifield = 0; ifield < nfields; ifield++) {
|
||||
char *pvalue;
|
||||
long status = dbFindField(pdbentry, papfields[ifield]);
|
||||
if (status) {
|
||||
if (!strcmp(papfields[ifield], "recordType")) {
|
||||
pvalue = dbGetRecordTypeName(pdbentry);
|
||||
}
|
||||
else {
|
||||
printf(", ");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
pvalue = dbGetString(pdbentry);
|
||||
}
|
||||
printf(", \"%s\"", (pvalue ? pvalue : ""));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
long dbl(const char *precordTypename, const char *fields)
|
||||
{
|
||||
DBENTRY dbentry;
|
||||
DBENTRY *pdbentry=&dbentry;
|
||||
long status;
|
||||
int nfields = 0;
|
||||
int ifield;
|
||||
char *fieldnames = 0;
|
||||
char **papfields = 0;
|
||||
|
||||
@@ -121,25 +167,8 @@ long dbl(const char *precordTypename, const char *fields)
|
||||
if (fields && (*fields == '\0'))
|
||||
fields = NULL;
|
||||
if (fields) {
|
||||
char *pnext;
|
||||
|
||||
fieldnames = epicsStrDup(fields);
|
||||
nfields = 1;
|
||||
pnext = fieldnames;
|
||||
while (*pnext && (pnext = strchr(pnext,' '))) {
|
||||
nfields++;
|
||||
while (*pnext == ' ') pnext++;
|
||||
}
|
||||
papfields = dbCalloc(nfields,sizeof(char *));
|
||||
pnext = fieldnames;
|
||||
for (ifield = 0; ifield < nfields; ifield++) {
|
||||
papfields[ifield] = pnext;
|
||||
if (ifield < nfields - 1) {
|
||||
pnext = strchr(pnext, ' ');
|
||||
*pnext++ = 0;
|
||||
while (*pnext == ' ') pnext++;
|
||||
}
|
||||
}
|
||||
nfields = splitFieldsList(fieldnames, &papfields);
|
||||
}
|
||||
dbInitEntry(pdbbase, pdbentry);
|
||||
if (!precordTypename)
|
||||
@@ -154,24 +183,7 @@ long dbl(const char *precordTypename, const char *fields)
|
||||
status = dbFirstRecord(pdbentry);
|
||||
while (!status) {
|
||||
printf("%s", dbGetRecordName(pdbentry));
|
||||
for (ifield = 0; ifield < nfields; ifield++) {
|
||||
char *pvalue;
|
||||
status = dbFindField(pdbentry, papfields[ifield]);
|
||||
if (status) {
|
||||
if (!strcmp(papfields[ifield], "recordType")) {
|
||||
pvalue = dbGetRecordTypeName(pdbentry);
|
||||
}
|
||||
else {
|
||||
printf(", ");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
pvalue = dbGetString(pdbentry);
|
||||
}
|
||||
printf(", \"%s\"", pvalue ? pvalue : "");
|
||||
}
|
||||
printf("\n");
|
||||
printFieldsList(pdbentry, papfields, nfields);
|
||||
status = dbNextRecord(pdbentry);
|
||||
}
|
||||
if (precordTypename)
|
||||
@@ -283,14 +295,17 @@ long dbli(const char *pattern)
|
||||
return 0;
|
||||
}
|
||||
|
||||
long dbgrep(const char *pmask)
|
||||
long dbgrep(const char *pmask,const char *fields)
|
||||
{
|
||||
DBENTRY dbentry;
|
||||
DBENTRY *pdbentry = &dbentry;
|
||||
long status;
|
||||
int nfields = 0;
|
||||
char *fieldnames = 0;
|
||||
char **papfields = 0;
|
||||
|
||||
if (!pmask || !*pmask) {
|
||||
printf("Usage: dbgrep \"pattern\"\n");
|
||||
printf("Usage: dbgrep \"pattern\" \"fields\"\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -298,20 +313,30 @@ long dbgrep(const char *pmask)
|
||||
printf("No database loaded\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fields && (*fields == '\0'))
|
||||
fields = NULL;
|
||||
if (fields) {
|
||||
fieldnames = epicsStrDup(fields);
|
||||
nfields = splitFieldsList(fieldnames, &papfields);
|
||||
}
|
||||
dbInitEntry(pdbbase, pdbentry);
|
||||
status = dbFirstRecordType(pdbentry);
|
||||
while (!status) {
|
||||
status = dbFirstRecord(pdbentry);
|
||||
while (!status) {
|
||||
char *pname = dbGetRecordName(pdbentry);
|
||||
if (epicsStrGlobMatch(pname, pmask))
|
||||
puts(pname);
|
||||
if (epicsStrGlobMatch(pname, pmask)) {
|
||||
printf("%s", pname);
|
||||
printFieldsList(pdbentry, papfields, nfields);
|
||||
}
|
||||
status = dbNextRecord(pdbentry);
|
||||
}
|
||||
status = dbNextRecordType(pdbentry);
|
||||
}
|
||||
|
||||
if (nfields > 0) {
|
||||
free((void *)papfields);
|
||||
free((void *)fieldnames);
|
||||
}
|
||||
dbFinishEntry(pdbentry);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ DBCORE_API long dbla(const char *pmask);
|
||||
/* list infos */
|
||||
DBCORE_API long dbli(const char *patern);
|
||||
/*list records with mask*/
|
||||
DBCORE_API long dbgrep(const char *pmask);
|
||||
DBCORE_API long dbgrep(const char *pmask,const char *fields);
|
||||
/*get field value*/
|
||||
DBCORE_API long dbgf(const char *pname);
|
||||
/*put field value*/
|
||||
|
||||
Reference in New Issue
Block a user