2014-git-work/cpp/aimaina/search.c

91 lines
1.8 KiB
C
Raw Normal View History

2012-08-28 23:07:07 +09:00
/*
search.c
(C)2012 B11T3074C, B11T3011K - MIT License
*/
#include <stdlib.h>
#include <string.h>
#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;
}