X-Git-Url: https://arthur.barton.de/gitweb/?a=blobdiff_plain;f=src%2Fsimple_pattern.c;h=f72a42d06e6e53c01eb3e5d4cd76637d728bd902;hb=0b3b92cdf87f4b8ddeae69a651c24891112171aa;hp=fe9e559968ef38466ad7bf177c73441b4b55a42d;hpb=83df0e7941994cb3a081af565f4b11f3c436bfe0;p=netdata.git diff --git a/src/simple_pattern.c b/src/simple_pattern.c index fe9e5599..f72a42d0 100644 --- a/src/simple_pattern.c +++ b/src/simple_pattern.c @@ -3,17 +3,17 @@ struct simple_pattern { const char *match; size_t len; - NETDATA_SIMPLE_PREFIX_MODE mode; + + SIMPLE_PREFIX_MODE mode; + char negative; struct simple_pattern *child; struct simple_pattern *next; }; -static inline struct simple_pattern *parse_pattern(const char *str, NETDATA_SIMPLE_PREFIX_MODE default_mode) { - info(">>>> PARSE: '%s'", str); - - NETDATA_SIMPLE_PREFIX_MODE mode; +static inline struct simple_pattern *parse_pattern(const char *str, SIMPLE_PREFIX_MODE default_mode) { + SIMPLE_PREFIX_MODE mode; struct simple_pattern *child = NULL; char *buf = strdupz(str); @@ -23,7 +23,7 @@ static inline struct simple_pattern *parse_pattern(const char *str, NETDATA_SIMP while(*c == '*') c++; // find the next asterisk - while(*c && *c != '*') c++ ; + while(*c && *c != '*') c++; // do we have an asterisk in the middle? if(*c == '*' && c[1] != '\0') { @@ -38,15 +38,15 @@ static inline struct simple_pattern *parse_pattern(const char *str, NETDATA_SIMP if(len >= 2 && *s == '*' && s[len - 1] == '*') { s[len - 1] = '\0'; s++; - mode = NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING; + mode = SIMPLE_PATTERN_SUBSTRING; } else if(len >= 1 && *s == '*') { s++; - mode = NETDATA_SIMPLE_PATTERN_MODE_SUFFIX; + mode = SIMPLE_PATTERN_SUFFIX; } else if(len >= 1 && s[len - 1] == '*') { s[len - 1] = '\0'; - mode = NETDATA_SIMPLE_PATTERN_MODE_PREFIX; + mode = SIMPLE_PATTERN_PREFIX; } else mode = default_mode; @@ -54,32 +54,22 @@ static inline struct simple_pattern *parse_pattern(const char *str, NETDATA_SIMP // allocate the structure struct simple_pattern *m = callocz(1, sizeof(struct simple_pattern)); if(*s) { - m->match = strdup(s); + m->match = strdupz(s); m->len = strlen(m->match); m->mode = mode; } else { - m->mode = NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING; + m->mode = SIMPLE_PATTERN_SUBSTRING; } m->child = child; - free(buf); - - info("PATTERN '%s' is composed by", str); - struct simple_pattern *p; - for(p = m; p ; p = p->child) - info(">>>> COMPONENT: '%s%s%s' (len %zu type %u)", - (p->mode == NETDATA_SIMPLE_PATTERN_MODE_SUFFIX || p->mode == NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING)?"*":"", - p->match, - (p->mode == NETDATA_SIMPLE_PATTERN_MODE_PREFIX || p->mode == NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING)?"*":"", - p->len, - p->mode); + freez(buf); return m; } -NETDATA_SIMPLE_PATTERN *netdata_simple_pattern_list_create(const char *list, NETDATA_SIMPLE_PREFIX_MODE default_mode) { +SIMPLE_PATTERN *simple_pattern_create(const char *list, SIMPLE_PREFIX_MODE default_mode) { struct simple_pattern *root = NULL, *last = NULL; if(unlikely(!list || !*list)) return root; @@ -89,9 +79,16 @@ NETDATA_SIMPLE_PATTERN *netdata_simple_pattern_list_create(const char *list, NET char *s = buf; while(s && *s) { + char negative = 0; + // skip all spaces while(isspace(*s)) s++; + if(*s == '!') { + negative = 1; + s++; + } + // empty string if(unlikely(!*s)) break; @@ -108,6 +105,7 @@ NETDATA_SIMPLE_PATTERN *netdata_simple_pattern_list_create(const char *list, NET *c = '\0'; struct simple_pattern *m = parse_pattern(s, default_mode); + m->negative = negative; if(likely(n)) *c = ' '; @@ -124,22 +122,16 @@ NETDATA_SIMPLE_PATTERN *netdata_simple_pattern_list_create(const char *list, NET } } - free(buf); - return (NETDATA_SIMPLE_PATTERN *)root; + freez(buf); + return (SIMPLE_PATTERN *)root; } static inline int match_pattern(struct simple_pattern *m, const char *str, size_t len) { - info("CHECK string '%s' (len %zu) with pattern '%s%s%s' (len %zu type %u)", str, len, - (m->mode == NETDATA_SIMPLE_PATTERN_MODE_SUFFIX || m->mode == NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING)?"*":"", - m->match, - (m->mode == NETDATA_SIMPLE_PATTERN_MODE_PREFIX || m->mode == NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING)?"*":"", - m->len, m->mode); - char *s; if(m->len <= len) { switch(m->mode) { - case NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING: + case SIMPLE_PATTERN_SUBSTRING: if(!m->len) return 1; if((s = strstr(str, m->match))) { if(!m->child) return 1; @@ -147,21 +139,21 @@ static inline int match_pattern(struct simple_pattern *m, const char *str, size_ } break; - case NETDATA_SIMPLE_PATTERN_MODE_PREFIX: + case SIMPLE_PATTERN_PREFIX: if(unlikely(strncmp(str, m->match, m->len) == 0)) { if(!m->child) return 1; return match_pattern(m->child, &str[m->len], len - m->len); } break; - case NETDATA_SIMPLE_PATTERN_MODE_SUFFIX: + case SIMPLE_PATTERN_SUFFIX: if(unlikely(strcmp(&str[len - m->len], m->match) == 0)) { if(!m->child) return 1; return 0; } break; - case NETDATA_SIMPLE_PATTERN_MODE_EXACT: + case SIMPLE_PATTERN_EXACT: default: if(unlikely(strcmp(str, m->match) == 0)) { if(!m->child) return 1; @@ -174,31 +166,32 @@ static inline int match_pattern(struct simple_pattern *m, const char *str, size_ return 0; } -int netdata_simple_pattern_list_matches(NETDATA_SIMPLE_PATTERN *list, const char *str) { +int simple_pattern_matches(SIMPLE_PATTERN *list, const char *str) { struct simple_pattern *m, *root = (struct simple_pattern *)list; - if(unlikely(!root)) return 0; + if(unlikely(!root || !str || !*str)) return 0; size_t len = strlen(str); for(m = root; m ; m = m->next) if(match_pattern(m, str, len)) { - info("MATCHED string '%s' (len %zu) with pattern '%s%s%s' (len %zu type %u)", str, len, - (m->mode == NETDATA_SIMPLE_PATTERN_MODE_SUFFIX || m->mode == NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING)?"*":"", - m->match, - (m->mode == NETDATA_SIMPLE_PATTERN_MODE_PREFIX || m->mode == NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING)?"*":"", - m->len, m->mode); - - struct simple_pattern *p; - for(p = m; p ; p = p->child) - info(">>>> MATCHED COMPONENT: '%s%s%s' (len %zu type %u)", - (p->mode == NETDATA_SIMPLE_PATTERN_MODE_SUFFIX || p->mode == NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING)?"*":"", - p->match, - (p->mode == NETDATA_SIMPLE_PATTERN_MODE_PREFIX || p->mode == NETDATA_SIMPLE_PATTERN_MODE_SUBSTRING)?"*":"", - p->len, - p->mode); - + if(m->negative) return 0; return 1; } return 0; } + +static inline void free_pattern(struct simple_pattern *m) { + if(!m) return; + + free_pattern(m->child); + free_pattern(m->next); + freez((void *)m->match); + freez(m); +} + +void simple_pattern_free(SIMPLE_PATTERN *list) { + if(!list) return; + + free_pattern(((struct simple_pattern *)list)); +}