summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom St Denis <tom.stdenis@amd.com>2019-02-08 09:51:49 -0500
committerTom St Denis <tom.stdenis@amd.com>2019-02-08 09:54:03 -0500
commit48f68b1eb172d436720b9e35fec8fa187fc3fdf5 (patch)
treef1f5bf02226d889417f49a3741bf6833e39a5d4d
parentbdb71cce3c30982b2bd2dba1e92bbcd4be49517c (diff)
Change wildcard search to use more regex friendly version of '*' and '?'
Now the '*' and '?' characters can be used to perform more traditional regex style searches. (minor indentation updates and documentation updates by Tom St Denis) Patch-contributed-by: Marcio Jose Moraes de Andrade <Marcio.Andrade@amd.com> Signed-off-by: Tom St Denis <tom.stdenis@amd.com>
-rw-r--r--doc/sphinx/source/libregister_access.rst6
-rw-r--r--src/lib/find_reg.c62
-rw-r--r--src/umr.h4
3 files changed, 50 insertions, 22 deletions
diff --git a/doc/sphinx/source/libregister_access.rst b/doc/sphinx/source/libregister_access.rst
index 2cfe350..e4dd12e 100644
--- a/doc/sphinx/source/libregister_access.rst
+++ b/doc/sphinx/source/libregister_access.rst
@@ -107,8 +107,8 @@ If the "ip" pointer is NULL then it will match any IP block. If the "ip" pointe
not NULL then it will be used for a partial match. For instance,
you can use "gfx" to search for any block starting with "gfx".
-If the string pointed to by "reg" is terminated with a '*' it means it should
-perform a partial match, otherwise it will perform a strict match.
+If the string pointed to by "reg" contains a '*' or '?' it will perform
+partial matches on strings, otherwise it performs an exact match.
The umr_find_reg_wild_next() function returns the following structure:
@@ -131,7 +131,7 @@ This example searches for registers containing "RB_BASE" in any block:
struct umr_reg *reg;
struct umr_find_reg_iter_result res;
- iter = umr_find_reg_wild_first(asic, NULL, "RB_BASE*");
+ iter = umr_find_reg_wild_first(asic, NULL, "*RB_BASE*");
res = umr_find_reg_wild_next(iter);
while (res.reg) {
printf("%s.%s\n", res.ip->ipname, res.reg->regname);
diff --git a/src/lib/find_reg.c b/src/lib/find_reg.c
index bb7fe76..e89187b 100644
--- a/src/lib/find_reg.c
+++ b/src/lib/find_reg.c
@@ -24,10 +24,44 @@
*/
#include "umr.h"
-struct umr_find_reg_iter *umr_find_reg_wild_first(struct umr_asic *asic, char *ip, char *reg)
+static int expression_matches(const char* str, const char* pattern)
+{
+ const char *cp = NULL, *mp = NULL;
+
+ while ((*str) && (*pattern != '*')) {
+ if ((*pattern != *str) && (*pattern != '?')) {
+ return 0;
+ }
+ str++;
+ pattern++;
+ }
+
+ while (*str) {
+ if (*pattern == '*') {
+ if (!*++pattern) {
+ return 1;
+ }
+ mp = pattern;
+ cp = str + 1;
+ } else if ((*pattern == *str) || (*pattern == '?')) {
+ pattern++;
+ str++;
+ } else {
+ pattern = mp;
+ str = cp++;
+ }
+ }
+
+ while (*pattern == '*') {
+ pattern++;
+ }
+ return !*pattern;
+}
+
+
+struct umr_find_reg_iter *umr_find_reg_wild_first(struct umr_asic *asic, const char *ip, const char *reg)
{
struct umr_find_reg_iter *iter;
- char *p;
iter = calloc(1, sizeof(*iter));
if (!iter) {
@@ -37,10 +71,7 @@ struct umr_find_reg_iter *umr_find_reg_wild_first(struct umr_asic *asic, char *i
iter->asic = asic;
iter->ip = ip ? strdup(ip) : NULL;
iter->reg = strdup(reg);
- if ((p = strstr(iter->reg, "*"))) {
- iter->reg_many = 1;
- *p = 0; // trim * off
- }
+
iter->ip_i = -1;
iter->reg_i = -1;
return iter;
@@ -53,8 +84,10 @@ struct umr_find_reg_iter_result umr_find_reg_wild_next(struct umr_find_reg_iter
// if reg_i == -1 find the next IP block
if (iter->reg_i == -1) {
++(iter->ip_i);
- while (iter->ip && iter->ip_i < iter->asic->no_blocks && !strstr(iter->asic->blocks[iter->ip_i]->ipname, iter->ip))
- ++(iter->ip_i);
+ while ( (iter->ip_i < iter->asic->no_blocks) &&
+ (iter->ip && !expression_matches(iter->asic->blocks[iter->ip_i]->ipname, iter->ip))) {
+ ++(iter->ip_i);
+ }
// no more blocks
if (iter->ip_i >= iter->asic->no_blocks) {
@@ -66,17 +99,12 @@ struct umr_find_reg_iter_result umr_find_reg_wild_next(struct umr_find_reg_iter
return res;
}
+ // start search inside block from the first register
iter->reg_i = 0;
}
while (iter->reg_i < iter->asic->blocks[iter->ip_i]->no_regs) {
- if (iter->reg_many && strstr(iter->asic->blocks[iter->ip_i]->regs[iter->reg_i].regname, iter->reg)) {
- res.reg = &iter->asic->blocks[iter->ip_i]->regs[iter->reg_i++];
- res.ip = iter->asic->blocks[iter->ip_i];
- return res;
- }
-
- if (!strcmp(iter->asic->blocks[iter->ip_i]->regs[iter->reg_i].regname, iter->reg)) {
+ if (expression_matches(iter->asic->blocks[iter->ip_i]->regs[iter->reg_i].regname, iter->reg)) {
res.reg = &iter->asic->blocks[iter->ip_i]->regs[iter->reg_i++];
res.ip = iter->asic->blocks[iter->ip_i];
return res;
@@ -84,7 +112,7 @@ struct umr_find_reg_iter_result umr_find_reg_wild_next(struct umr_find_reg_iter
++(iter->reg_i);
}
- // no match go to next
+ // no match go to next block
iter->reg_i = -1;
}
}
@@ -94,7 +122,7 @@ struct umr_find_reg_iter_result umr_find_reg_wild_next(struct umr_find_reg_iter
*
* Returns the offset of the register if found or 0xFFFFFFFF if not.
*/
-uint32_t umr_find_reg(struct umr_asic *asic, char *regname)
+uint32_t umr_find_reg(struct umr_asic *asic, const char *regname)
{
int i, j;
diff --git a/src/umr.h b/src/umr.h
index b17086e..07e49b1 100644
--- a/src/umr.h
+++ b/src/umr.h
@@ -632,10 +632,10 @@ int umr_read_sensor(struct umr_asic *asic, int sensor, void *dst, int *size);
int umr_create_mmio_accel(struct umr_asic *asic);
// find the word address of a register
-uint32_t umr_find_reg(struct umr_asic *asic, char *regname);
+uint32_t umr_find_reg(struct umr_asic *asic, const char *regname);
// wildcard searches
-struct umr_find_reg_iter *umr_find_reg_wild_first(struct umr_asic *asic, char *ip, char *reg);
+struct umr_find_reg_iter *umr_find_reg_wild_first(struct umr_asic *asic, const char *ip, const char *reg);
struct umr_find_reg_iter_result umr_find_reg_wild_next(struct umr_find_reg_iter *iter);