First version of scan.
authorAdam Dickmeiss <adam@indexdata.dk>
Fri, 6 Oct 1995 09:03:51 +0000 (09:03 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Fri, 6 Oct 1995 09:03:51 +0000 (09:03 +0000)
dict/Makefile
dict/scan.c [new file with mode: 0644]
include/dict.h

index ee9f629..ece4b6b 100644 (file)
@@ -1,7 +1,7 @@
 # Copyright (C) 1994, Index Data I/S 
 # All rights reserved.
 # Sebastian Hammer, Adam Dickmeiss
-# $Id: Makefile,v 1.15 1995-09-04 12:33:31 adam Exp $
+# $Id: Makefile,v 1.16 1995-10-06 09:04:03 adam Exp $
 
 SHELL=/bin/sh
 RANLIB=ranlib
@@ -13,7 +13,7 @@ TPROG2=dictext
 #CFLAGS=-g -Wall -pedantic -ansi
 DEFS=$(INCLUDE)
 LIB=../lib/dict.a 
-PO = dopen.o dclose.o drdwr.o open.o close.o insert.o lookup.o \
+PO = scan.o dopen.o dclose.o drdwr.o open.o close.o insert.o lookup.o \
  lookupec.o lookgrep.o
 CPP=cc -E
 
diff --git a/dict/scan.c b/dict/scan.c
new file mode 100644 (file)
index 0000000..85e870f
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 1994, Index Data I/S 
+ * All rights reserved.
+ * Sebastian Hammer, Adam Dickmeiss
+ *
+ * $Log: scan.c,v $
+ * Revision 1.1  1995-10-06 09:04:18  adam
+ * First version of scan.
+ *
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+
+#include <dict.h>
+
+void dict_scan_trav (Dict dict, Dict_ptr ptr, int pos, Dict_char *str, 
+                   int start, int *count,
+                    int (*userfunc)(Dict_char *, const char *, int pos),
+                   int dir)
+{
+    int lo, hi, j;
+    void *p;
+    short *indxp;
+    char *info;
+
+    dict_bf_readp (dict->dbf, ptr, &p);
+    hi = DICT_nodir(p)-1;
+    if (start == 0 && dir == -1)
+        lo = hi;
+    else
+        lo = start;
+    indxp = (short*) ((char*) p+DICT_pagesize(dict)-sizeof(short)); 
+
+    while (lo <= hi && lo >= 0 && *count > 0)
+    {
+        if (indxp[-lo] > 0)
+        {
+            /* string (Dict_char *) DICT_EOS terminated */
+            /* unsigned char        length of information */
+            /* char *               information */
+
+           info = (char*)p + indxp[-lo];
+            for (j = 0; info[j] != DICT_EOS; j++)
+               str[pos+j] = info[j];
+            str[pos+j] = DICT_EOS;
+            (*userfunc)(str, info+j*sizeof(Dict_char), *count * dir);
+            --(*count);
+        }
+        else
+        {
+            Dict_char dc;
+           Dict_ptr subptr;
+
+            /* Dict_ptr             subptr */
+            /* Dict_char            sub char */
+            /* unsigned char        length of information */
+            /* char *               information */
+
+            info = (char*)p - indxp[-lo];
+            memcpy (&dc, info+sizeof(Dict_ptr), sizeof(Dict_char));
+            str[pos] = dc;
+           memcpy (&subptr, info, sizeof(Dict_ptr));
+           if (info[sizeof(Dict_ptr)+sizeof(Dict_char)])
+            {
+                 str[pos+1] = DICT_EOS;
+                 (*userfunc)(str, info+sizeof(Dict_ptr)+sizeof(Dict_char),
+                            *count * dir);
+                 --(*count);
+            }
+            if (*count > 0 && subptr)
+                dict_scan_trav (dict, subptr, pos+1, str, 0, count, 
+                                 userfunc, dir);
+        }
+        lo += dir;
+    }
+}
+    
+int dict_scan_r (Dict dict, Dict_ptr ptr, int pos, Dict_char *str, 
+                int *before, int *after,
+                 int (*userfunc)(Dict_char *, const char *, int))
+{
+    int cmp = 0, mid, lo, hi, j;
+    void *p;
+    short *indxp;
+    char *info;
+
+    dict_bf_readp (dict->dbf, ptr, &p);
+    mid = lo = 0;
+    hi = DICT_nodir(p)-1;
+    indxp = (short*) ((char*) p+DICT_pagesize(dict)-sizeof(short));    
+    while (lo <= hi)
+    {
+        mid = (lo+hi)/2;
+        if (indxp[-mid] > 0)
+        {
+            /* string (Dict_char *) DICT_EOS terminated */
+            /* unsigned char        length of information */
+            /* char *               information */
+           info = (char*)p + indxp[-mid];
+           cmp = dict_strcmp ((Dict_char*) info, str + pos);
+           if (!cmp)
+            {
+               for (j = 0; info[j++] != DICT_EOS; )
+                   ;
+                (*userfunc)(str, info+j*sizeof(Dict_char), *after);
+                --(*after);
+                break;
+            }
+        }
+        else
+        {
+            Dict_char dc;
+           Dict_ptr subptr;
+
+            /* Dict_ptr             subptr */
+            /* Dict_char            sub char */
+            /* unsigned char        length of information */
+            /* char *               information */
+            info = (char*)p - indxp[-mid];
+            memcpy (&dc, info+sizeof(Dict_ptr), sizeof(Dict_char));
+           cmp = dc - str[pos];
+           if (!cmp)
+            {
+               memcpy (&subptr, info, sizeof(Dict_ptr));
+                if (str[pos+1] == DICT_EOS)
+                {
+                   if (info[sizeof(Dict_ptr)+sizeof(Dict_char)])
+                    {
+                        (*userfunc)(str, 
+                                    info+sizeof(Dict_ptr)+sizeof(Dict_char),
+                                   *after);
+                       --(*after);
+                    }
+                    if (*after > 0 && subptr)
+                       dict_scan_trav (dict, subptr, pos+1, str, 0, 
+                                        after, userfunc, 1);
+                }
+               else if (*after > 0 && subptr)
+                    dict_scan_r (dict, subptr, pos+1, str, before, after,
+                                 userfunc);
+                break;
+            }
+        }
+       if (cmp < 0)
+           lo = mid+1;
+       else
+           hi = mid-1;
+    }
+    if (lo>hi && cmp < 0)
+        ++mid;
+    if (*after)
+        dict_scan_trav (dict, ptr, pos, str, cmp ? mid : mid+1, after,
+                        userfunc, 1);
+    if (*before && mid > 1)
+        dict_scan_trav (dict, ptr, pos, str, mid-1, before, 
+                        userfunc, -1);
+    return 0;
+}
+
+int dict_scan (Dict dict, Dict_char *str, int *before, int *after,
+               int (*f)(Dict_char *name, const char *info, int pos))
+{
+    int i;
+    i = dict_scan_r (dict, 1, 0, str, before, after, f);
+    return i;
+}
+
index da75819..206cbf1 100644 (file)
@@ -4,7 +4,10 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: dict.h,v $
- * Revision 1.12  1995-09-14 11:53:02  adam
+ * Revision 1.13  1995-10-06 09:03:51  adam
+ * First version of scan.
+ *
+ * Revision 1.12  1995/09/14  11:53:02  adam
  * Grep handle function parameter info is const now.
  *
  * Revision 1.11  1995/09/04  09:09:51  adam
@@ -115,6 +118,9 @@ int        dict_lookup_grep (Dict dict, Dict_char *p, int range,
                              int (*f)(Dict_char *name, const char *info));
 int        dict_strcmp (const Dict_char *s1, const Dict_char *s2);
 int        dict_strlen (const Dict_char *s);
+int       dict_scan (Dict dict, Dict_char *str, 
+                     int *before, int *after,
+                     int (*f)(Dict_char *name, const char *info, int pos));
 
 #define DICT_EOS        0
 #define DICT_type(x)    0[(Dict_ptr*) x]