diff options
author | aiju <devnull@localhost> | 2018-12-13 10:42:49 +0000 |
---|---|---|
committer | aiju <devnull@localhost> | 2018-12-13 10:42:49 +0000 |
commit | c7304ea03caf68cf035d14f50f6e24e0c16ccdfe (patch) | |
tree | f4b5e8047078c41caa0d98cc0ea3d5012c4d17f9 /sys/src/libdtracy | |
parent | dae5a44111dfb21a714824a5cec2abee4f9f9080 (diff) |
dtracy: get rid of DTName struct, support more than three parts in a probe name, wildcard matching
Diffstat (limited to 'sys/src/libdtracy')
-rw-r--r-- | sys/src/libdtracy/chan.c | 50 | ||||
-rw-r--r-- | sys/src/libdtracy/prov.c | 126 |
2 files changed, 114 insertions, 62 deletions
diff --git a/sys/src/libdtracy/chan.c b/sys/src/libdtracy/chan.c index c29f24eb4..b926c965e 100644 --- a/sys/src/libdtracy/chan.c +++ b/sys/src/libdtracy/chan.c @@ -81,7 +81,7 @@ dtcfree(DTChan *ch) } int -dtcaddgr(DTChan *c, DTName name, DTActGr *gr) +dtcaddgr(DTChan *c, char *name, DTActGr *gr) { DTProbe **l, *p; DTEnab *ep; @@ -92,6 +92,11 @@ dtcaddgr(DTChan *c, DTName name, DTActGr *gr) gr->chan = c; nl = dtpmatch(name, &l); + if(nl == 0){ + dtfree(l); + werrstr("no match for %s", name); + return -1; + } n = 0; for(i = 0; i < nl; i++){ p = l[i]; @@ -118,53 +123,14 @@ dtcaddgr(DTChan *c, DTName name, DTActGr *gr) return n; } -static int -dtnamesplit(char *s, DTName *rp) -{ - char *p; - - p = strchr(s, ':'); - if(p == nil) return -1; - rp->provider = dtmalloc(p - s + 1); - memcpy(rp->provider, s, p - s); - s = p + 1; - p = strchr(s, ':'); - if(p == nil){ - free(rp->provider); - rp->provider = nil; - return -1; - } - rp->function = dtmalloc(p - s + 1); - memcpy(rp->function, s, p - s); - s = p + 1; - if(strchr(s, ':') != nil){ - free(rp->provider); - rp->provider = nil; - free(rp->function); - rp->function = nil; - return -1; - } - rp->name = dtstrdup(s); - return 0; -} - int dtcaddcl(DTChan *c, DTClause *cl) { - DTName n; int i, rc; rc = 0; - for(i = 0; i < cl->nprob; i++){ - if(dtnamesplit(cl->probs[i], &n) < 0){ - werrstr("invalid probe name '%s'", cl->probs[i]); - return -1; - } - rc += dtcaddgr(c, n, cl->gr); - dtfree(n.provider); - dtfree(n.function); - dtfree(n.name); - } + for(i = 0; i < cl->nprob; i++) + rc += dtcaddgr(c, cl->probs[i], cl->gr); return rc; } diff --git a/sys/src/libdtracy/prov.c b/sys/src/libdtracy/prov.c index 8becbc756..c9e4f822c 100644 --- a/sys/src/libdtracy/prov.c +++ b/sys/src/libdtracy/prov.c @@ -14,14 +14,12 @@ dtstrdup(char *n) } DTProbe * -dtpnew(DTName name, DTProvider *prov, void *aux) +dtpnew(char *name, DTProvider *prov, void *aux) { DTProbe *p, **pp; p = dtmalloc(sizeof(DTProbe)); - p->provider = dtstrdup(name.provider); - p->function = dtstrdup(name.function); - p->name = dtstrdup(name.name); + p->name = dtstrdup(name); p->prov = prov; p->aux = aux; p->enablist.probnext = p->enablist.probprev = &p->enablist; @@ -31,46 +29,134 @@ dtpnew(DTName name, DTProvider *prov, void *aux) return p; } +/* does the pattern match at most one probe (or provider if provonly)? */ +static int +patunique(char *pat, int provonly) +{ + for(;; pat++) + switch(*pat){ + case ':': + if(provonly){ + case 0: + return 1; + } + break; + case '?': + case '*': + return 0; + } +} + +static char * +partmatch(char *pat, char *str, int provonly) +{ + for(;; pat++, str++){ + if(*pat == '*') + return pat; + if(*pat != *str && (*pat != '?' || *str == ':') && (!provonly || *pat != ':' || *str != 0)) + return nil; + if(*pat == 0 || *pat == ':' && provonly) + return (void*)-1; + } +} + +/* + do a wildcard match with * and ?, but don't match : against a wildcard + if provonly, stop at the first : + + replacing empty parts with * is done in user space +*/ int -dtstrmatch(char *a, char *b) +dtnamematch(char *pat, char *str, int provonly) { - if(a == nil || *a == 0) return 1; - if(b == nil) return 0; - return strcmp(a, b) == 0; + char *patp, *strp, *p; + + patp = partmatch(pat, str, provonly); + if(patp == nil) return 0; + if(patp == (void*)-1) return 1; + /* reached a * */ + strp = str + (patp - pat); + patp++; + for(;;){ + /* try the rest of the pattern against each position */ + p = partmatch(patp, strp, provonly); + if(p == nil){ + if(*strp == 0 || *strp == ':') return 0; + strp++; + continue; + } + if(p == (void*)-1) + return 1; + /* reached another * */ + strp += p - patp; + patp = p + 1; + } } int -dtpmatch(DTName name, DTProbe ***ret) +dtpmatch(char *name, DTProbe ***ret) { DTProbe **l; int nl; DTProvider **provp, *prov; DTProbe **pp, *p; + int unique, uniqueprov; l = nil; nl = 0; + unique = patunique(name, 0); + uniqueprov = patunique(name, 1); for(provp = dtproviders; prov = *provp, prov != nil; provp++){ - if(!dtstrmatch(name.provider, prov->name)) + if(!dtnamematch(name, prov->name, 1)) continue; - for(pp = &prov->probes; p = *pp, p != nil; pp = &p->provnext) - if(dtstrmatch(name.function, p->function) && dtstrmatch(name.name, p->name)){ + if(!prov->provided){ + prov->provided = 1; + prov->provide(prov); + } + for(pp = &prov->probes; p = *pp, p != nil; pp = &p->provnext){ + if(dtnamematch(name, p->name, 0)){ if(ret != nil){ l = dtrealloc(l, (nl + 1) * sizeof(DTProbe *)); l[nl] = p; } nl++; + if(unique) goto out; } - prov->provide(prov, name); - for(; p = *pp, p != nil; pp = &p->provnext) - if(dtstrmatch(name.function, p->function) && dtstrmatch(name.name, p->name)){ - if(ret != nil){ - l = dtrealloc(l, (nl + 1) * sizeof(DTProbe *)); - l[nl] = p; - } - nl++; + } + if(uniqueprov) goto out; + } +out: + if(ret != nil) + *ret = l; + return nl; +} + +int +dtplist(DTProbe ***ret) +{ + DTProbe **l; + int nl; + DTProvider **provp, *prov; + DTProbe **pp, *p; + + l = nil; + nl = 0; + for(provp = dtproviders; prov = *provp, prov != nil; provp++){ + if(!prov->provided){ + prov->provided = 1; + prov->provide(prov); + } + for(pp = &prov->probes; p = *pp, p != nil; pp = &p->provnext){ + if(ret != nil){ + l = dtrealloc(l, (nl + 1) * sizeof(DTProbe *)); + l[nl] = p; } + nl++; + } } if(ret != nil) *ret = l; + else + dtfree(l); return nl; } |