]> mj.ucw.cz Git - libucw.git/commitdiff
More changes in KMP:
authorPavel Charvat <pavel.charvat@netcentrum.cz>
Thu, 20 Apr 2006 08:05:43 +0000 (10:05 +0200)
committerPavel Charvat <pavel.charvat@netcentrum.cz>
Thu, 20 Apr 2006 08:05:43 +0000 (10:05 +0200)
- renamed P(context) -> P(struct)
- removed KMP_NO_DUPS
- changed syntax of user-defined variables in P(struct) and P(state)

lib/kmp-search.h
lib/kmp-test.c
lib/kmp.h

index 5cfb8ea1f4a7166e72c4fbf3fc4676d3667b58ca..ab276b5a3916b3934a3e97b3a93894a917e8a4a7 100644 (file)
  *
  *  KMPS_SOURCE                        user-defined search input (together with KMPS_GET_CHAR);
  *                             if unset, the one from lib/kmp.h is used
- *  KMPS_GET_CHAR(ctx,src,s)
+ *  KMPS_GET_CHAR(kmp,src,s)
  *
  *  KMPS_ADD_CONTROLS          add control characters at both ends of the input string
  *  KMPS_MERGE_CONTROLS        merge adjacent control characters to a single one
  *
  *  KMPS_EXTRA_ARGS            extra arguments to the search routine
  *  KMPS_EXTRA_VAR             extra user-defined structure in search structures
- *  KMPS_INIT(ctx,src,s)
- *  KMPS_EXIT(ctx,src,s)
- *  KMPS_FOUND(ctx,src,s)
- *  KMPS_FOUND_CHAIN(ctx,src,s)
- *  KMPS_STEP(ctx,src,s)
+ *  KMPS_INIT(kmp,src,s)
+ *  KMPS_EXIT(kmp,src,s)
+ *  KMPS_FOUND(kmp,src,s)
+ *  KMPS_FOUND_CHAIN(kmp,src,s)
+ *  KMPS_STEP(kmp,src,s)
  *  KMPS_T
  *
  *  KMPS_WANT_BEST
@@ -48,7 +48,7 @@ typedef KP(source_t) P(search_source_t);
 #endif
 
 #ifndef KMPS_GET_CHAR
