+static bool lu_part_matches(part_match_t const *match, /* {{{ */
+ char const *str) {
+ if (match->is_regex) {
+ /* Short cut popular catch-all regex. */
+ if (strcmp(".*", match->str) == 0)
+ return true;
+
+ int status = regexec(&match->regex, str,
+ /* nmatch = */ 0, /* pmatch = */ NULL,
+ /* flags = */ 0);
+ if (status == 0)
+ return true;
+ else
+ return false;
+ } else if (strcmp(match->str, str) == 0)
+ return true;
+ else
+ return false;
+} /* }}} bool lu_part_matches */
+
+static int lu_copy_ident_to_match_part(part_match_t *match_part, /* {{{ */
+ char const *ident_part) {
+ size_t len = strlen(ident_part);
+ int status;
+
+ if ((len < 3) || (ident_part[0] != '/') || (ident_part[len - 1] != '/')) {
+ sstrncpy(match_part->str, ident_part, sizeof(match_part->str));
+ match_part->is_regex = false;
+ return 0;
+ }
+
+ /* Copy string without the leading slash. */
+ sstrncpy(match_part->str, ident_part + 1, sizeof(match_part->str));
+ assert(sizeof(match_part->str) > len);
+ /* strip trailing slash */
+ match_part->str[len - 2] = 0;
+
+ status = regcomp(&match_part->regex, match_part->str,
+ /* flags = */ REG_EXTENDED);
+ if (status != 0) {
+ char errbuf[1024];
+ regerror(status, &match_part->regex, errbuf, sizeof(errbuf));
+ ERROR("utils_vl_lookup: Compiling regular expression \"%s\" failed: %s",
+ match_part->str, errbuf);
+ return EINVAL;
+ }
+ match_part->is_regex = true;
+
+ return 0;
+} /* }}} int lu_copy_ident_to_match_part */
+
+static int lu_copy_ident_to_match(identifier_match_t *match, /* {{{ */
+ lookup_identifier_t const *ident,
+ unsigned int group_by) {
+ memset(match, 0, sizeof(*match));
+
+ match->group_by = group_by;
+
+#define COPY_FIELD(field) \
+ do { \
+ int status = lu_copy_ident_to_match_part(&match->field, ident->field); \
+ if (status != 0) \
+ return status; \
+ } while (0)
+
+ COPY_FIELD(host);
+ COPY_FIELD(plugin);
+ COPY_FIELD(plugin_instance);
+ COPY_FIELD(type);
+ COPY_FIELD(type_instance);
+
+#undef COPY_FIELD
+
+ return 0;
+} /* }}} int lu_copy_ident_to_match */
+
+/* user_class->lock must be held when calling this function */
+static void *lu_create_user_obj(lookup_t *obj, /* {{{ */
+ data_set_t const *ds, value_list_t const *vl,
+ user_class_t *user_class) {