/* Perform name match against the schema. Result is stored in * match_type. */ void cnode_schema_match(struct cnode *schema, char *name, enum match_type *match_type) { switch (schema->type) { case CNODE_TYPE_KEYWORD: keyword_match(name, schema->name, match_type); break; case CNODE_TYPE_WORD: word_match(name, match_type); break; case CNODE_TYPE_IPV4: ipv4_match(name, match_type); break; case CNODE_TYPE_IPV4_PREFIX: ipv4_prefix_match(name, match_type); break; case CNODE_TYPE_IPV6: ipv6_match(name, match_type); break; case CNODE_TYPE_IPV6_PREFIX: ipv6_prefix_match(name, match_type); break; case CNODE_TYPE_MAC: mac_address_match(name, match_type); break; case CNODE_TYPE_RANGE: range_match(name, schema, match_type); break; default: *match_type = NONE_MATCH; break; } }
/* instantiate a component with overrides * tname type to instantiate, * cname name of instantiated component * loader is the module loader function for tname */ int *lp_override_inst(struct lp_block *spec, char *cname, lp_modloader_t loader, char **overrides, int overrides_len) { int c, d; struct lp_block *spec_copy; char *p1, *p2; int *result; spec_copy = copy_block(spec); for(c = 0; c < overrides_len; c += 3) { if(range_match(overrides[c], cname)) { /* overrides[c+2] could be an int, a real, a string or a list or * a block. need parser to deal with lists and blocks * reasonably so we aren't going to deal with them here */ if(!dumb_split2(overrides[c+1], &p1, &p2)) { /* descend hierarchy */ for(d = 0; d < spec_copy->params_len; d++) { if(!spec_copy->params[d]) continue; if(!strcmp(p1, spec_copy->params[d]->name)) { if(spec_copy->params[d]->v->t != BLOCK) { fprintf(stderr, "*** error: tried to recurse through non-block parameter.\n"); return 0; } else { param_override(spec_copy->params[d]->v->v.b, p2, overrides[c+2]); } } } } else { param_override(spec_copy, overrides[c+1], overrides[c+2]); } } } if(!check_types(spec_copy)) { result = loader(spec_copy, 0); } // XXX don't leak (segfaults) // destroy_block(spec_copy); return result; }
static bool range_match(char c, const char **ppat, const char *epattern) { if (*ppat == epattern) { if (c == '[') return true; else return false; } if (**ppat == '!' || **ppat == '^') { (*ppat)++; return !range_match(c, ppat, epattern); } for (;;) { if (**ppat == '\\') { if (++(*ppat) == epattern) return false; } if (**ppat == c) break; if ((*ppat)[1] == '-') { if (*ppat + 2 == epattern) return false; if (**ppat < c && c <= (*ppat)[2]) break; if ((*ppat)[2] <= c && c < **ppat) break; *ppat += 3; } else (*ppat)++; /* The test for ']' is done at the end * so that ']' can be used at the * start of the range without '\' */ if (*ppat == epattern || **ppat == ']') return false; } /* Found matching character, skip over rest * of class. */ while (**ppat != ']') { if (**ppat == '\\') (*ppat)++; /* A non-terminated character class * is ok. */ if (*ppat == epattern) break; (*ppat)++; } return true; }
int match(char *str1, char *str2) { if ((*str1 == '\0') && (*str2 == '\0')) return (1); if ((*str1 == '\0') && (*str2 == STAR)) return (match(str1, str2 + 1)); if (*str2 == HAT) return (!match(str1, str2 + 1)); if (*str2 == OPEN_BRACKET) return (range_match(str1, str2)); if ((*str1 != '\0') && ((undash(*str2) == *str1) || (*str2 == ANY))) return (match(str1 + 1, str2 + 1)); if ((*str1 != '\0') && (*str2 == STAR)) return (match(str1, str2 + 1) || match(str1 + 1, str2)); return (0); }
bool Str_Matchi(const char *string, const char *estring, const char *pattern, const char *epattern) { while (pattern != epattern) { /* Check for a "*" as the next pattern character. */ if (*pattern == '*') return star_match(string, estring, pattern, epattern); else if (string == estring) return false; /* Check for a "[" as the next pattern character. It is * followed by a list of characters that are acceptable, or * by a range (two characters separated by "-"). */ else if (*pattern == '[') { pattern++; if (!range_match(*string, &pattern, epattern)) return false; } /* '?' matches any single character, so shunt test. */ else if (*pattern != '?') { /* If the next pattern character is '\', just strip * off the '\' so we do exact matching on the * character that follows. */ if (*pattern == '\\') { if (++pattern == epattern) return false; } /* There's no special character. Just make sure that * the next characters of each string match. */ if (*pattern != *string) return false; } pattern++; string++; } if (string == estring) return true; else return false; }
static int fn_match(char *pattern, char *string, char **pend) { char c; char test; *pend = NULL; for (;;) { switch (c = *pattern++) { case '\0': /* * Ok we found an exact match */ if (*string == '\0') return(0); /* * Check if it is a prefix match */ if ((dflag == 1) || (*string != '/')) return(-1); /* * It is a prefix match, remember where the trailing * / is located */ *pend = string; return(0); case '?': if ((test = *string++) == '\0') return (-1); break; case '*': c = *pattern; /* * Collapse multiple *'s. */ while (c == '*') c = *++pattern; /* * Optimized hack for pattern with a * at the end */ if (c == '\0') return (0); /* * General case, use recursion. */ while ((test = *string) != '\0') { if (!fn_match(pattern, string, pend)) return (0); ++string; } return (-1); case '[': /* * range match */ if (((test = *string++) == '\0') || ((pattern = range_match(pattern, test)) == NULL)) return (-1); break; case '\\': default: if (c != *string++) return (-1); break; } } /* NOTREACHED */ }
int fnmatch (const char *pattern, const char *string, int flags) { char c, test; while (1) { c = *pattern++; switch (c) { case 0: return (*string == 0 ? FNM_MATCH : FNM_NOMATCH); case '?': test = *string++; if (test == 0 || (IS_SLASH(test) && (flags & FNM_FLAG_PATHNAME))) return (FNM_NOMATCH); break; case '*': c = *pattern; /* collapse multiple stars */ while (c == '*') c = *(++pattern); /* optimize for pattern with '*' at end or before '/' */ if (c == 0) { if (flags & FNM_FLAG_PATHNAME) return (find_slash(string) ? FNM_NOMATCH : FNM_MATCH); return (FNM_MATCH); } if (IS_SLASH(c) && (flags & FNM_FLAG_PATHNAME)) { string = find_slash (string); if (!string) return (FNM_NOMATCH); break; } /* general case, use recursion */ while ((test = *string) != '\0') { if (fnmatch(pattern, string, flags) == FNM_MATCH) return (FNM_MATCH); if (IS_SLASH(test) && (flags & FNM_FLAG_PATHNAME)) break; ++string; } return (FNM_NOMATCH); case '[': test = *string++; if (!test || (IS_SLASH(test) && (flags & FNM_FLAG_PATHNAME))) return (FNM_NOMATCH); pattern = range_match (pattern, test, flags & FNM_FLAG_NOCASE); if (!pattern) return (FNM_NOMATCH); break; case '\\': if (!(flags & FNM_FLAG_NOESCAPE) && pattern[1] && strchr("*?[\\", pattern[1])) { c = *pattern++; if (c == 0) { c = '\\'; --pattern; } if (c != *string++) return (FNM_NOMATCH); break; } /* FALLTHROUGH */ default: if (IS_SLASH(c) && IS_SLASH(*string)) { string++; break; } if (flags & FNM_FLAG_NOCASE) { if (TOUPPER(c) != TOUPPER(*string++)) return (FNM_NOMATCH); } else { if (c != *string++) return (FNM_NOMATCH); } break; } /* switch (c) */ } /* while (1) */ }
struct cnode * cnode_match(struct cnode *cnode, char *name) { uint32_t i; struct cnode *child; enum match_type type; if (cnode == NULL) { return NULL; } for (i = 0; i < vector_max(cnode->v); i++) { if ((child = vector_slot(cnode->v, i)) != NULL) { switch (child->type) { case CNODE_TYPE_KEYWORD: if (strcmp(child->name, name) == 0) { return child; } break; case CNODE_TYPE_WORD: return child; break; case CNODE_TYPE_IPV4: ipv4_match(name, &type); if (type == IPV4_MATCH) { return child; } break; case CNODE_TYPE_IPV4_PREFIX: ipv4_prefix_match(name, &type); if (type == IPV4_PREFIX_MATCH) { return child; } break; case CNODE_TYPE_IPV6: ipv6_match(name, &type); if (type == IPV6_MATCH) { return child; } break; case CNODE_TYPE_IPV6_PREFIX: ipv6_prefix_match(name, &type); if (type == IPV6_PREFIX_MATCH) { return child; } break; case CNODE_TYPE_MAC: mac_address_match(name, &type); if (type == MAC_ADDRESS_MATCH) { return child; } break; case CNODE_TYPE_RANGE: range_match(name, child, &type); if (type == RANGE_MATCH) { return child; } break; default: break; } } } return NULL; }