Search with regex

main
cel 5 years ago
parent 6092f321dd
commit b5c2984c6c
Signed by: cel
GPG Key ID: C28D95BB012367EA

@ -7,6 +7,7 @@
#include <dirent.h> #include <dirent.h>
#include <fcntl.h> #include <fcntl.h>
#include <limits.h> #include <limits.h>
#include <regex.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
@ -66,7 +67,8 @@ struct http_request {
struct zet_search { struct zet_search {
DIR *dir; DIR *dir;
const char *id; const char *id;
char *query; regex_t regex;
bool has_regex;
}; };
struct zet_mtime { struct zet_mtime {
@ -335,7 +337,7 @@ static int zet_links_to(const char *id_from, const char *id_to) {
return rc; return rc;
} }
static int zet_matches_query(const char *id, const char *query) { static int zet_matches_regex(const char *id, regex_t *regex) {
char path_buf[_POSIX_PATH_MAX]; char path_buf[_POSIX_PATH_MAX];
ssize_t sz = snprintf(path_buf, sizeof(path_buf), "%s/%s", zet_dir, id); ssize_t sz = snprintf(path_buf, sizeof(path_buf), "%s/%s", zet_dir, id);
if (sz < 0 || (size_t)sz >= sizeof(path_buf)) return -1; if (sz < 0 || (size_t)sz >= sizeof(path_buf)) return -1;
@ -344,25 +346,45 @@ static int zet_matches_query(const char *id, const char *query) {
if (note_fd < 0) return -1; if (note_fd < 0) return -1;
char *text = read_full(note_fd); char *text = read_full(note_fd);
bool found = strcasestr(text, query) != NULL; bool found = regexec(regex, text, 0, NULL, 0) == 0;
free(text); free(text);
return found ? 1 : 0; return found ? 1 : 0;
} }
static int zet_search_init_query(struct zet_search *zs, const char *query) {
int rc = regcomp(&zs->regex, query, REG_NOSUB | REG_EXTENDED | REG_ICASE);
if (rc != 0) {
char errbuf[LINE_MAX];
size_t sz = regerror(rc, &zs->regex, errbuf, sizeof(errbuf));
if (sz > sizeof(errbuf)-1) {
errbuf[sizeof(errbuf)-2] = '.';
errbuf[sizeof(errbuf)-3] = '.';
errbuf[sizeof(errbuf)-4] = '.';
}
warnx("regex: %s", errbuf);
return -1;
}
return 0;
}
static int zet_search_start(struct zet_search *zs, const char *id, char *query) { static int zet_search_start(struct zet_search *zs, const char *id, char *query) {
zs->dir = opendir(zet_dir); zs->dir = opendir(zet_dir);
if (zs->dir == NULL) return -1; if (zs->dir == NULL) return -1;
zs->id = id; zs->id = id;
zs->query = query; if (query != NULL) {
zs->has_regex = true;
return zet_search_init_query(zs, query);
} else {
zs->has_regex = false;
return 0; return 0;
} }
}
static int zet_search_next(struct zet_search *zs, const char **idp) { static int zet_search_next(struct zet_search *zs, const char **idp) {
int rc; int rc;
struct dirent *ent; struct dirent *ent;
const char *id; const char *id;
const char *dest_id = zs->id; const char *dest_id = zs->id;
const char *query = zs->query;
while (1) { while (1) {
errno = 0; errno = 0;
ent = readdir(zs->dir); ent = readdir(zs->dir);
@ -379,8 +401,8 @@ static int zet_search_next(struct zet_search *zs, const char **idp) {
if (rc < 0) return -1; if (rc < 0) return -1;
if (rc != 1) continue; if (rc != 1) continue;
} }
if (query != NULL) { if (zs->has_regex) {
rc = zet_matches_query(id, query); rc = zet_matches_regex(id, &zs->regex);
if (rc < 0) return -1; if (rc < 0) return -1;
if (rc != 1) continue; if (rc != 1) continue;
} }
@ -391,6 +413,7 @@ static int zet_search_next(struct zet_search *zs, const char **idp) {
} }
static int zet_search_close(struct zet_search *sz) { static int zet_search_close(struct zet_search *sz) {
regfree(&sz->regex);
return closedir(sz->dir); return closedir(sz->dir);
} }

Loading…
Cancel
Save