Example #1
0
static int trie_fnmatch_f(sd_hwdb *hwdb, const struct trie_node_f *node, size_t p,
                          struct linebuf *buf, const char *search) {
        size_t len;
        size_t i;
        const char *prefix;
        int err;

        prefix = trie_string(hwdb, node->prefix_off);
        len = strlen(prefix + p);
        linebuf_add(buf, prefix + p, len);

        for (i = 0; i < node->children_count; i++) {
                const struct trie_child_entry_f *child = &trie_node_children(hwdb, node)[i];

                linebuf_add_char(buf, child->c);
                err = trie_fnmatch_f(hwdb, trie_node_from_off(hwdb, child->child_off), 0, buf, search);
                if (err < 0)
                        return err;
                linebuf_rem_char(buf);
        }

        if (le64toh(node->values_count) && fnmatch(linebuf_get(buf), search, 0) == 0)
                for (i = 0; i < le64toh(node->values_count); i++) {
                        err = hwdb_add_property(hwdb, trie_string(hwdb, trie_node_values(hwdb, node)[i].key_off),
                                                trie_string(hwdb, trie_node_values(hwdb, node)[i].value_off));
                        if (err < 0)
                                return err;
                }

        linebuf_rem(buf, len);
        return 0;
}
Example #2
0
static int
trie_search_f (sd_hwdb * hwdb, const char *search)
{
  struct linebuf buf;
  const struct trie_node_f *node;
  size_t i = 0;
  int err;

  linebuf_init (&buf);

  node = trie_node_from_off (hwdb, hwdb->head->nodes_root_off);
  while (node)
    {
      const struct trie_node_f *child;
      size_t p = 0;

      if (node->prefix_off)
	{
	  uint8_t c;

	  for (; (c = trie_string (hwdb, node->prefix_off)[p]); p++)
	    {
	      if (c == '*' || c == '?' || c == '[')
		return trie_fnmatch_f (hwdb, node, p, &buf, search + i + p);
	      if (c != search[i + p])
		return 0;
	    }
	  i += p;
	}

      child = node_lookup_f (hwdb, node, '*');
      if (child)
	{
	  linebuf_add_char (&buf, '*');
	  err = trie_fnmatch_f (hwdb, child, 0, &buf, search + i);
	  if (err < 0)
	    return err;
	  linebuf_rem_char (&buf);
	}

      child = node_lookup_f (hwdb, node, '?');
      if (child)
	{
	  linebuf_add_char (&buf, '?');
	  err = trie_fnmatch_f (hwdb, child, 0, &buf, search + i);
	  if (err < 0)
	    return err;
	  linebuf_rem_char (&buf);
	}

      child = node_lookup_f (hwdb, node, '[');
      if (child)
	{
	  linebuf_add_char (&buf, '[');
	  err = trie_fnmatch_f (hwdb, child, 0, &buf, search + i);
	  if (err < 0)
	    return err;
	  linebuf_rem_char (&buf);
	}

      if (search[i] == '\0')
	{
	  size_t n;

	  for (n = 0; n < le64toh (node->values_count); n++)
	    {
	      err =
		hwdb_add_property (hwdb,
				   trie_string (hwdb,
						trie_node_values
						(hwdb,
						 node)[n].key_off),
				   trie_string (hwdb,
						trie_node_values
						(hwdb, node)[n].value_off));
	      if (err < 0)
		return err;
	    }
	  return 0;
	}

      child = node_lookup_f (hwdb, node, search[i]);
      node = child;
      i++;
    }
  return 0;
}