Plan 9 from Bell Labs’s /usr/web/sources/contrib/de0u/root/sys/src/cmd/divergefs/regexrule.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#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, &regexops);
}



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");
}




Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.