#include <u.h>
#include <libc.h>
#include <regexp.h>
#include <fcall.h>
#include <String.h>
#include "common.h"
#include "debug.h"
#include "string.h"
#include "filepath.h"
#include "rule.h"
#include "filedirrule.h"
#include "regexrule.h"
enum
{
DEBUG_REGEXRULE = false,
DEBUG_FILEREGEXRULE = false,
DEBUG_DIRREGEXRULE = false
};
typedef struct RegexRule
{
Rule;
Reprog *regex;
} RegexRule;
Rule *regexrule_new(char *regex, char *root, RuleOperations *ops)
{
RegexRule *result;
char buf[RULE_MAXNAMELEN];
assert_valid(root);
assert_valid(ops);
result = (RegexRule *)emalloc_fs(sizeof(*result));
result->ops = ops;
result->root = estrdup_fs(root);
snprint(buf, sizeof(buf), "regex<%s>", regex);
result->name = estrdup_fs(buf);
result->regex = regcomp(regex);
return result;
}
static void regexrule_free(Rule *rule)
{
RegexRule *self = (RegexRule *)rule;
free(self->name);
self->name = nil;
free(self->regex);
self->regex = nil;
free(self);
}
static bool regexrule_matches(RegexRule *self, char *path)
{
NOISE(DEBUG_REGEXRULE, "regexrule_matches checking against: %s", path);
return regexec(self->regex, path, nil, 0) == 1;
}
static bool regexrule_contains(Rule *rule, char *path, int, ulong)
{
RegexRule *self = (RegexRule *)rule;
return regexrule_matches(self, path);
}
bool regexrule_issatisfy(Rule *rule, char *path, Dir *)
{
RegexRule *self = (RegexRule *)rule;
return regexrule_matches(self, path);
}
static RuleOperations regexops =
{
.free = regexrule_free,
.issatisfy = regexrule_issatisfy,
.contains = regexrule_contains
};
Rule *regexrule_parse(char *rule, char *setting, char *path)
{
assert_valid(rule);
assert_valid(setting);
assert_valid(path);
if(strcmp(rule, "regex") != 0)
{
return nil;
}
INFO(DEBUG_REGEXRULE, "parsed regex rule with path: %s regex: %s",
path, setting);
return regexrule_new(setting, path, ®exops);
}
typedef struct FileDirRegexRule
{
FileDirRule;
Reprog *regex;
} FileDirRegexRule;
Rule *filedirregexrule_new(char *regex, char *root,
RuleOperations *ops, FileDirRuleOperations *fdops, char *name)
{
FileDirRegexRule *result;
char buf[RULE_MAXNAMELEN];
assert_valid(root);
assert_valid(ops);
assert_valid(fdops);
result = (FileDirRegexRule *)emalloc_fs(sizeof(*result));
result->ops = ops;
result->root = estrdup_fs(root);
snprint(buf, sizeof(buf), "%s<%s>", name, regex);
result->name = estrdup_fs(buf);
result->fdops = fdops;
result->regex = regcomp(regex);
return result;
}
static void filedirregexrule_free(Rule *rule)
{
FileDirRegexRule *self = (FileDirRegexRule *)rule;
free(self->name);
self->name = nil;
free(self->regex);
self->regex = nil;
free(self);
}
static bool filedirregexrule_contains(Rule *rule, char *name)
{
bool result;
FileDirRegexRule *self = (FileDirRegexRule *)rule;
result = regexec(self->regex, name, nil, 0) == 1;
NOISE(DEBUG_REGEXRULE,
"filedirregexrule_contains checking against: %s result: %d", name, result);
return result;
}
static bool fileregexrule_contains(FileDirRule *rule, char *name);
static RuleOperations fileregexops =
{
.free = filedirregexrule_free,
.issatisfy = filedirrule_file_issatisfy,
.contains = filedirrule_contains
};
static FileDirRuleOperations fileregexfdops =
{
.contains_file = fileregexrule_contains,
.contains_dir = filedirrule_contains_true
};
static bool fileregexrule_contains(FileDirRule *rule, char *name)
{
char *filename;
filename = string_after_last(name, '/');
if(filename == nil)
{
filename = name;
}
return filedirregexrule_contains(rule, filename);
}
Rule *fileregexrule_parse(char *rule, char *setting, char *path)
{
assert_valid(rule);
assert_valid(setting);
assert_valid(path);
if(strcmp(rule, "fregex") != 0)
{
return nil;
}
INFO(DEBUG_FILEREGEXRULE, "parsed fregex rule with path: %s regex: %s",
path, setting);
return filedirregexrule_new(setting, path, &fileregexops, &fileregexfdops,
"fregex");
}
static bool dirregexrule_contains(FileDirRule *rule, char *name);
static RuleOperations dirregexops =
{
.free = filedirregexrule_free,
.issatisfy = filedirrule_dir_issatisfy,
.contains = filedirrule_contains
};
static FileDirRuleOperations dirregexfdops =
{
.contains_file = filedirrule_contains_false,
.contains_dir = dirregexrule_contains
};
static bool dirregexrule_contains(FileDirRule *rule, char *name)
{
bool result;
String *dirname;
dirname = s_copy(name);
filepath_remove_last(dirname);
result = filedirregexrule_contains(rule, s_to_c(dirname));
s_free(dirname);
return result;
}
Rule *dirregexrule_parse(char *rule, char *setting, char *path)
{
assert_valid(rule);
assert_valid(setting);
assert_valid(path);
if(strcmp(rule, "dregex") != 0)
{
return nil;
}
INFO(DEBUG_DIRREGEXRULE, "parsed dregex rule with path: %s regex: %s",
path, setting);
return filedirregexrule_new(setting, path, &dirregexops, &dirregexfdops,
"dregex");
}
|