-#define KMPS_GET_CHAR(ctx,src,s) ({ KP(get_char)(ctx, &src, &s.c); })
+#define KMPS_GET_CHAR(kmp,src,s) ({ KP(get_char)(kmp, &src, &s.c); })
 #endif
 
 struct P(search) {
@@ -71,16 +71,16 @@ static KMPS_T
 #else
 static void
 #endif
-P(search) (struct KP(context) *ctx, P(search_source_t) src
+P(search) (struct KP(struct) *kmp, P(search_source_t) src
 #   ifdef KMPS_EXTRA_ARGS
     , KMPS_EXTRA_ARGS
 #   endif
 )
 {
   struct P(search) s;
-  s.s = &ctx->null;
+  s.s = &kmp->null;
 # ifdef KMPS_WANT_BEST
-  s.best = &ctx->null;
+  s.best = &kmp->null;
 # endif
 # ifdef KMPS_ADD_CONTROLS 
   s.c = KP(control)();
@@ -89,18 +89,18 @@ P(search) (struct KP(context) *ctx, P(search_source_t) src
   s.c = 0;
 # endif  
 # ifdef KMPS_INIT
-  { KMPS_INIT(ctx, src, s); }
+  { KMPS_INIT(kmp, src, s); }
 # endif
 # ifndef KMPS_ADD_CONTROLS  
   goto start_read;
 #endif  
   for (;;)
   {
-    for (struct KP(state) *t = s.s; t && !(s.s = KP(hash_find)(&ctx->hash, t, s.c)); t = t->back);
-    s.s = s.s ? : &ctx->null;
+    for (struct KP(state) *t = s.s; t && !(s.s = KP(hash_find)(&kmp->hash, t, s.c)); t = t->back);
+    s.s = s.s ? : &kmp->null;
 
 #   ifdef KMPS_STEP
-    { KMPS_STEP(ctx, src, s); }
+    { KMPS_STEP(kmp, src, s); }
 #   endif
 
 #   if defined(KMPS_FOUND) || defined(KMPS_FOUND_CHAIN) || defined(KMPS_WANT_BEST)
@@ -112,11 +112,11 @@ P(search) (struct KP(context) *ctx, P(search_source_t) src
          s.best = s.out;
 #       endif  
         #ifdef KMPS_FOUND_CHAIN
-       { KMPS_FOUND_CHAIN(ctx, src, s); }
+       { KMPS_FOUND_CHAIN(kmp, src, s); }
 #       endif
 #       ifdef KMPS_FOUND
        do
-          { KMPS_FOUND(ctx, src, s); }
+          { KMPS_FOUND(kmp, src, s); }
        while (s.out = s.out->next);
 #       endif  
       }
@@ -136,10 +136,10 @@ start_read: ;
 
     do
       {
-       if (!KMPS_GET_CHAR(ctx, src, s))
+       if (!KMPS_GET_CHAR(kmp, src, s))
          {
 #           ifdef KMPS_ADD_CONTROLS
-           if (!KP(is_control)(ctx, s.c))
+           if (!KP(is_control)(kmp, s.c))
              {
                 s.c = KP(control)();
                 s.eof = 1;
@@ -151,13 +151,13 @@ start_read: ;
       }
     while (0
 #     ifdef KMPS_MERGE_CONTROLS
-      || (KP(is_control)(ctx, last_c) && KP(is_control)(ctx, s.c))
+      || (KP(is_control)(kmp, last_c) && KP(is_control)(kmp, s.c))
 #     endif
       );
   }
 exit: ;
 # ifdef KMPS_EXIT
-  { KMPS_EXIT(ctx, src, s); }
+  { KMPS_EXIT(kmp, src, s); }
 # endif
 }
 
index 100291eb96233145688df0f455a9fcbefce7ec57..63a5974efa65f9119f75ee962eaf67131dbc36e8 100644 (file)
 #define KMPS_KMP_PREFIX(x) GLUE_(kmp1,x)
 #define KMPS_WANT_BEST
 #define KMPS_T uns
-#define KMPS_EXIT(ctx,src,s) do{ return s.best->len; }while(0)
+#define KMPS_EXIT(kmp,src,s) do{ return s.best->len; }while(0)
 #include "lib/kmp-search.h"
 #define KMPS_PREFIX(x) GLUE_(kmp1s2,x)
 #define KMPS_KMP_PREFIX(x) GLUE_(kmp1,x)
 #define KMPS_EXTRA_VAR uns
-#define KMPS_INIT(ctx,src,s) do{ s.v = 0; }while(0)
+#define KMPS_INIT(kmp,src,s) do{ s.v = 0; }while(0)
 #define KMPS_T uns
-#define KMPS_FOUND(ctx,src,s) do{ s.v++; }while(0)
-#define KMPS_EXIT(ctx,src,s) do{ return s.v; }while(0)
+#define KMPS_FOUND(kmp,src,s) do{ s.v++; }while(0)
+#define KMPS_EXIT(kmp,src,s) do{ return s.v; }while(0)
 #define KMPS_WANT_BEST
 #include "lib/kmp-search.h"
 
@@ -39,18 +39,18 @@ static void
 test1(void)
 {
   TRACE("Running test1");
-  struct kmp1_context ctx;
-  kmp1_init(&ctx);
-  kmp1_add(&ctx, "ahoj");
-  kmp1_add(&ctx, "hoj");
-  kmp1_add(&ctx, "aho");
-  kmp1_build(&ctx);
-  UNUSED uns best = kmp1s1_search(&ctx, "asjlahslhalahosjkjhojsas");
+  struct kmp1_struct kmp;
+  kmp1_init(&kmp);
+  kmp1_add(&kmp, "ahoj");
+  kmp1_add(&kmp, "hoj");
+  kmp1_add(&kmp, "aho");
+  kmp1_build(&kmp);
+  UNUSED uns best = kmp1s1_search(&kmp, "asjlahslhalahosjkjhojsas");
   TRACE("Best match has %d characters", best);
   ASSERT(best == 3);
-  UNUSED uns count = kmp1s2_search(&ctx, "asjlahslhalahojsjkjhojsas");
+  UNUSED uns count = kmp1s2_search(&kmp, "asjlahslhalahojsjkjhojsas");
   ASSERT(count == 4);
-  kmp1_cleanup(&ctx);
+  kmp1_cleanup(&kmp);
 }
 
 /* TEST2 - various tracing */
@@ -59,54 +59,54 @@ test1(void)
 #define KMP_USE_UTF8
 #define KMP_TOLOWER
 #define KMP_ONLYALPHA
-#define KMP_NODE struct { byte *str; uns id; }
+#define KMP_STATE_VARS byte *str; uns id;
 #define KMP_ADD_EXTRA_ARGS uns id
 #define KMP_ADD_EXTRA_VAR byte *
-#define KMP_ADD_INIT(ctx,src,var) do{ var = src; }while(0)
-#define KMP_ADD_NEW(ctx,src,var,state) do{ TRACE("Inserting string %s with id %d", var, id); \
-  state->n.str = var; state->n.id = id; }while(0)
-#define KMP_ADD_DUP(ctx,src,var,state) do{ TRACE("String %s already inserted", var); }while(0)
+#define KMP_ADD_INIT(kmp,src,v) do{ v = src; }while(0)
+#define KMP_ADD_NEW(kmp,src,v,s) do{ TRACE("Inserting string %s with id %d", v, id); \
+  s->u.str = v; s->u.id = id; }while(0)
+#define KMP_ADD_DUP(kmp,src,v,s) do{ TRACE("String %s already inserted", v); }while(0)
 #define KMP_WANT_CLEANUP
 #define KMP_WANT_SEARCH
 #define KMPS_ADD_CONTROLS
 #define KMPS_MERGE_CONTROLS
 #define KMPS_WANT_BEST
-#define KMPS_FOUND(ctx,src,s) do{ TRACE("String %s with id %d found", s.out->n.str, s.out->n.id); }while(0)
-#define KMPS_STEP(ctx,src,s) do{ TRACE("Got to state %p after reading %d", s.s, s.c); }while(0)
-#define KMPS_EXIT(ctx,src,s) do{ if (s.best->len) TRACE("Best match is %s", s.best->n.str); } while(0)
+#define KMPS_FOUND(kmp,src,s) do{ TRACE("String %s with id %d found", s.out->u.str, s.out->u.id); }while(0)
+#define KMPS_STEP(kmp,src,s) do{ TRACE("Got to state %p after reading %d", s.s, s.c); }while(0)
+#define KMPS_EXIT(kmp,src,s) do{ if (s.best->len) TRACE("Best match is %s", s.best->u.str); } while(0)
 #include "lib/kmp.h"
 
 static void
 test2(void)
 {
   TRACE("Running test2");
-  struct kmp2_context ctx;
-  kmp2_init(&ctx);
-  kmp2_add(&ctx, "ahoj", 1);
-  kmp2_add(&ctx, "ahoj", 2);
-  kmp2_add(&ctx, "hoj", 3);
-  kmp2_add(&ctx, "aho", 4);
-  kmp2_add(&ctx, "aba", 5);
-  kmp2_add(&ctx, "aba", 5);
-  kmp2_add(&ctx, "pěl", 5);
-  kmp2_build(&ctx);
-  kmp2_search(&ctx, "Šíleně žluťoučký kůň úpěl ďábelské ódy labababaks sdahojdhsaladsjhla");
-  kmp2_cleanup(&ctx);
+  struct kmp2_struct kmp;
+  kmp2_init(&kmp);
+  kmp2_add(&kmp, "ahoj", 1);
+  kmp2_add(&kmp, "ahoj", 2);
+  kmp2_add(&kmp, "hoj", 3);
+  kmp2_add(&kmp, "aho", 4);
+  kmp2_add(&kmp, "aba", 5);
+  kmp2_add(&kmp, "aba", 5);
+  kmp2_add(&kmp, "pěl", 5);
+  kmp2_build(&kmp);
+  kmp2_search(&kmp, "Šíleně žluťoučký kůň úpěl ďábelské ódy labababaks sdahojdhsaladsjhla");
+  kmp2_cleanup(&kmp);
 }
 
 /* TEST3 - random tests */
 
 #define KMP_PREFIX(x) GLUE_(kmp3,x)
-#define KMP_NODE uns
+#define KMP_STATE_VARS uns index;
 #define KMP_ADD_EXTRA_ARGS uns index
 #define KMP_ADD_EXTRA_VAR byte *
-#define KMP_ADD_INIT(ctx,src,v) do{ v = src; }while(0)
-#define KMP_ADD_NEW(ctx,src,v,s) do{ s->n = index; }while(0)
-#define KMP_ADD_DUP(ctx,src,v,s) do{ *v = 0; }while(0)
+#define KMP_ADD_INIT(kmp,src,v) do{ v = src; }while(0)
+#define KMP_ADD_NEW(kmp,src,v,s) do{ s->u.index = index; }while(0)
+#define KMP_ADD_DUP(kmp,src,v,s) do{ *v = 0; }while(0)
 #define KMP_WANT_CLEANUP
 #define KMP_WANT_SEARCH
 #define KMPS_EXTRA_ARGS uns *cnt, uns *sum
-#define KMPS_FOUND(ctx,src,s) do{ ASSERT(cnt[s.out->n]); cnt[s.out->n]--; sum[0]--; }while(0)
+#define KMPS_FOUND(kmp,src,s) do{ ASSERT(cnt[s.out->u.index]); cnt[s.out->u.index]--; sum[0]--; }while(0)
 #include "lib/kmp.h"
 
 static void
@@ -119,8 +119,8 @@ test3(void)
     mp_flush(pool);
     uns n = random_max(100);
     byte *s[n];
-    struct kmp3_context ctx;
-    kmp3_init(&ctx);
+    struct kmp3_struct kmp;
+    kmp3_init(&kmp);
     for (uns i = 0; i < n; i++)
       {
         uns m = random_max(10);
@@ -128,9 +128,9 @@ test3(void)
         for (uns j = 0; j < m; j++)
          s[i][j] = 'a' + random_max(3);
         s[i][m] = 0;
-        kmp3_add(&ctx, s[i], i);
+        kmp3_add(&kmp, s[i], i);
       }
-    kmp3_build(&ctx);
+    kmp3_build(&kmp);
     for (uns i = 0; i < 10; i++)
       {
         uns m = random_max(100);
@@ -147,27 +147,27 @@ test3(void)
                if (!strncmp(b + k, s[j], strlen(s[j])))
                  cnt[j]++, sum++;
          }
-        kmp3_search(&ctx, b, cnt, &sum);
+        kmp3_search(&kmp, b, cnt, &sum);
         ASSERT(sum == 0);
       }
-    kmp3_cleanup(&ctx);
+    kmp3_cleanup(&kmp);
   }
   mp_delete(pool);
 }
 
 /* TEST4 - user-defined character type */
 
