summaryrefslogtreecommitdiff
path: root/lib/fieldtrie.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/fieldtrie.c')
-rw-r--r--lib/fieldtrie.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/lib/fieldtrie.c b/lib/fieldtrie.c
new file mode 100644
index 0000000..250fc89
--- /dev/null
+++ b/lib/fieldtrie.c
@@ -0,0 +1,98 @@
+/* dctrl-tools - Debian control file inspection tools
+ Copyright (C) 2003 Antti-Juhani Kaijanaho
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <string.h>
+#include "fieldtrie.h"
+#include "msg.h"
+
+struct field_bucket {
+ char const * name;
+ size_t namelen;
+ struct field_attr attr;
+ struct field_bucket * next;
+};
+
+struct fieldtrie_private {
+ size_t nextfree;
+ /* A one-level trie listing all field names occurring in the
+ * atomic predicates. */
+ struct field_bucket * fields[UCHAR_MAX];
+};
+
+static struct fieldtrie_private trie;
+
+void fieldtrie_init(void)
+{
+ for (size_t i = 0; i < UCHAR_MAX; i++) {
+ trie.fields[i] = 0;
+ }
+ trie.nextfree = 0;
+}
+
+size_t fieldtrie_insert(char const * s)
+{
+ size_t slen = strlen(s);
+ struct field_attr l_attr = fieldtrie_lookup(s, slen);
+ if (l_attr.valid) return l_attr.inx;
+ struct field_bucket * b = malloc(sizeof *b);
+ if (b == 0) fatal_enomem(0);
+ b->name = malloc(slen+1);
+ if (b->name == 0) fatal_enomem(0);
+ strcpy((char*)b->name, s);
+ b->namelen = slen;
+ b->attr.inx = trie.nextfree++;
+ b->attr.valid = true;
+ unsigned char c = tolower((unsigned char)(b->name[0]));
+ b->next = trie.fields[c];
+ trie.fields[c] = b;
+ return b->attr.inx;
+}
+
+struct field_attr fieldtrie_lookup(char const * s, size_t n)
+{
+ for (struct field_bucket * b = trie.fields[tolower((unsigned char)s[0])];
+ b != 0;
+ b = b->next) {
+ if (n == b->namelen &&
+ strncasecmp(s, b->name, n) == 0) return b->attr;
+ }
+ return (struct field_attr){ .valid = false };
+}
+
+size_t fieldtrie_count(void)
+{
+ return trie.nextfree;
+}
+
+#if 0
+void fieldtrie_clear(void)
+{
+ for (size_t i = 0; i < UCHAR_MAX; i++) {
+ struct field_bucket * b = trie.fields[i];
+ while (b != 0) {
+ struct field_bucket * bn = b->next;
+ free(b);
+ b = bn;
+ }
+ trie->fields[i] = 0;
+ }
+ trie->nextfree = 0;
+}
+#endif