#include <stdio.h> #include <string.h> #include "externs.h" static bool is_glob_token(char c) { return((c == '?' || c == '*')); } static void add_glob(char *str, int len, char ***globs) { char buf[4096]; int i; if(!len) return; strncpy(buf, str, len); *(buf+len) = '\0'; for(i = 0;(*globs)[i];i++); /* Whole loop */ *globs = (char **)stack_realloc_tmp(*globs, sizeof(char *)*(i+2)); (*globs)[i] = stack_string_alloc(buf, 0); (*globs)[i+1] = NULL; } static void wildcard_parse(char *str, char ***globs) { char *p; *globs = (char **)stack_alloc(sizeof(char *), 0, 0); (*globs)[0] = NULL; for(p = str;*p;p++) { if(!is_glob_token(*p)) continue; add_glob(str, p-str, globs); add_glob(p, 1, globs); str = p+1; } add_glob(str, p-str, globs); } static void add_glob_arg(char *p, int len, char ***args) { char buf[4096]; int i; if(!args) return; strncpy(buf, p, len); *(buf+len) = '\0'; for(i = 0;(*args)[i];i++); /* Whole loop */ *args = (char **)stack_realloc_tmp(*args, sizeof(char *)*(i+2)); (*args)[i] = stack_string_alloc(buf, 0); (*args)[i+1] = NULL; } bool wildcard_match(char *wildcard_str, char *match_str, char ***args) { char **globs; char *q; int i; wildcard_parse(wildcard_str, &globs); if(args) { *args = (char **)stack_alloc(sizeof(char *), 0, 0); (*args)[0] = NULL; } for(i = 0;globs[i] && *match_str;i++) { switch(*(globs[i])) { case '?': add_glob_arg(match_str++, 1, args); break; case '*': if(!globs[i+1]) { add_glob_arg(match_str, strlen(match_str), args); match_str += strlen(match_str); } else { if(is_glob_token(*(globs[i+1]))) { if(!*(match_str+1)) return(0); add_glob_arg(match_str++, 1, args); } else { if(!(q = strstr(match_str+1, globs[i+1]))) return(0); add_glob_arg(match_str, q-match_str, args); match_str = q; } } break; default: if(strncmp(match_str, globs[i], strlen(globs[i]))) return(0); match_str += strlen(globs[i]); } } return((bool)(!globs[i] && !*match_str)); }