-struct kmp4_context;
+struct kmp4_struct;
 struct kmp4_state;
 
 static inline int
-kmp4_eq(struct kmp4_context *ctx UNUSED, byte *a, byte *b)
+kmp4_eq(struct kmp4_struct *kmp UNUSED, byte *a, byte *b)
 {
   return (a == b) || (a && b && *a == *b);
 }
 
 static inline uns
-kmp4_hash(struct kmp4_context *ctx UNUSED, struct kmp4_state *s, byte *c)
+kmp4_hash(struct kmp4_struct *kmp UNUSED, struct kmp4_state *s, byte *c)
 {
   return (c ? (*c << 16) : 0) + (uns)(addr_int_t)s;
 }
@@ -175,12 +175,12 @@ kmp4_hash(struct kmp4_context *ctx UNUSED, struct kmp4_state *s, byte *c)
 #define KMP_PREFIX(x) GLUE_(kmp4,x)
 #define KMP_CHAR byte *
 #define KMP_CONTROL_CHAR NULL
-#define KMP_GET_CHAR(ctx,src,c) ({ c = src++; !!*c; })
+#define KMP_GET_CHAR(kmp,src,c) ({ c = src++; !!*c; })
 #define KMP_GIVE_HASHFN
 #define KMP_GIVE_EQ
 #define KMP_WANT_CLEANUP
 #define KMP_WANT_SEARCH
