/* search.c 検索するための関数群 (C)2012 B11T3074C, B11T3011K - MIT License */ #include #include #include "search.h" // stringにpatternが含まれていれば1、それ以外で0を返す int match(char *pattern, const char *string){ const char *p; size_t pat_len = strlen(pattern); for(p=string; *p; p++){ if(!strncmp(pattern, p, pat_len)){ return 1; } } return 0; } // 破壊的AND-match : "pattern1 pattern2" => "pattern1" AND "pattern2" int andmatch(char *pattern, const char *string){ char *p; int match_flag = 1; for(p = strtok(pattern, " "); p != NULL; p = strtok(NULL, " ")){ match_flag &= match(p, string); } return match_flag; } // 破壊的OR-match : "pattern1|pattern2" => "pattern1" OR "pattern2" int ormatch(char *pattern, const char *string){ char *p; int match_flag = 0; for(p = strtok(pattern, "|"); p != NULL; p = strtok(NULL, "|")){ match_flag |= match(p, string); } return match_flag; } // 再帰可能なstrtok char *strtok_r(char *str, const char *delim, char **saveptr){ size_t len; char *head; if(str == NULL){ head = *saveptr; }else{ head = str; } len = strcspn(head, delim); if(len == 0){ head += strspn(head, delim); len = strcspn(head, delim); } if(*head == '\0'){ return NULL; } *saveptr = head + len + strspn(head + len, delim); *(head + len) = '\0'; return head; } // Smart-match : 破壊的でない // "pattern1 pattern2|pattern3" => "pattern1" AND ("pattern2" OR "pattern3") int smatch(const char *pattern, const char *string){ char *p; char *nextp; int match_flag; char *tmp; tmp = strdup(pattern); match_flag = 1; for(p = strtok_r(tmp, " ", &nextp); p != NULL; p = strtok_r(NULL, " ", &nextp)){ match_flag &= ormatch(p, string); if(match_flag == 0) break; } free(tmp); return match_flag; }