-#define KMPS_FOUND(ctx,src,s) do{ TRACE("found"); }while(0)
+#define KMPS_FOUND(kmp,src,s) do{ TRACE("found"); }while(0)
 #define KMPS_ADD_CONTROLS
 #define KMPS_MERGE_CONTROLS
 #include "lib/kmp.h"
@@ -189,12 +189,12 @@ static void
 test4(void)
 {
   TRACE("Running test4");
-  struct kmp4_context ctx;
-  kmp4_init(&ctx);
-  kmp4_add(&ctx, "ahoj");
-  kmp4_build(&ctx);
-  kmp4_search(&ctx, "djdhaskjdahoahaahojojshdaksjahdahojskj");
-  kmp4_cleanup(&ctx);
+  struct kmp4_struct kmp;
+  kmp4_init(&kmp);
+  kmp4_add(&kmp, "ahoj");
+  kmp4_build(&kmp);
+  kmp4_search(&kmp, "djdhaskjdahoahaahojojshdaksjahdahojskj");
+  kmp4_cleanup(&kmp);
 }
 
 int
index 2ce01b3a910e0dee29505b59c1d041c5e6bf5b3f..f061e337e20f29beea2424757427732aa9e9a935 100644 (file)
--- a/lib/kmp.h
+++ b/lib/kmp.h
  *     KMP_CHAR                alphabet type, the default is u16
  *     
  *     KMP_SOURCE              user-defined text source; KMP_GET_CHAR must 
- *     KMP_GET_CHAR(ctx,src,c) return next character from the input or zero at the end;
+ *     KMP_GET_CHAR(kmp,src,c) return next character from the input or zero at the end;
  *                             if not defined, zero-terminated array of bytes is used as the input
  *     
- *     KMP_NODE                user-defined data in each state of the automaton
- *     KMP_CONTEXT             user-defined data in struct context (a structure describing
+ *     KMP_VARS                user-defined data in main structure (a structure describing
  *                             the whole automaton)
+ *     KMP_STATE_VARS          user-defined data in each state of the automaton
  *
  *    Parameters which select how the input is interpreted (if KMP_SOURCE is unset):
  *     KMP_USE_ASCII           reads single bytes from the input (default)
  *    Parameters controlling add():
  *     KMP_ADD_EXTRA_ARGS      extra arguments
  *     KMP_ADD_EXTRA_VAR       structure with extra local variables
- *     KMP_ADD_INIT(ctx,src,v)
- *     KMP_ADD_NEW(ctx,src,v,s)
- *     KMP_ADD_DUP(ctx,src,v,s)
- *     KMP_NO_DUPS             no support for duplicates
+ *     KMP_ADD_INIT(kmp,src,v)
+ *     KMP_ADD_NEW(kmp,src,v,s)
+ *     KMP_ADD_DUP(kmp,src,v,s)
  *
  *    Parameters to build():
- *      KMP_BUILD_STATE(ctx,s) called for all states (including null) in order of non-decreasing tree depth
+ *      KMP_BUILD_STATE(kmp,s) called for all states (including null) in order of non-decreasing tree depth
  *
  *    Other parameters:
  *     KMP_WANT_CLEANUP        define cleanup()
@@ -84,7 +83,7 @@ typedef KMP_NODE P(node_t);
 typedef struct {} P(node_t);
 #endif
 
-struct P(context);
+struct P(struct);
 
 struct P(state) {
   struct P(state) *from;       /* state with previous character */
@@ -92,18 +91,22 @@ struct P(state) {
   struct P(state) *next;       /* largest shorter match */
   P(len_t) len;                        /* largest match, zero otherwise */
   P(char_t) c;                 /* last character */
-  P(node_t) n;                 /* user-defined data */
+  struct {
+#   ifdef KMP_STATE_VARS
+    KMP_STATE_VARS
+#   endif    
+  } u;                         /* user-defined data*/
 };
 
 /* Control char */
 static inline P(char_t)
 P(control) (void)
 {
-#ifdef KMP_CONTROL_CHAR
+# ifdef KMP_CONTROL_CHAR
   return KMP_CONTROL_CHAR;
-#else
+# else
   return ':';
-#endif
+# endif
 }
 
 /* User-defined source */
@@ -114,7 +117,7 @@ struct P(hash_table);
 static inline uns
 P(hash_hash) (struct P(hash_table) *t, struct P(state) *f, P(char_t) c)
 {
-  return P(hash) ((struct P(context) *) t, f, c);
+  return P(hash) ((struct P(struct) *) t, f, c);
 }
 #else
 static inline uns
@@ -126,23 +129,23 @@ P(hash_hash) (struct P(hash_table) *t UNUSED, struct P(state) *f, P(char_t) c)
 
 #ifndef KMP_GIVE_EQ
 static inline int
-P(eq) (struct P(context) *ctx UNUSED, P(char_t) c1, P(char_t) c2)
+P(eq) (struct P(struct) *kmp UNUSED, P(char_t) c1, P(char_t) c2)
 {
   return c1 == c2;
 }
 #endif
 
 static inline int
-P(is_control) (struct P(context) *ctx, P(char_t) c)
+P(is_control) (struct P(struct) *kmp, P(char_t) c)
 {
-  return P(eq) (ctx, c, P(control)());
+  return P(eq) (kmp, c, P(control)());
 }
 
 #define HASH_GIVE_EQ
 static inline int
 P(hash_eq) (struct P(hash_table) *t, struct P(state) *f1, P(char_t) c1, struct P(state) *f2, P(char_t) c2)
 {
-  return f1 == f2 && P(eq)((struct P(context) *) t, c1, c2);
+  return f1 == f2 && P(eq)((struct P(struct) *) t, c1, c2);
 }
 
 #ifdef KMP_GIVE_ALLOC
@@ -150,13 +153,13 @@ P(hash_eq) (struct P(hash_table) *t, struct P(state) *f1, P(char_t) c1, struct P
 static inline void *
 P(hash_alloc) (struct P(hash_table) *t, uns size)
 {
-  return P(alloc) ((struct P(context) *) t, size);
+  return P(alloc) ((struct P(struct) *) t, size);
 }
 
 static inline void
 P(hash_free) (struct P(hash_table) *t, void *ptr)
 {
-  P(free) ((struct P(context) *) t, ptr);
+  P(free) ((struct P(struct) *) t, ptr);
 }
 #endif
 
@@ -191,12 +194,14 @@ P(hash_init_key) (struct P(hash_table) *t UNUSED, struct P(state) *s, struct P(s
 #include "lib/hashtable.h"
 #define P(x) KMP_PREFIX(x)
 
-struct P(context) {
+struct P(struct) {
   struct P(hash_table) hash;           /* hash table of state transitions */
   struct P(state) null;                        /* null state */
-# ifdef KMP_CONTEXT
-  KMP_CONTEXT v;                       /* user defined data */
-# endif  
+  struct {
+#   ifdef KMP_VARS
+    KMP_VARS
+#   endif
+  } u;                                 /* user-defined data */
 };
 
 #ifdef KMP_SOURCE
@@ -207,9 +212,9 @@ typedef byte *P(source_t);
 
 #ifdef KMP_GET_CHAR
 static inline int
-P(get_char) (struct P(context) *ctx UNUSED, P(source_t) *src UNUSED, P(char_t) *c UNUSED)
+P(get_char) (struct P(struct) *kmp UNUSED, P(source_t) *src UNUSED, P(char_t) *c UNUSED)
 {
-  return KMP_GET_CHAR(ctx, (*src), (*c));
+  return KMP_GET_CHAR(kmp, (*src), (*c));
 }
 #else
 #  if defined(KMP_USE_UTF8)
@@ -223,7 +228,7 @@ P(get_char) (struct P(context) *ctx UNUSED, P(source_t) *src UNUSED, P(char_t) *
 #    endif
 #  endif
 static inline int
-P(get_char) (struct P(context) *ctx UNUSED, P(source_t) *src, P(char_t) *c)
+P(get_char) (struct P(struct) *kmp UNUSED, P(source_t) *src, P(char_t) *c)
 {
 # ifdef KMP_USE_UTF8
   uns cc;
@@ -263,7 +268,7 @@ P(get_char) (struct P(context) *ctx UNUSED, P(source_t) *src, P(char_t) *c)
 #endif
 
 static struct P(state) *
-P(add) (struct P(context) *ctx, P(source_t) src
+P(add) (struct P(struct) *kmp, P(source_t) src
 #   ifdef KMP_ADD_EXTRA_ARGS
     , KMP_ADD_EXTRA_ARGS
 #   endif
@@ -273,37 +278,37 @@ P(add) (struct P(context) *ctx, P(source_t) src
   KMP_ADD_EXTRA_VAR v;
 # endif
 # ifdef KMP_ADD_INIT
-  { KMP_ADD_INIT(ctx, src, v); }
+  { KMP_ADD_INIT(kmp, src, v); }
 # endif
 
   P(char_t) c;
-  if (!P(get_char)(ctx, &src, &c))
+  if (!P(get_char)(kmp, &src, &c))
     return NULL;
-  struct P(state) *p = &ctx->null, *s;
+  struct P(state) *p = &kmp->null, *s;
   uns len = 0;
   do
     {
-      s = P(hash_find)(&ctx->hash, p, c);
+      s = P(hash_find)(&kmp->hash, p, c);
       if (!s)
        for (;;)
          {
-           s = P(hash_new)(&ctx->hash, p, c);
+           s = P(hash_new)(&kmp->hash, p, c);
            len++;
-           if (!(P(get_char)(ctx, &src, &c)))
+           if (!(P(get_char)(kmp, &src, &c)))
              goto enter_new;
            p = s;
          }
       p = s;
       len++;
     }
-  while (P(get_char)(ctx, &src, &c));
+  while (P(get_char)(kmp, &src, &c));
 # ifdef KMP_NO_DUPS
   ASSERT(!s->len);
 # else  
   if (s->len)
     {
 #     ifdef KMP_ADD_DUP
-      { KMP_ADD_DUP(ctx, src, v, s); }
+      { KMP_ADD_DUP(kmp, src, v, s); }
 #     endif
       return s;
     }
@@ -311,30 +316,30 @@ P(add) (struct P(context) *ctx, P(source_t) src
 enter_new:
   s->len = len;
 # ifdef KMP_ADD_NEW
-  { KMP_ADD_NEW(ctx, src, v, s); }
+  { KMP_ADD_NEW(kmp, src, v, s); }
 # endif
   return s;
 }
 
 static void
-P(init) (struct P(context) *ctx)
+P(init) (struct P(struct) *kmp)
 {
-  bzero(&ctx->null, sizeof(struct P(state)));
-  P(hash_init)(&ctx->hash);
+  bzero(&kmp->null, sizeof(struct P(state)));
+  P(hash_init)(&kmp->hash);
 }
 
 #ifdef KMP_WANT_CLEANUP
 static inline void
-P(cleanup) (struct P(context) *ctx)
+P(cleanup) (struct P(struct) *kmp)
 {
-  P(hash_cleanup)(&ctx->hash);
+  P(hash_cleanup)(&kmp->hash);
 }
 #endif
 
 static inline int
-P(empty) (struct P(context) *ctx)
+P(empty) (struct P(struct) *kmp)
 {
-  return !ctx->hash.hash_count;
+  return !kmp->hash.hash_count;
 }
 
 static inline struct P(state) *
@@ -344,17 +349,17 @@ P(chain_start) (struct P(state) *s)
 }
 
 static void
-P(build) (struct P(context) *ctx)
+P(build) (struct P(struct) *kmp)
 {
-  if (P(empty)(ctx))
+  if (P(empty)(kmp))
     return;
   uns read = 0, write = 0;
-  struct P(state) *fifo[ctx->hash.hash_count], *null = &ctx->null;
+  struct P(state) *fifo[kmp->hash.hash_count], *null = &kmp->null;
   for (struct P(state) *s = null->back; s; s = s->next)
     fifo[write++] = s;
   null->back = NULL;
 # ifdef KMP_BUILD_STATE
-  { KMP_BUILD_STATE(ctx, null); }
+  { KMP_BUILD_STATE(kmp, null); }
 # endif  
   while (read != write)
     {
@@ -369,7 +374,7 @@ P(build) (struct P(context) *ctx)
              s->next = NULL;
              break;
            }
-         s->back = P(hash_find)(&ctx->hash, t, s->c);
+         s->back = P(hash_find)(&kmp->hash, t, s->c);
          if (s->back)
            {
              s->next = s->back->len ? s->back : s->back->next;
@@ -377,7 +382,7 @@ P(build) (struct P(context) *ctx)
            }
        }
 #     ifdef KMP_BUILD_STATE
-      { KMP_BUILD_STATE(ctx, s); }
+      { KMP_BUILD_STATE(kmp, s); }
 #     endif      
     }
 }
@@ -386,7 +391,8 @@ P(build) (struct P(context) *ctx)
 #undef KMP_CHAR
 #undef KMP_SOURCE
 #undef KMP_GET_CHAR
-#undef KMP_NODE
+#undef KMP_VARS
+#undef KMP_STATE_VARS
 #undef KMP_CONTEXT
 #undef KMP_USE_ASCII
 #undef KMP_USE_UTF8
@@ -399,7 +405,6 @@ P(build) (struct P(context) *ctx)
 #undef KMP_ADD_INIT
 #undef KMP_ADD_NEW
 #undef KMP_ADD_DUP
-#undef KMP_NO_DUPS
 #undef KMP_BUILD_STATE
 #undef KMP_USE_POOL
 #undef KMP_GIVE_ALLOC