nmake: align with pazpar2 WRT icu/libxslt
[idzebra-moved-to-github.git] / index / zinfo.c
index f19a068..1e30ca0 100644 (file)
@@ -1,8 +1,5 @@
-/* $Id: zinfo.c,v 1.63 2006-05-18 12:03:05 adam Exp $
-   Copyright (C) 1995-2006
-   Index Data ApS
-
-This file is part of the Zebra server.
+/* This file is part of the Zebra server.
+   Copyright (C) Index Data
 
 Zebra 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
 
 Zebra 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
@@ -15,11 +12,14 @@ 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
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with Zebra; see the file LICENSE.zebra.  If not, write to the
-Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
 */
 
 */
 
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
 #include <sys/types.h>
 #include <assert.h>
 #include <stdlib.h>
 #include <sys/types.h>
 #include <assert.h>
 #include <stdlib.h>
@@ -32,17 +32,9 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #define ZINFO_DEBUG 0
 
 struct zebSUInfo {
 #define ZINFO_DEBUG 0
 
 struct zebSUInfo {
-    int index_type;
-#define ZEB_SU_SET_USE 1
-#define ZEB_SU_STR 2
-    int which;
-    union {
-       char *str;
-       struct {
-           int set;
-           int use;
-       } su;
-    } u;
+    char *index_type;
+    zinfo_index_category_t cat;
+    char *str;
     int ordinal;
     zint doc_occurrences;
     zint term_occurrences;
     int ordinal;
     zint doc_occurrences;
     zint term_occurrences;
@@ -56,7 +48,7 @@ struct zebSUInfoB {
 typedef struct zebAccessObjectB *zebAccessObject;
 struct zebAccessObjectB {
     void *handle;
 typedef struct zebAccessObjectB *zebAccessObject;
 struct zebAccessObjectB {
     void *handle;
-    SYSNO sysno;
+    zint sysno;
     Odr_oid *oid;
     zebAccessObject next;
 };
     Odr_oid *oid;
     zebAccessObject next;
 };
@@ -69,7 +61,7 @@ struct zebAccessInfoB {
 
 typedef struct {
     struct zebSUInfoB *SUInfo;
 
 typedef struct {
     struct zebSUInfoB *SUInfo;
-    SYSNO sysno;
+    zint sysno;
     int dirty;
     int readFlag;
     data1_node *data1_tree;
     int dirty;
     int readFlag;
     data1_node *data1_tree;
@@ -82,7 +74,7 @@ struct zebDatabaseInfoB {
     data1_node *data1_database;
     zint recordCount;    /* records in db */
     zint recordBytes;    /* size of records */
     data1_node *data1_database;
     zint recordCount;    /* records in db */
     zint recordBytes;    /* size of records */
-    SYSNO sysno;         /* sysno of database info */
+    zint sysno;          /* sysno of database info */
     int readFlag;        /* 1: read is needed when referenced; 0 if not */
     int dirty;           /* 1: database is dirty: write is needed */
     struct zebDatabaseInfoB *next;
     int readFlag;        /* 1: read is needed when referenced; 0 if not */
     int dirty;           /* 1: database is dirty: write is needed */
     struct zebDatabaseInfoB *next;
@@ -97,7 +89,7 @@ struct zebraExplainAttset {
 
 struct zebraCategoryListInfo {
     int dirty;
 
 struct zebraCategoryListInfo {
     int dirty;
-    SYSNO sysno;
+    zint sysno;
     data1_node *data1_categoryList;
 };
 
     data1_node *data1_categoryList;
 };
 
@@ -118,7 +110,7 @@ struct zebraExplainInfo {
     struct zebDatabaseInfoB *curDatabaseInfo;
     zebAccessInfo accessInfo;
     char date[15]; /* YYYY MMDD HH MM SS */
     struct zebDatabaseInfoB *curDatabaseInfo;
     zebAccessInfo accessInfo;
     char date[15]; /* YYYY MMDD HH MM SS */
-    int (*updateFunc)(void *handle, Record drec, data1_node *n);
+    ZebraExplainUpdateFunc *updateFunc;
     void *updateHandle;
 };
 
     void *updateHandle;
 };
 
@@ -146,7 +138,7 @@ static void zebraExplain_writeCategoryList(ZebraExplainInfo zei,
                                            int key_flush);
 
 
                                            int key_flush);
 
 
-static Record createRecord(Records records, SYSNO *sysno)
+static Record createRecord(Records records, zint *sysno)
 {
     Record rec;
     if (*sysno)
 {
     Record rec;
     if (*sysno)
@@ -162,12 +154,12 @@ static Record createRecord(Records records, SYSNO *sysno)
        if (!rec)
            return 0;
        *sysno = rec->sysno;
        if (!rec)
            return 0;
        *sysno = rec->sysno;
-       
+
        rec->info[recInfo_fileType] =
            rec_strdup("grs.sgml", &rec->size[recInfo_fileType]);
        rec->info[recInfo_databaseName] =
            rec_strdup("IR-Explain-1",
        rec->info[recInfo_fileType] =
            rec_strdup("grs.sgml", &rec->size[recInfo_fileType]);
        rec->info[recInfo_databaseName] =
            rec_strdup("IR-Explain-1",
-                       &rec->size[recInfo_databaseName]); 
+                       &rec->size[recInfo_databaseName]);
     }
     return rec;
 }
     }
     return rec;
 }
@@ -224,7 +216,7 @@ void zebraExplain_close(ZebraExplainInfo zei)
     nmem_destroy(zei->nmem);
 }
 
     nmem_destroy(zei->nmem);
 }
 
-void zebraExplain_mergeOids (ZebraExplainInfo zei, data1_node *n,
+void zebraExplain_mergeOids(ZebraExplainInfo zei, data1_node *n,
                             zebAccessObject *op)
 {
     data1_node *np;
                             zebAccessObject *op)
 {
     data1_node *np;
@@ -243,7 +235,7 @@ void zebraExplain_mergeOids (ZebraExplainInfo zei, data1_node *n,
            len = 63;
        memcpy(str, np->child->u.data.data, len);
        str[len] = '\0';
            len = 63;
        memcpy(str, np->child->u.data.data, len);
        str[len] = '\0';
-       
+
        oid = odr_getoidbystr_nmem(zei->nmem, str);
 
        for (ao = *op; ao; ao = ao->next)
        oid = odr_getoidbystr_nmem(zei->nmem, str);
 
        for (ao = *op; ao; ao = ao->next)
@@ -255,7 +247,7 @@ void zebraExplain_mergeOids (ZebraExplainInfo zei, data1_node *n,
        if (!ao)
        {
            ao = (zebAccessObject) nmem_malloc(zei->nmem, sizeof(*ao));
        if (!ao)
        {
            ao = (zebAccessObject) nmem_malloc(zei->nmem, sizeof(*ao));
-           ao->handle = NULL;
+           ao->handle = 0;
            ao->sysno = 1;
            ao->oid = oid;
            ao->next = *op;
            ao->sysno = 1;
            ao->oid = oid;
            ao->next = *op;
@@ -268,13 +260,13 @@ void zebraExplain_mergeAccessInfo(ZebraExplainInfo zei, data1_node *n,
                                   zebAccessInfo *accessInfo)
 {
     data1_node *np;
                                   zebAccessInfo *accessInfo)
 {
     data1_node *np;
-    
+
     if (!n)
     {
        *accessInfo = (zebAccessInfo)
            nmem_malloc(zei->nmem, sizeof(**accessInfo));
     if (!n)
     {
        *accessInfo = (zebAccessInfo)
            nmem_malloc(zei->nmem, sizeof(**accessInfo));
-       (*accessInfo)->attributeSetIds = NULL;
-       (*accessInfo)->schemas = NULL;
+       (*accessInfo)->attributeSetIds = 0;
+       (*accessInfo)->schemas = 0;
     }
     else
     {
     }
     else
     {
@@ -340,7 +332,7 @@ ZebraExplainInfo zebraExplain_open(
     Res res,
     int writeFlag,
     void *updateHandle,
     Res res,
     int writeFlag,
     void *updateHandle,
-    int (*updateFunc)(void *handle, Record drec, data1_node *n))
+    ZebraExplainUpdateFunc *updateFunc)
 {
     Record trec;
     ZebraExplainInfo zei;
 {
     Record trec;
     ZebraExplainInfo zei;
@@ -359,17 +351,20 @@ ZebraExplainInfo zebraExplain_open(
     zei->updateFunc = updateFunc;
     zei->dirty = 0;
     zei->ordinalDatabase = 1;
     zei->updateFunc = updateFunc;
     zei->dirty = 0;
     zei->ordinalDatabase = 1;
-    zei->curDatabaseInfo = NULL;
+    zei->curDatabaseInfo = 0;
     zei->records = records;
     zei->nmem = nmem;
     zei->dh = dh;
     zei->records = records;
     zei->nmem = nmem;
     zei->dh = dh;
-    zei->attsets = NULL;
+
+    data1_get_absyn(zei->dh, "explain", DATA1_XPATH_INDEXING_DISABLE);
+
+    zei->attsets = 0;
     zei->res = res;
     zei->categoryList = (struct zebraCategoryListInfo *)
        nmem_malloc(zei->nmem, sizeof(*zei->categoryList));
     zei->categoryList->sysno = 0;
     zei->categoryList->dirty = 0;
     zei->res = res;
     zei->categoryList = (struct zebraCategoryListInfo *)
        nmem_malloc(zei->nmem, sizeof(*zei->categoryList));
     zei->categoryList->sysno = 0;
     zei->categoryList->dirty = 0;
-    zei->categoryList->data1_categoryList = NULL;
+    zei->categoryList->data1_categoryList = 0;
 
     if ( atoi(res_get_def(res, "notimestamps", "0") )== 0)
     {
 
     if ( atoi(res_get_def(res, "notimestamps", "0") )== 0)
     {
@@ -409,11 +404,23 @@ ZebraExplainInfo zebraExplain_open(
 #endif
        node_tgtinfo = data1_search_tag(zei->dh, zei->data1_target,
                                         "/targetInfo");
 #endif
        node_tgtinfo = data1_search_tag(zei->dh, zei->data1_target,
                                         "/targetInfo");
+        if (!node_tgtinfo)
+        {
+           yaz_log(YLOG_FATAL, "Node node_tgtinfo missing");
+           nmem_destroy(zei->nmem);
+           return 0;
+        }
        zebraExplain_mergeAccessInfo(zei, node_tgtinfo,
                                      &zei->accessInfo);
 
        node_zebra = data1_search_tag(zei->dh, node_tgtinfo->child,
                                       "zebraInfo");
        zebraExplain_mergeAccessInfo(zei, node_tgtinfo,
                                      &zei->accessInfo);
 
        node_zebra = data1_search_tag(zei->dh, node_tgtinfo->child,
                                       "zebraInfo");
+        if (!node_zebra)
+        {
+           yaz_log(YLOG_FATAL, "Node node_zebra missing");
+           nmem_destroy(zei->nmem);
+           return 0;
+        }
        np = 0;
        if (node_zebra)
        {
        np = 0;
        if (node_zebra)
        {
@@ -424,9 +431,9 @@ ZebraExplainInfo zebraExplain_open(
        }
        for(; np; np = np->next)
        {
        }
        for(; np; np = np->next)
        {
-           data1_node *node_name = NULL;
-           data1_node *node_id = NULL;
-           data1_node *node_aid = NULL;
+           data1_node *node_name = 0;
+           data1_node *node_id = 0;
+           data1_node *node_aid = 0;
            data1_node *np2;
            if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "database"))
                continue;
            data1_node *np2;
            if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "database"))
                continue;
@@ -442,30 +449,30 @@ ZebraExplainInfo zebraExplain_open(
                    node_aid = np2->child;
            }
            assert(node_id && node_name && node_aid);
                    node_aid = np2->child;
            }
            assert(node_id && node_name && node_aid);
-           
-           *zdip =(struct zebDatabaseInfoB *) 
+
+           *zdip =(struct zebDatabaseInfoB *)
                nmem_malloc(zei->nmem, sizeof(**zdip));
             (*zdip)->readFlag = 1;
             (*zdip)->dirty = 0;
                nmem_malloc(zei->nmem, sizeof(**zdip));
             (*zdip)->readFlag = 1;
             (*zdip)->dirty = 0;
-           (*zdip)->data1_database = NULL;
+           (*zdip)->data1_database = 0;
            (*zdip)->recordCount = 0;
            (*zdip)->recordBytes = 0;
            (*zdip)->recordCount = 0;
            (*zdip)->recordBytes = 0;
-           zebraExplain_mergeAccessInfo (zei, 0, &(*zdip)->accessInfo);
+           zebraExplain_mergeAccessInfo(zei, 0, &(*zdip)->accessInfo);
 
            (*zdip)->databaseName = (char *)
 
            (*zdip)->databaseName = (char *)
-               nmem_malloc (zei->nmem, 1+node_name->u.data.len);
+               nmem_malloc(zei->nmem, 1+node_name->u.data.len);
            memcpy((*zdip)->databaseName, node_name->u.data.data,
                   node_name->u.data.len);
            (*zdip)->databaseName[node_name->u.data.len] = '\0';
            memcpy((*zdip)->databaseName, node_name->u.data.data,
                   node_name->u.data.len);
            (*zdip)->databaseName[node_name->u.data.len] = '\0';
-           (*zdip)->sysno = atoi_zn (node_id->u.data.data,
+           (*zdip)->sysno = atoi_zn(node_id->u.data.data,
                                      node_id->u.data.len);
            (*zdip)->attributeDetails = (zebAttributeDetails)
                                      node_id->u.data.len);
            (*zdip)->attributeDetails = (zebAttributeDetails)
-               nmem_malloc (zei->nmem, sizeof(*(*zdip)->attributeDetails));
-           (*zdip)->attributeDetails->sysno = atoi_zn (node_aid->u.data.data,
+               nmem_malloc(zei->nmem, sizeof(*(*zdip)->attributeDetails));
+           (*zdip)->attributeDetails->sysno = atoi_zn(node_aid->u.data.data,
                                                        node_aid->u.data.len);
            (*zdip)->attributeDetails->readFlag = 1;
            (*zdip)->attributeDetails->dirty = 0;
                                                        node_aid->u.data.len);
            (*zdip)->attributeDetails->readFlag = 1;
            (*zdip)->attributeDetails->dirty = 0;
-           (*zdip)->attributeDetails->SUInfo = NULL;
+           (*zdip)->attributeDetails->SUInfo = 0;
 
            zdip = &(*zdip)->next;
        }
 
            zdip = &(*zdip)->next;
        }
@@ -474,30 +481,30 @@ ZebraExplainInfo zebraExplain_open(
            np = data1_search_tag(zei->dh, node_zebra->child,
                                  "ordinalSU");
            np = np->child;
            np = data1_search_tag(zei->dh, node_zebra->child,
                                  "ordinalSU");
            np = np->child;
-           assert (np && np->which == DATA1N_data);
+           assert(np && np->which == DATA1N_data);
            zei->ordinalSU = atoi_n(np->u.data.data, np->u.data.len);
            zei->ordinalSU = atoi_n(np->u.data.data, np->u.data.len);
-           
+
            np = data1_search_tag(zei->dh, node_zebra->child,
                                  "ordinalDatabase");
            np = np->child;
            np = data1_search_tag(zei->dh, node_zebra->child,
                                  "ordinalDatabase");
            np = np->child;
-           assert (np && np->which == DATA1N_data);
+           assert(np && np->which == DATA1N_data);
            zei->ordinalDatabase = atoi_n(np->u.data.data, np->u.data.len);
 
            np = data1_search_tag(zei->dh, node_zebra->child,
                                   "runNumber");
            np = np->child;
            zei->ordinalDatabase = atoi_n(np->u.data.data, np->u.data.len);
 
            np = data1_search_tag(zei->dh, node_zebra->child,
                                   "runNumber");
            np = np->child;
-           assert (np && np->which == DATA1N_data);
+           assert(np && np->which == DATA1N_data);
            zei->runNumber = atoi_zn(np->u.data.data, np->u.data.len);
             yaz_log(YLOG_DEBUG, "read runnumber=" ZINT_FORMAT, zei->runNumber);
            zei->runNumber = atoi_zn(np->u.data.data, np->u.data.len);
             yaz_log(YLOG_DEBUG, "read runnumber=" ZINT_FORMAT, zei->runNumber);
-           *zdip = NULL;
+           *zdip = 0;
        }
        }
-       rec_rm(&trec);
+       rec_free(&trec);
     }
     else  /* create initial targetInfo */
     {
        data1_node *node_tgtinfo;
 
     }
     else  /* create initial targetInfo */
     {
        data1_node *node_tgtinfo;
 
-       *zdip = NULL;
+       *zdip = 0;
        if (writeFlag)
        {
            char *sgml_buf;
        if (writeFlag)
        {
            char *sgml_buf;
@@ -536,29 +543,29 @@ ZebraExplainInfo zebraExplain_open(
                rec_strdup("grs.sgml", &trec->size[recInfo_fileType]);
            trec->info[recInfo_databaseName] =
                rec_strdup("IR-Explain-1", &trec->size[recInfo_databaseName]);
                rec_strdup("grs.sgml", &trec->size[recInfo_fileType]);
            trec->info[recInfo_databaseName] =
                rec_strdup("IR-Explain-1", &trec->size[recInfo_databaseName]);
-           
+
            sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
            trec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
            memcpy(trec->info[recInfo_storeData], sgml_buf, sgml_len);
            trec->size[recInfo_storeData] = sgml_len;
            sgml_buf = data1_nodetoidsgml(dh, zei->data1_target, 0, &sgml_len);
            trec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
            memcpy(trec->info[recInfo_storeData], sgml_buf, sgml_len);
            trec->size[recInfo_storeData] = sgml_len;
-               
+
            rec_put(records, &trec);
            rec_put(records, &trec);
-           rec_rm(&trec);
+           rec_free(&trec);
        }
        }
-       
+
        zebraExplain_newDatabase(zei, "IR-Explain-1", 0);
        zebraExplain_newDatabase(zei, "IR-Explain-1", 0);
-           
+
        if (!zei->categoryList->dirty)
        {
            struct zebraCategoryListInfo *zcl = zei->categoryList;
            data1_node *node_cl;
        if (!zei->categoryList->dirty)
        {
            struct zebraCategoryListInfo *zcl = zei->categoryList;
            data1_node *node_cl;
-           
+
            zcl->dirty = 1;
            zcl->data1_categoryList =
                data1_read_sgml(zei->dh, zei->nmem,
                                 "<explain><categoryList>CategoryList\n"
                                 "</></>\n");
            zcl->dirty = 1;
            zcl->data1_categoryList =
                data1_read_sgml(zei->dh, zei->nmem,
                                 "<explain><categoryList>CategoryList\n"
                                 "</></>\n");
-       
+
            if (zcl->data1_categoryList)
            {
                node_cl = data1_search_tag(zei->dh, zcl->data1_categoryList,
            if (zcl->data1_categoryList)
            {
                node_cl = data1_search_tag(zei->dh, zcl->data1_categoryList,
@@ -578,7 +585,7 @@ static void zebraExplain_readAttributeDetails(ZebraExplainInfo zei,
     struct zebSUInfoB **zsuip = &zad->SUInfo;
     data1_node *node_adinfo, *node_zebra, *node_list, *np;
 
     struct zebSUInfoB **zsuip = &zad->SUInfo;
     data1_node *node_adinfo, *node_zebra, *node_list, *np;
 
-    assert (zad->sysno);
+    assert(zad->sysno);
     rec = rec_get(zei->records, zad->sysno);
 
     zad->data1_tree = read_sgml_rec(zei->dh, zei->nmem, rec);
     rec = rec_get(zei->records, zad->sysno);
 
     zad->data1_tree = read_sgml_rec(zei->dh, zei->nmem, rec);
@@ -591,16 +598,13 @@ static void zebraExplain_readAttributeDetails(ZebraExplainInfo zei,
                                  "attrlist");
     for (np = node_list->child; np; np = np->next)
     {
                                  "attrlist");
     for (np = node_list->child; np; np = np->next)
     {
-       data1_node *node_set = NULL;
-       data1_node *node_use = NULL;
-       data1_node *node_str = NULL;
-       data1_node *node_ordinal = NULL;
-       data1_node *node_type = NULL;
-        data1_node *node_doc_occurrences = NULL;
-        data1_node *node_term_occurrences = NULL;
+       data1_node *node_str = 0;
+       data1_node *node_ordinal = 0;
+       data1_node *node_type = 0;
+       data1_node *node_cat = 0;
+        data1_node *node_doc_occurrences = 0;
+        data1_node *node_term_occurrences = 0;
        data1_node *np2;
        data1_node *np2;
-       char oid_str[128];
-       int oid_str_len;
 
        if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "attr"))
            continue;
 
        if (np->which != DATA1N_tag || strcmp(np->u.tag.tag, "attr"))
            continue;
@@ -609,16 +613,14 @@ static void zebraExplain_readAttributeDetails(ZebraExplainInfo zei,
            if (np2->which != DATA1N_tag || !np2->child ||
                np2->child->which != DATA1N_data)
                continue;
            if (np2->which != DATA1N_tag || !np2->child ||
                np2->child->which != DATA1N_data)
                continue;
-           if (!strcmp(np2->u.tag.tag, "set"))
-               node_set = np2->child;
-           else if (!strcmp(np2->u.tag.tag, "use"))
-               node_use = np2->child;
-           else if (!strcmp(np2->u.tag.tag, "str"))
+           if (!strcmp(np2->u.tag.tag, "str"))
                node_str = np2->child;
            else if (!strcmp(np2->u.tag.tag, "ordinal"))
                node_ordinal = np2->child;
            else if (!strcmp(np2->u.tag.tag, "type"))
                node_type = np2->child;
                node_str = np2->child;
            else if (!strcmp(np2->u.tag.tag, "ordinal"))
                node_ordinal = np2->child;
            else if (!strcmp(np2->u.tag.tag, "type"))
                node_type = np2->child;
+           else if (!strcmp(np2->u.tag.tag, "cat"))
+               node_cat = np2->child;
            else if (!strcmp(np2->u.tag.tag, "dococcurrences"))
                node_doc_occurrences = np2->child;
            else if (!strcmp(np2->u.tag.tag, "termoccurrences"))
            else if (!strcmp(np2->u.tag.tag, "dococcurrences"))
                node_doc_occurrences = np2->child;
            else if (!strcmp(np2->u.tag.tag, "termoccurrences"))
@@ -635,12 +637,40 @@ static void zebraExplain_readAttributeDetails(ZebraExplainInfo zei,
            nmem_malloc(zei->nmem, sizeof(**zsuip));
 
        if (node_type && node_type->u.data.len > 0)
            nmem_malloc(zei->nmem, sizeof(**zsuip));
 
        if (node_type && node_type->u.data.len > 0)
-           (*zsuip)->info.index_type =  node_type->u.data.data[0];
+           (*zsuip)->info.index_type =
+                nmem_strdupn(zei->nmem,
+                             node_type->u.data.data,
+                             node_type->u.data.len);
        else
        {
            yaz_log(YLOG_WARN, "Missing attribute 'type' in attribute info");
        else
        {
            yaz_log(YLOG_WARN, "Missing attribute 'type' in attribute info");
-           (*zsuip)->info.index_type = 'w';
+           (*zsuip)->info.index_type = "w";
        }
        }
+        if (node_cat && node_cat->u.data.len > 0)
+        {
+            zinfo_index_category_t cat;
+
+            data1_node *np = node_cat;
+            if (!strncmp(np->u.data.data, "index", np->u.data.len))
+                cat = zinfo_index_category_index;
+            else if (!strncmp(np->u.data.data, "sort", np->u.data.len))
+                cat = zinfo_index_category_sort;
+            else if (!strncmp(np->u.data.data, "alwaysmatches",
+                              np->u.data.len))
+                cat = zinfo_index_category_alwaysmatches;
+            else if (!strncmp(np->u.data.data, "anchor",
+                              np->u.data.len))
+                cat = zinfo_index_category_anchor;
+            else
+            {
+                yaz_log(YLOG_WARN, "Bad index cateogry '%.*s'",
+                        np->u.data.len, np->u.data.data);
+                cat = zinfo_index_category_index;
+            }
+            (*zsuip)->info.cat = cat;
+        }
+        else
+            (*zsuip)->info.cat = zinfo_index_category_index;
 
         if (node_doc_occurrences)
         {
 
         if (node_doc_occurrences)
         {
@@ -654,89 +684,69 @@ static void zebraExplain_readAttributeDetails(ZebraExplainInfo zei,
             (*zsuip)->info.term_occurrences = atoi_zn(np->u.data.data,
                                                       np->u.data.len);
         }
             (*zsuip)->info.term_occurrences = atoi_zn(np->u.data.data,
                                                       np->u.data.len);
         }
-       if (node_set && node_use)
-       {
-           (*zsuip)->info.which = ZEB_SU_SET_USE;
-           
-           oid_str_len = node_set->u.data.len;
-           if (oid_str_len >= (int) sizeof(oid_str))
-               oid_str_len = sizeof(oid_str)-1;
-           memcpy(oid_str, node_set->u.data.data, oid_str_len);
-           oid_str[oid_str_len] = '\0';
-
-           (*zsuip)->info.u.su.set = oid_getvalbyname(oid_str);
-           
-           (*zsuip)->info.u.su.use = atoi_n(node_use->u.data.data,
-                                        node_use->u.data.len);
-           yaz_log(YLOG_DEBUG, "set=%d use=%d ordinal=%d",
-                    (*zsuip)->info.u.su.set, (*zsuip)->info.u.su.use,
-                    (*zsuip)->info.ordinal);
-       }
-       else if (node_str)
+       if (node_str)
        {
        {
-           (*zsuip)->info.which = ZEB_SU_STR;
-           
-           (*zsuip)->info.u.str = nmem_strdupn(zei->nmem,
-                                               node_str->u.data.data,
-                                               node_str->u.data.len);
+           (*zsuip)->info.str = nmem_strdupn(zei->nmem,
+                                              node_str->u.data.data,
+                                              node_str->u.data.len);
        }
        else
        {
            yaz_log(YLOG_WARN, "Missing set/use/str in attribute info");
            continue;
        }
        }
        else
        {
            yaz_log(YLOG_WARN, "Missing set/use/str in attribute info");
            continue;
        }
-       (*zsuip)->info.ordinal = atoi_n (node_ordinal->u.data.data,
+       (*zsuip)->info.ordinal = atoi_n(node_ordinal->u.data.data,
                                         node_ordinal->u.data.len);
         zsuip = &(*zsuip)->next;
     }
                                         node_ordinal->u.data.len);
         zsuip = &(*zsuip)->next;
     }
-    *zsuip = NULL;
+    *zsuip = 0;
     zad->readFlag = 0;
     zad->readFlag = 0;
-    rec_rm (&rec);
+    rec_free(&rec);
 }
 
 }
 
-static void zebraExplain_readDatabase (ZebraExplainInfo zei,
-                                      struct zebDatabaseInfoB *zdi)
+static void zebraExplain_readDatabase(ZebraExplainInfo zei,
+                                      struct zebDatabaseInfoB *zdi)
 {
     Record rec;
     data1_node *node_dbinfo, *node_zebra, *np;
 
 {
     Record rec;
     data1_node *node_dbinfo, *node_zebra, *np;
 
-    assert (zdi->sysno);
-    rec = rec_get (zei->records, zdi->sysno);
+    assert(zdi->sysno);
+    rec = rec_get(zei->records, zdi->sysno);
 
 
-    zdi->data1_database = read_sgml_rec (zei->dh, zei->nmem, rec);
-    
-    node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
+    zdi->data1_database = read_sgml_rec(zei->dh, zei->nmem, rec);
+
+    node_dbinfo = data1_search_tag(zei->dh, zdi->data1_database,
                                     "/databaseInfo");
                                     "/databaseInfo");
-    assert (node_dbinfo);
-    zebraExplain_mergeAccessInfo (zei, node_dbinfo, &zdi->accessInfo);
+    assert(node_dbinfo);
+    zebraExplain_mergeAccessInfo(zei, node_dbinfo, &zdi->accessInfo);
 
 
-    node_zebra = data1_search_tag (zei->dh, node_dbinfo->child,
+    node_zebra = data1_search_tag(zei->dh, node_dbinfo->child,
                                 "zebraInfo");
     if (node_zebra
                                 "zebraInfo");
     if (node_zebra
-       && (np = data1_search_tag (zei->dh, node_zebra->child,
-                                  "recordBytes")) 
+       && (np = data1_search_tag(zei->dh, node_zebra->child,
+                                  "recordBytes"))
        && np->child && np->child->which == DATA1N_data)
        && np->child && np->child->which == DATA1N_data)
-       zdi->recordBytes = atoi_zn (np->child->u.data.data,
+       zdi->recordBytes = atoi_zn(np->child->u.data.data,
                                    np->child->u.data.len);
 
     if (node_zebra
                                    np->child->u.data.len);
 
     if (node_zebra
-       && (np = data1_search_tag (zei->dh, node_zebra->child,
-                                  "ordinalDatabase")) 
+       && (np = data1_search_tag(zei->dh, node_zebra->child,
+                                  "ordinalDatabase"))
        && np->child && np->child->which == DATA1N_data)
        zdi->ordinalDatabase = atoi_n(np->child->u.data.data,
                                      np->child->u.data.len);
 
        && np->child && np->child->which == DATA1N_data)
        zdi->ordinalDatabase = atoi_n(np->child->u.data.data,
                                      np->child->u.data.len);
 
-    if ((np = data1_search_tag (zei->dh, node_dbinfo->child,
+    if ((np = data1_search_tag(zei->dh, node_dbinfo->child,
                                "recordCount")) &&
                                "recordCount")) &&
-       (np = data1_search_tag (zei->dh, np->child,
+       (np = data1_search_tag(zei->dh, np->child,
                                "recordCountActual")) &&
        np->child->which == DATA1N_data)
     {
                                "recordCountActual")) &&
        np->child->which == DATA1N_data)
     {
-       zdi->recordCount = atoi_zn (np->child->u.data.data,
+       zdi->recordCount = atoi_zn(np->child->u.data.data,
                                    np->child->u.data.len);
     }
     zdi->readFlag = 0;
                                    np->child->u.data.len);
     }
     zdi->readFlag = 0;
-    rec_rm (&rec);
+    rec_free(&rec);
 }
 
 int zebraExplain_removeDatabase(ZebraExplainInfo zei, void *update_handle)
 }
 
 int zebraExplain_removeDatabase(ZebraExplainInfo zei, void *update_handle)
@@ -757,15 +767,15 @@ int zebraExplain_removeDatabase(ZebraExplainInfo zei, void *update_handle)
            {
                /* remove attribute details keys and delete it */
                zebAttributeDetails zad = zdi->attributeDetails;
            {
                /* remove attribute details keys and delete it */
                zebAttributeDetails zad = zdi->attributeDetails;
-               
+
                rec = rec_get(zei->records, zad->sysno);
                (*zei->updateFunc)(zei->updateHandle, rec, 0);
                rec = rec_get(zei->records, zad->sysno);
                (*zei->updateFunc)(zei->updateHandle, rec, 0);
-               rec_rm(&rec);
+               rec_del(zei->records, &rec);
            }
            /* remove database record keys and delete it */
            }
            /* remove database record keys and delete it */
-           rec = rec_get (zei->records, zdi->sysno);
+           rec = rec_get(zei->records, zdi->sysno);
            (*zei->updateFunc)(zei->updateHandle, rec, 0);
            (*zei->updateFunc)(zei->updateHandle, rec, 0);
-           rec_rm(&rec);
+           rec_del(zei->records, &rec);
 
            /* remove from list */
            *zdip = zdi->next;
 
            /* remove from list */
            *zdip = zdi->next;
@@ -778,23 +788,23 @@ int zebraExplain_removeDatabase(ZebraExplainInfo zei, void *update_handle)
     return -1;
 }
 
     return -1;
 }
 
-int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
+int zebraExplain_curDatabase(ZebraExplainInfo zei, const char *database)
 {
     struct zebDatabaseInfoB *zdi;
 {
     struct zebDatabaseInfoB *zdi;
-    const char *database_n = strrchr (database, '/');
+    const char *database_n = strrchr(database, '/');
 
     if (database_n)
         database_n++;
     else
         database_n = database;
 
     if (database_n)
         database_n++;
     else
         database_n = database;
-    
-    assert (zei);
+
+    assert(zei);
     if (zei->curDatabaseInfo &&
     if (zei->curDatabaseInfo &&
-        !STRCASECMP (zei->curDatabaseInfo->databaseName, database))
+        !STRCASECMP(zei->curDatabaseInfo->databaseName, database))
         return 0;
     for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
     {
         return 0;
     for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
     {
-        if (!STRCASECMP (zdi->databaseName, database_n))
+        if (!STRCASECMP(zdi->databaseName, database_n))
             break;
     }
     if (!zdi)
             break;
     }
     if (!zdi)
@@ -807,76 +817,75 @@ int zebraExplain_curDatabase (ZebraExplainInfo zei, const char *database)
 #if ZINFO_DEBUG
        yaz_log(YLOG_LOG, "zebraExplain_readDatabase: %s", database);
 #endif
 #if ZINFO_DEBUG
        yaz_log(YLOG_LOG, "zebraExplain_readDatabase: %s", database);
 #endif
-        zebraExplain_readDatabase (zei, zdi);
+        zebraExplain_readDatabase(zei, zdi);
     }
     if (zdi->attributeDetails->readFlag)
     {
 #if ZINFO_DEBUG
        yaz_log(YLOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
 #endif
     }
     if (zdi->attributeDetails->readFlag)
     {
 #if ZINFO_DEBUG
        yaz_log(YLOG_LOG, "zebraExplain_readAttributeDetails: %s", database);
 #endif
-        zebraExplain_readAttributeDetails (zei, zdi->attributeDetails);
+        zebraExplain_readAttributeDetails(zei, zdi->attributeDetails);
     }
     zei->curDatabaseInfo = zdi;
     return 0;
 }
 
     }
     zei->curDatabaseInfo = zdi;
     return 0;
 }
 
-static void zebraExplain_initCommonInfo (ZebraExplainInfo zei, data1_node *n)
+static void zebraExplain_initCommonInfo(ZebraExplainInfo zei, data1_node *n)
 {
 {
-    data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "commonInfo", 0, n);
-    data1_mk_tag_data_text (zei->dh, c, "dateAdded", zei->date, zei->nmem);
-    data1_mk_tag_data_text (zei->dh, c, "dateChanged", zei->date, zei->nmem);
-    data1_mk_tag_data_text (zei->dh, c, "languageCode", "EN", zei->nmem);
+    data1_node *c = data1_mk_tag(zei->dh, zei->nmem, "commonInfo", 0, n);
+    data1_mk_tag_data_text(zei->dh, c, "dateAdded", zei->date, zei->nmem);
+    data1_mk_tag_data_text(zei->dh, c, "dateChanged", zei->date, zei->nmem);
+    data1_mk_tag_data_text(zei->dh, c, "languageCode", "EN", zei->nmem);
 }
 
 }
 
-static void zebraExplain_updateCommonInfo (ZebraExplainInfo zei, data1_node *n)
+static void zebraExplain_updateCommonInfo(ZebraExplainInfo zei, data1_node *n)
 {
 {
-    data1_node *c = data1_search_tag (zei->dh, n->child, "commonInfo");
-    assert (c);
-    data1_mk_tag_data_text_uni (zei->dh, c, "dateChanged", zei->date,
+    data1_node *c = data1_search_tag(zei->dh, n->child, "commonInfo");
+    assert(c);
+    data1_mk_tag_data_text_uni(zei->dh, c, "dateChanged", zei->date,
                                 zei->nmem);
 }
 
                                 zei->nmem);
 }
 
-static void zebraExplain_initAccessInfo (ZebraExplainInfo zei, data1_node *n)
+static void zebraExplain_initAccessInfo(ZebraExplainInfo zei, data1_node *n)
 {
 {
-    data1_node *c = data1_mk_tag (zei->dh, zei->nmem, "accessInfo", 0, n);
-    data1_node *d = data1_mk_tag (zei->dh, zei->nmem, "unitSystems", 0, c);
-    data1_mk_tag_data_text (zei->dh, d, "string", "ISO", zei->nmem);
+    data1_node *c = data1_mk_tag(zei->dh, zei->nmem, "accessInfo", 0, n);
+    data1_node *d = data1_mk_tag(zei->dh, zei->nmem, "unitSystems", 0, c);
+    data1_mk_tag_data_text(zei->dh, d, "string", "ISO", zei->nmem);
 }
 
 }
 
-static void zebraExplain_updateAccessInfo (ZebraExplainInfo zei, data1_node *n,
+static void zebraExplain_updateAccessInfo(ZebraExplainInfo zei, data1_node *n,
                                           zebAccessInfo accessInfo)
 {
                                           zebAccessInfo accessInfo)
 {
-    data1_node *c = data1_search_tag (zei->dh, n->child, "accessInfo");
+    data1_node *c = data1_search_tag(zei->dh, n->child, "accessInfo");
     data1_node *d;
     zebAccessObject p;
     data1_node *d;
     zebAccessObject p;
-    
+
     if (!c)
     {
     if (!c)
     {
-        data1_pr_tree (zei->dh, n, stdout);
-        exit (0);
-        assert (c);
+        data1_pr_tree(zei->dh, n, stdout);
+        zebra_exit("zebraExplain_updateAccessInfo");
     }
 
     if ((p = accessInfo->attributeSetIds))
     {
     }
 
     if ((p = accessInfo->attributeSetIds))
     {
-       d = data1_mk_tag_uni (zei->dh, zei->nmem, "attributeSetIds", c);
+       d = data1_mk_tag_uni(zei->dh, zei->nmem, "attributeSetIds", c);
        for (; p; p = p->next)
        for (; p; p = p->next)
-           data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
+           data1_mk_tag_data_oid(zei->dh, d, "oid", p->oid, zei->nmem);
     }
     if ((p = accessInfo->schemas))
     {
     }
     if ((p = accessInfo->schemas))
     {
-       d = data1_mk_tag_uni (zei->dh, zei->nmem, "schemas", c);
+       d = data1_mk_tag_uni(zei->dh, zei->nmem, "schemas", c);
        for (; p; p = p->next)
        for (; p; p = p->next)
-           data1_mk_tag_data_oid (zei->dh, d, "oid", p->oid, zei->nmem);
+           data1_mk_tag_data_oid(zei->dh, d, "oid", p->oid, zei->nmem);
     }
 }
 
     }
 }
 
-int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
+int zebraExplain_newDatabase(ZebraExplainInfo zei, const char *database,
                              int explain_database)
 {
     struct zebDatabaseInfoB *zdi;
     data1_node *node_dbinfo, *node_adinfo;
                              int explain_database)
 {
     struct zebDatabaseInfoB *zdi;
     data1_node *node_dbinfo, *node_adinfo;
-    const char *database_n = strrchr (database, '/');
+    const char *database_n = strrchr(database, '/');
 
     if (database_n)
         database_n++;
 
     if (database_n)
         database_n++;
@@ -886,113 +895,89 @@ int zebraExplain_newDatabase (ZebraExplainInfo zei, const char *database,
 #if ZINFO_DEBUG
     yaz_log(YLOG_LOG, "zebraExplain_newDatabase: %s", database);
 #endif
 #if ZINFO_DEBUG
     yaz_log(YLOG_LOG, "zebraExplain_newDatabase: %s", database);
 #endif
-    assert (zei);
+    assert(zei);
     for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
     {
     for (zdi = zei->databaseInfo; zdi; zdi=zdi->next)
     {
-        if (!STRCASECMP (zdi->databaseName, database_n))
+        if (!STRCASECMP(zdi->databaseName, database_n))
             break;
     }
     if (zdi)
         return -1;
     /* it's new really. make it */
             break;
     }
     if (zdi)
         return -1;
     /* it's new really. make it */
-    zdi = (struct zebDatabaseInfoB *) nmem_malloc (zei->nmem, sizeof(*zdi));
+    zdi = (struct zebDatabaseInfoB *) nmem_malloc(zei->nmem, sizeof(*zdi));
     zdi->next = zei->databaseInfo;
     zei->databaseInfo = zdi;
     zdi->sysno = 0;
     zdi->recordCount = 0;
     zdi->recordBytes = 0;
     zdi->readFlag = 0;
     zdi->next = zei->databaseInfo;
     zei->databaseInfo = zdi;
     zdi->sysno = 0;
     zdi->recordCount = 0;
     zdi->recordBytes = 0;
     zdi->readFlag = 0;
-    zdi->databaseName = nmem_strdup (zei->nmem, database_n);
+    zdi->databaseName = nmem_strdup(zei->nmem, database_n);
 
     zdi->ordinalDatabase = zei->ordinalDatabase++;
 
 
     zdi->ordinalDatabase = zei->ordinalDatabase++;
 
-    zebraExplain_mergeAccessInfo (zei, 0, &zdi->accessInfo);
-    
-    assert (zei->dh);
-    assert (zei->nmem);
+    zebraExplain_mergeAccessInfo(zei, 0, &zdi->accessInfo);
+
+    assert(zei->dh);
+    assert(zei->nmem);
 
     zdi->data1_database =
 
     zdi->data1_database =
-       data1_read_sgml (zei->dh, zei->nmem, 
+       data1_read_sgml(zei->dh, zei->nmem,
                         "<explain><databaseInfo>DatabaseInfo\n"
                         "</></>\n");
     if (!zdi->data1_database)
        return -2;
 
                         "<explain><databaseInfo>DatabaseInfo\n"
                         "</></>\n");
     if (!zdi->data1_database)
        return -2;
 
-    node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
+    node_dbinfo = data1_search_tag(zei->dh, zdi->data1_database,
                                     "/databaseInfo");
                                     "/databaseInfo");
-    assert (node_dbinfo);
+    assert(node_dbinfo);
 
 
-    zebraExplain_initCommonInfo (zei, node_dbinfo);
-    zebraExplain_initAccessInfo (zei, node_dbinfo);
+    zebraExplain_initCommonInfo(zei, node_dbinfo);
+    zebraExplain_initAccessInfo(zei, node_dbinfo);
 
 
-    data1_mk_tag_data_text (zei->dh, node_dbinfo, "name",
+    data1_mk_tag_data_text(zei->dh, node_dbinfo, "name",
                               database, zei->nmem);
                               database, zei->nmem);
-    
+
     if (explain_database)
     if (explain_database)
-       data1_mk_tag_data_text (zei->dh, node_dbinfo, "explainDatabase",
+       data1_mk_tag_data_text(zei->dh, node_dbinfo, "explainDatabase",
                                "", zei->nmem);
                                "", zei->nmem);
-    
-    data1_mk_tag_data_text (zei->dh, node_dbinfo, "userFee",
+
+    data1_mk_tag_data_text(zei->dh, node_dbinfo, "userFee",
                            "0", zei->nmem);
                            "0", zei->nmem);
-    
-    data1_mk_tag_data_text (zei->dh, node_dbinfo, "available",
+
+    data1_mk_tag_data_text(zei->dh, node_dbinfo, "available",
                            "1", zei->nmem);
                            "1", zei->nmem);
-    
+
 #if ZINFO_DEBUG
 #if ZINFO_DEBUG
-    data1_pr_tree (zei->dh, zdi->data1_database, stderr);
+    data1_pr_tree(zei->dh, zdi->data1_database, stderr);
 #endif
     zdi->dirty = 1;
     zei->dirty = 1;
     zei->curDatabaseInfo = zdi;
 
     zdi->attributeDetails = (zebAttributeDetails)
 #endif
     zdi->dirty = 1;
     zei->dirty = 1;
     zei->curDatabaseInfo = zdi;
 
     zdi->attributeDetails = (zebAttributeDetails)
-       nmem_malloc (zei->nmem, sizeof(*zdi->attributeDetails));
+       nmem_malloc(zei->nmem, sizeof(*zdi->attributeDetails));
     zdi->attributeDetails->readFlag = 0;
     zdi->attributeDetails->sysno = 0;
     zdi->attributeDetails->dirty = 1;
     zdi->attributeDetails->readFlag = 0;
     zdi->attributeDetails->sysno = 0;
     zdi->attributeDetails->dirty = 1;
-    zdi->attributeDetails->SUInfo = NULL;
+    zdi->attributeDetails->SUInfo = 0;
     zdi->attributeDetails->data1_tree =
     zdi->attributeDetails->data1_tree =
-       data1_read_sgml (zei->dh, zei->nmem,
+       data1_read_sgml(zei->dh, zei->nmem,
                         "<explain><attributeDetails>AttributeDetails\n"
                         "</></>\n");
 
                         "<explain><attributeDetails>AttributeDetails\n"
                         "</></>\n");
 
-    node_adinfo = data1_search_tag (zei->dh, zdi->attributeDetails->data1_tree,
+    node_adinfo = data1_search_tag(zei->dh, zdi->attributeDetails->data1_tree,
                                     "/attributeDetails");
                                     "/attributeDetails");
-    assert (node_adinfo);
+    assert(node_adinfo);
 
 
-    zebraExplain_initCommonInfo (zei, node_adinfo);
+    zebraExplain_initCommonInfo(zei, node_adinfo);
+
+    data1_mk_tag_data_text(zei->dh, node_adinfo, "name", database, zei->nmem);
 
     return 0;
 }
 
 
     return 0;
 }
 
-static void writeAttributeValueDetails (ZebraExplainInfo zei,
-                                 zebAttributeDetails zad,
-                                 data1_node *node_atvs, data1_attset *attset)
-
-{
-    struct zebSUInfoB *zsui;
-    int set_ordinal = attset->reference;
-    data1_attset_child *c;
 
 
-    for (c = attset->children; c; c = c->next)
-       writeAttributeValueDetails (zei, zad, node_atvs, c->child);
-    for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
-    {
-       if (zsui->info.which == ZEB_SU_SET_USE && 
-           set_ordinal == zsui->info.u.su.set)
-       {
-           data1_node *node_attvalue, *node_value;
-           node_attvalue = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
-                                         0 /* attr */, node_atvs);
-           node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
-                                      0 /* attr */, node_attvalue);
-           data1_mk_tag_data_int (zei->dh, node_value, "numeric",
-                                  zsui->info.u.su.use, zei->nmem);
-       }
-    }
-}
-
-static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
+static void zebraExplain_writeCategoryList(ZebraExplainInfo zei,
                                            struct zebraCategoryListInfo *zcl,
                                            int key_flush)
 {
                                            struct zebraCategoryListInfo *zcl,
                                            int key_flush)
 {
@@ -1001,43 +986,43 @@ static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
     int i;
     Record drec;
     data1_node *node_ci, *node_categoryList;
     int i;
     Record drec;
     data1_node *node_ci, *node_categoryList;
-    SYSNO sysno = 0;
+    zint sysno = 0;
     static char *category[] = {
        "CategoryList",
        "TargetInfo",
        "DatabaseInfo",
        "AttributeDetails",
     static char *category[] = {
        "CategoryList",
        "TargetInfo",
        "DatabaseInfo",
        "AttributeDetails",
-       NULL
+       0
     };
 
     };
 
-    assert (zcl);
+    assert(zcl);
     if (!zcl->dirty)
        return ;
     if (!zcl->dirty)
        return ;
-    zcl->dirty = 1;
+    zcl->dirty = 0;
     node_categoryList = zcl->data1_categoryList;
 
 #if ZINFO_DEBUG
     yaz_log(YLOG_LOG, "zebraExplain_writeCategoryList");
 #endif
 
     node_categoryList = zcl->data1_categoryList;
 
 #if ZINFO_DEBUG
     yaz_log(YLOG_LOG, "zebraExplain_writeCategoryList");
 #endif
 
-    drec = createRecord (zei->records, &sysno);
+    drec = createRecord(zei->records, &sysno);
     if (!drec)
        return;
     if (!drec)
        return;
-    
-    node_ci = data1_search_tag (zei->dh, node_categoryList,
+
+    node_ci = data1_search_tag(zei->dh, node_categoryList,
                                "/categoryList");
     assert (node_ci);
                                "/categoryList");
     assert (node_ci);
-    node_ci = data1_mk_tag (zei->dh, zei->nmem, "categories", 0 /* attr */,
+    node_ci = data1_mk_tag(zei->dh, zei->nmem, "categories", 0 /* attr */,
                             node_ci);
     assert (node_ci);
                             node_ci);
     assert (node_ci);
-    
+
     for (i = 0; category[i]; i++)
     {
     for (i = 0; category[i]; i++)
     {
-       data1_node *node_cat = data1_mk_tag (zei->dh, zei->nmem,  "category",
+       data1_node *node_cat = data1_mk_tag(zei->dh, zei->nmem,  "category",
                                              0 /* attr */, node_ci);
 
                                              0 /* attr */, node_ci);
 
-       data1_mk_tag_data_text (zei->dh, node_cat, "name",
-                               category[i], zei->nmem);
+       data1_mk_tag_data_text(zei->dh, node_cat, "name",
+                               category[i], zei->nmem);
     }
     /* extract *searchable* keys from it. We do this here, because
        record count, etc. is affected */
     }
     /* extract *searchable* keys from it. We do this here, because
        record count, etc. is affected */
@@ -1046,17 +1031,17 @@ static void zebraExplain_writeCategoryList (ZebraExplainInfo zei,
 
     /* convert to "SGML" and write it */
 #if ZINFO_DEBUG
 
     /* convert to "SGML" and write it */
 #if ZINFO_DEBUG
-    data1_pr_tree (zei->dh, node_categoryList, stderr);
+    data1_pr_tree(zei->dh, node_categoryList, stderr);
 #endif
     sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
 #endif
     sgml_buf = data1_nodetoidsgml(zei->dh, node_categoryList, 0, &sgml_len);
-    drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
-    memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
+    drec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
+    memcpy(drec->info[recInfo_storeData], sgml_buf, sgml_len);
     drec->size[recInfo_storeData] = sgml_len;
     drec->size[recInfo_storeData] = sgml_len;
-    
-    rec_put (zei->records, &drec);
+
+    rec_put(zei->records, &drec);
 }
 
 }
 
-static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
+static void zebraExplain_writeAttributeDetails(ZebraExplainInfo zei,
                                                zebAttributeDetails zad,
                                                const char *databaseName,
                                                int key_flush)
                                                zebAttributeDetails zad,
                                                const char *databaseName,
                                                int key_flush)
@@ -1064,152 +1049,84 @@ static void zebraExplain_writeAttributeDetails (ZebraExplainInfo zei,
     char *sgml_buf;
     int sgml_len;
     Record drec;
     char *sgml_buf;
     int sgml_len;
     Record drec;
-    data1_node *node_adinfo, *node_list, *node_zebra, *node_attributesBySet;
+    data1_node *node_adinfo, *node_list, *node_zebra;
     struct zebSUInfoB *zsui;
     struct zebSUInfoB *zsui;
-    int set_min;
-    
+
     if (!zad->dirty)
        return;
     if (!zad->dirty)
        return;
-    
+
     zad->dirty = 0;
 #if ZINFO_DEBUG
     zad->dirty = 0;
 #if ZINFO_DEBUG
-    yaz_log(YLOG_LOG, "zebraExplain_writeAttributeDetails");    
+    yaz_log(YLOG_LOG, "zebraExplain_writeAttributeDetails");
+    data1_pr_tree(zei->dh, zad->data1_tree, stderr);
 #endif
 
 #endif
 
-    drec = createRecord (zei->records, &zad->sysno);
+    drec = createRecord(zei->records, &zad->sysno);
     if (!drec)
        return;
     if (!drec)
        return;
-    assert (zad->data1_tree);
+    assert(zad->data1_tree);
 
 
-    node_adinfo = data1_search_tag (zei->dh, zad->data1_tree,
+    node_adinfo = data1_search_tag(zei->dh, zad->data1_tree,
                                   "/attributeDetails");
                                   "/attributeDetails");
-    zebraExplain_updateCommonInfo (zei, node_adinfo);
+    zebraExplain_updateCommonInfo(zei, node_adinfo);
 
 
-    data1_mk_tag_data_text (zei->dh, node_adinfo, "name",
-                           databaseName, zei->nmem);
+    /* zebra info (private) .. no children yet.. so se don't index zebraInfo */
+    node_zebra = data1_mk_tag_uni(zei->dh, zei->nmem,
+                                "zebraInfo", node_adinfo);
 
     /* extract *searchable* keys from it. We do this here, because
        record count, etc. is affected */
     if (key_flush)
        (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
 
     /* extract *searchable* keys from it. We do this here, because
        record count, etc. is affected */
     if (key_flush)
        (*zei->updateFunc)(zei->updateHandle, drec, zad->data1_tree);
-
-    node_attributesBySet = data1_mk_tag_uni (zei->dh, zei->nmem,
-                                          "attributesBySet", node_adinfo);
-    set_min = -1;
-    while (1)
-    {
-       data1_node *node_asd;
-       data1_attset *attset;
-       int set_ordinal = -1;
-       for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
-       {
-           if (zsui->info.which == ZEB_SU_SET_USE &&
-               (set_ordinal < 0 || set_ordinal > zsui->info.u.su.set)
-               && zsui->info.u.su.set > set_min)
-               set_ordinal = zsui->info.u.su.set;
-       }
-       if (set_ordinal < 0)
-           break;
-       set_min = set_ordinal;
-       node_asd = data1_mk_tag (zei->dh, zei->nmem,
-                                 "attributeSetDetails",
-                                 0 /* attr */, node_attributesBySet);
-
-       attset = data1_attset_search_id (zei->dh, set_ordinal);
-       if (!attset)
-       {
-           zebraExplain_loadAttsets (zei->dh, zei->res);
-           attset = data1_attset_search_id (zei->dh, set_ordinal);
-       }
-       if (attset)
-       {
-           int oid[OID_SIZE];
-           oident oe;
-           
-           oe.proto = PROTO_Z3950;
-           oe.oclass = CLASS_ATTSET;
-           oe.value = (enum oid_value) set_ordinal;
-           
-           if (oid_ent_to_oid (&oe, oid))
-           {
-               data1_node *node_abt, *node_atd, *node_atvs;
-               data1_mk_tag_data_oid (zei->dh, node_asd, "oid",
-                                      oid, zei->nmem);
-               
-               node_abt = data1_mk_tag (zei->dh, zei->nmem,
-                                         "attributesByType",
-                                         0 /*attr */, node_asd);
-               node_atd = data1_mk_tag (zei->dh, zei->nmem,
-                                         "attributeTypeDetails", 
-                                         0 /* attr */, node_abt);
-               data1_mk_tag_data_int (zei->dh, node_atd,
-                                      "type", 1, zei->nmem);
-               node_atvs = data1_mk_tag (zei->dh, zei->nmem, 
-                                          "attributeValues",
-                                          0 /* attr */, node_atd);
-               writeAttributeValueDetails (zei, zad, node_atvs, attset);
-           }
-       }
-    }
-    /* zebra info (private) */
-    node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
-                                "zebraInfo", node_adinfo);
-    node_list = data1_mk_tag_uni (zei->dh, zei->nmem,
+    node_list = data1_mk_tag_uni(zei->dh, zei->nmem,
                                 "attrlist", node_zebra);
     for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
     {
                                 "attrlist", node_zebra);
     for (zsui = zad->SUInfo; zsui; zsui = zsui->next)
     {
-       struct oident oident;
-       int oid[OID_SIZE];
        data1_node *node_attr;
        data1_node *node_attr;
-       char index_type_str[2];
-
-       
-       node_attr = data1_mk_tag (zei->dh, zei->nmem, "attr", 0 /* attr */,
+       node_attr = data1_mk_tag(zei->dh, zei->nmem, "attr", 0 /* attr */,
                                   node_list);
 
                                   node_list);
 
-       index_type_str[0] = zsui->info.index_type;
-       index_type_str[1] = '\0';
-       data1_mk_tag_data_text (zei->dh, node_attr, "type",
-                               index_type_str, zei->nmem);
-       if (zsui->info.which == ZEB_SU_SET_USE)
-       {
-           oident.proto = PROTO_Z3950;
-           oident.oclass = CLASS_ATTSET;
-           oident.value = (enum oid_value) zsui->info.u.su.set;
-           oid_ent_to_oid (&oident, oid);
-           
-           data1_mk_tag_data_text (zei->dh, node_attr, "set",
-                                   oident.desc, zei->nmem);
-           data1_mk_tag_data_int (zei->dh, node_attr, "use",
-                                  zsui->info.u.su.use, zei->nmem);
-       }
-       else if (zsui->info.which == ZEB_SU_STR)
-       {
-           data1_mk_tag_data_text (zei->dh, node_attr, "str",
-                                   zsui->info.u.str, zei->nmem);
-       }
-       data1_mk_tag_data_int (zei->dh, node_attr, "ordinal",
+       data1_mk_tag_data_text(zei->dh, node_attr, "type",
+                               zsui->info.index_type, zei->nmem);
+        data1_mk_tag_data_text(zei->dh, node_attr, "str",
+                               zsui->info.str, zei->nmem);
+       data1_mk_tag_data_int(zei->dh, node_attr, "ordinal",
                               zsui->info.ordinal, zei->nmem);
 
                               zsui->info.ordinal, zei->nmem);
 
-        data1_mk_tag_data_zint (zei->dh, node_attr, "dococcurrences",
+        data1_mk_tag_data_zint(zei->dh, node_attr, "dococcurrences",
                                 zsui->info.doc_occurrences, zei->nmem);
                                 zsui->info.doc_occurrences, zei->nmem);
-        data1_mk_tag_data_zint (zei->dh, node_attr, "termoccurrences",
+        data1_mk_tag_data_zint(zei->dh, node_attr, "termoccurrences",
                                 zsui->info.term_occurrences, zei->nmem);
                                 zsui->info.term_occurrences, zei->nmem);
+        switch(zsui->info.cat)
+        {
+        case zinfo_index_category_index:
+           data1_mk_tag_data_text(zei->dh, node_attr, "cat",
+                                   "index", zei->nmem); break;
+        case zinfo_index_category_sort:
+           data1_mk_tag_data_text(zei->dh, node_attr, "cat",
+                                   "sort", zei->nmem); break;
+        case zinfo_index_category_alwaysmatches:
+           data1_mk_tag_data_text(zei->dh, node_attr, "cat",
+                                   "alwaysmatches", zei->nmem); break;
+        case zinfo_index_category_anchor:
+           data1_mk_tag_data_text(zei->dh, node_attr, "cat",
+                                   "anchor", zei->nmem); break;
+        }
     }
     /* convert to "SGML" and write it */
 #if ZINFO_DEBUG
     }
     /* convert to "SGML" and write it */
 #if ZINFO_DEBUG
-    data1_pr_tree (zei->dh, zad->data1_tree, stderr);
+    data1_pr_tree(zei->dh, zad->data1_tree, stderr);
 #endif
     sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
                                  0, &sgml_len);
 #endif
     sgml_buf = data1_nodetoidsgml(zei->dh, zad->data1_tree,
                                  0, &sgml_len);
-    drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
-    memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
+    drec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
+    memcpy(drec->info[recInfo_storeData], sgml_buf, sgml_len);
     drec->size[recInfo_storeData] = sgml_len;
     drec->size[recInfo_storeData] = sgml_len;
-    
-    rec_put (zei->records, &drec);
+
+    rec_put(zei->records, &drec);
 }
 
 }
 
-static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
+static void zebraExplain_writeDatabase(ZebraExplainInfo zei,
                                         struct zebDatabaseInfoB *zdi,
                                        int key_flush)
 {
                                         struct zebDatabaseInfoB *zdi,
                                        int key_flush)
 {
@@ -1217,7 +1134,7 @@ static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
     int sgml_len;
     Record drec;
     data1_node *node_dbinfo, *node_count, *node_zebra;
     int sgml_len;
     Record drec;
     data1_node *node_dbinfo, *node_count, *node_zebra;
-    
+
     if (!zdi->dirty)
        return;
 
     if (!zdi->dirty)
        return;
 
@@ -1225,32 +1142,33 @@ static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
 #if ZINFO_DEBUG
     yaz_log(YLOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
 #endif
 #if ZINFO_DEBUG
     yaz_log(YLOG_LOG, "zebraExplain_writeDatabase %s", zdi->databaseName);
 #endif
-    drec = createRecord (zei->records, &zdi->sysno);
+    drec = createRecord(zei->records, &zdi->sysno);
     if (!drec)
        return;
     if (!drec)
        return;
-    assert (zdi->data1_database);
+    assert(zdi->data1_database);
 
 
-    node_dbinfo = data1_search_tag (zei->dh, zdi->data1_database,
+    node_dbinfo = data1_search_tag(zei->dh, zdi->data1_database,
                                     "/databaseInfo");
 
                                     "/databaseInfo");
 
-    assert (node_dbinfo);
-    zebraExplain_updateCommonInfo (zei, node_dbinfo);
-    zebraExplain_updateAccessInfo (zei, node_dbinfo, zdi->accessInfo);
+    assert(node_dbinfo);
+    zebraExplain_updateCommonInfo(zei, node_dbinfo);
+    zebraExplain_updateAccessInfo(zei, node_dbinfo, zdi->accessInfo);
 
 
-    /* extract *searchable* keys from it. We do this here, because
-       record count, etc. is affected */
-    if (key_flush)
-       (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
     /* record count */
     /* record count */
-    node_count = data1_mk_tag_uni (zei->dh, zei->nmem,
+    node_count = data1_mk_tag_uni(zei->dh, zei->nmem,
                                 "recordCount", node_dbinfo);
                                 "recordCount", node_dbinfo);
-    data1_mk_tag_data_zint (zei->dh, node_count, "recordCountActual",
+    data1_mk_tag_data_zint(zei->dh, node_count, "recordCountActual",
                            zdi->recordCount, zei->nmem);
 
     /* zebra info (private) */
                            zdi->recordCount, zei->nmem);
 
     /* zebra info (private) */
-    node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
+    node_zebra = data1_mk_tag_uni(zei->dh, zei->nmem,
                                 "zebraInfo", node_dbinfo);
                                 "zebraInfo", node_dbinfo);
-    data1_mk_tag_data_zint (zei->dh, node_zebra,
+
+    /* extract *searchable* keys from it. We do this here, because
+       record count, etc. is affected */
+    if (key_flush)
+       (*zei->updateFunc)(zei->updateHandle, drec, zdi->data1_database);
+    data1_mk_tag_data_zint(zei->dh, node_zebra,
                           "recordBytes", zdi->recordBytes, zei->nmem);
 
     data1_mk_tag_data_zint(zei->dh, node_zebra,
                           "recordBytes", zdi->recordBytes, zei->nmem);
 
     data1_mk_tag_data_zint(zei->dh, node_zebra,
@@ -1258,18 +1176,18 @@ static void zebraExplain_writeDatabase (ZebraExplainInfo zei,
 
     /* convert to "SGML" and write it */
 #if ZINFO_DEBUG
 
     /* convert to "SGML" and write it */
 #if ZINFO_DEBUG
-    data1_pr_tree (zei->dh, zdi->data1_database, stderr);
+    data1_pr_tree(zei->dh, zdi->data1_database, stderr);
 #endif
     sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
                                  0, &sgml_len);
 #endif
     sgml_buf = data1_nodetoidsgml(zei->dh, zdi->data1_database,
                                  0, &sgml_len);
-    drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
-    memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
+    drec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
+    memcpy(drec->info[recInfo_storeData], sgml_buf, sgml_len);
     drec->size[recInfo_storeData] = sgml_len;
     drec->size[recInfo_storeData] = sgml_len;
-    
-    rec_put (zei->records, &drec);
+
+    rec_put(zei->records, &drec);
 }
 
 }
 
-static void writeAttributeValues (ZebraExplainInfo zei,
+static void writeAttributeValues(ZebraExplainInfo zei,
                                  data1_node *node_values,
                                  data1_attset *attset)
 {
                                  data1_node *node_values,
                                  data1_attset *attset)
 {
@@ -1280,24 +1198,24 @@ static void writeAttributeValues (ZebraExplainInfo zei,
        return;
 
     for (c = attset->children; c; c = c->next)
        return;
 
     for (c = attset->children; c; c = c->next)
-       writeAttributeValues (zei, node_values, c->child);
+       writeAttributeValues(zei, node_values, c->child);
     for (atts = attset->atts; atts; atts = atts->next)
     {
        data1_node *node_value;
     for (atts = attset->atts; atts; atts = atts->next)
     {
        data1_node *node_value;
-       
-       node_value = data1_mk_tag (zei->dh, zei->nmem, "attributeValue",
+
+       node_value = data1_mk_tag(zei->dh, zei->nmem, "attributeValue",
                                    0 /* attr */, node_values);
                                    0 /* attr */, node_values);
-       data1_mk_tag_data_text (zei->dh, node_value, "name",
+       data1_mk_tag_data_text(zei->dh, node_value, "name",
                                atts->name, zei->nmem);
                                atts->name, zei->nmem);
-        node_value = data1_mk_tag (zei->dh, zei->nmem, "value",
+        node_value = data1_mk_tag(zei->dh, zei->nmem, "value",
                                    0 /* attr */, node_value);
                                    0 /* attr */, node_value);
-       data1_mk_tag_data_int (zei->dh, node_value, "numeric",
+       data1_mk_tag_data_int(zei->dh, node_value, "numeric",
                               atts->value, zei->nmem);
     }
 }
 
 
                               atts->value, zei->nmem);
     }
 }
 
 
-static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
+static void zebraExplain_writeAttributeSet(ZebraExplainInfo zei,
                                            zebAccessObject o,
                                            int key_flush)
 {
                                            zebAccessObject o,
                                            int key_flush)
 {
@@ -1306,52 +1224,51 @@ static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
     Record drec;
     data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
     data1_node *node_values;
     Record drec;
     data1_node *node_root, *node_attinfo, *node_attributes, *node_atttype;
     data1_node *node_values;
-    struct oident *entp;
-    struct data1_attset *attset = NULL;
-    
-    if ((entp = oid_getentbyoid (o->oid)))
-       attset = data1_attset_search_id (zei->dh, entp->value);
-           
+    struct data1_attset *attset = 0;
+
+    if (o->oid)
+       attset = data1_attset_search_id(zei->dh, o->oid);
+
 #if ZINFO_DEBUG
     yaz_log(YLOG_LOG, "zebraExplain_writeAttributeSet %s",
 #if ZINFO_DEBUG
     yaz_log(YLOG_LOG, "zebraExplain_writeAttributeSet %s",
-         attset ? attset->name : "<unknown>");    
+         attset ? attset->name : "<unknown>");
 #endif
 
 #endif
 
-    drec = createRecord (zei->records, &o->sysno);
+    drec = createRecord(zei->records, &o->sysno);
     if (!drec)
        return;
     node_root =
     if (!drec)
        return;
     node_root =
-       data1_read_sgml (zei->dh, zei->nmem,
+       data1_read_sgml(zei->dh, zei->nmem,
                         "<explain><attributeSetInfo>AttributeSetInfo\n"
                         "</></>\n" );
 
                         "<explain><attributeSetInfo>AttributeSetInfo\n"
                         "</></>\n" );
 
-    node_attinfo = data1_search_tag (zei->dh, node_root,
+    node_attinfo = data1_search_tag(zei->dh, node_root,
                                   "/attributeSetInfo");
 
                                   "/attributeSetInfo");
 
-    assert (node_attinfo);
-    zebraExplain_initCommonInfo (zei, node_attinfo);
-    zebraExplain_updateCommonInfo (zei, node_attinfo);
+    assert(node_attinfo);
+    zebraExplain_initCommonInfo(zei, node_attinfo);
+    zebraExplain_updateCommonInfo(zei, node_attinfo);
 
 
-    data1_mk_tag_data_oid (zei->dh, node_attinfo,
+    data1_mk_tag_data_oid(zei->dh, node_attinfo,
                            "oid", o->oid, zei->nmem);
     if (attset && attset->name)
                            "oid", o->oid, zei->nmem);
     if (attset && attset->name)
-       data1_mk_tag_data_text (zei->dh, node_attinfo,
+       data1_mk_tag_data_text(zei->dh, node_attinfo,
                                "name", attset->name, zei->nmem);
                                "name", attset->name, zei->nmem);
-    
-    node_attributes = data1_mk_tag_uni (zei->dh, zei->nmem,
+
+    node_attributes = data1_mk_tag_uni(zei->dh, zei->nmem,
                                      "attributes", node_attinfo);
                                      "attributes", node_attinfo);
-    node_atttype = data1_mk_tag_uni (zei->dh, zei->nmem,
+    node_atttype = data1_mk_tag_uni(zei->dh, zei->nmem,
                                   "attributeType", node_attributes);
                                   "attributeType", node_attributes);
-    data1_mk_tag_data_text (zei->dh, node_atttype,
+    data1_mk_tag_data_text(zei->dh, node_atttype,
                            "name", "Use", zei->nmem);
                            "name", "Use", zei->nmem);
-    data1_mk_tag_data_text (zei->dh, node_atttype,
+    data1_mk_tag_data_text(zei->dh, node_atttype,
                            "description", "Use Attribute", zei->nmem);
                            "description", "Use Attribute", zei->nmem);
-    data1_mk_tag_data_int (zei->dh, node_atttype,
+    data1_mk_tag_data_int(zei->dh, node_atttype,
                           "type", 1, zei->nmem);
                           "type", 1, zei->nmem);
-    node_values = data1_mk_tag (zei->dh, zei->nmem,
+    node_values = data1_mk_tag(zei->dh, zei->nmem,
                                 "attributeValues", 0 /* attr */, node_atttype);
     if (attset)
                                 "attributeValues", 0 /* attr */, node_atttype);
     if (attset)
-       writeAttributeValues (zei, node_values, attset);
+       writeAttributeValues(zei, node_values, attset);
 
     /* extract *searchable* keys from it. We do this here, because
        record count, etc. is affected */
 
     /* extract *searchable* keys from it. We do this here, because
        record count, etc. is affected */
@@ -1359,17 +1276,17 @@ static void zebraExplain_writeAttributeSet (ZebraExplainInfo zei,
        (*zei->updateFunc)(zei->updateHandle, drec, node_root);
     /* convert to "SGML" and write it */
 #if ZINFO_DEBUG
        (*zei->updateFunc)(zei->updateHandle, drec, node_root);
     /* convert to "SGML" and write it */
 #if ZINFO_DEBUG
-    data1_pr_tree (zei->dh, node_root, stderr);
+    data1_pr_tree(zei->dh, node_root, stderr);
 #endif
     sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
 #endif
     sgml_buf = data1_nodetoidsgml(zei->dh, node_root, 0, &sgml_len);
-    drec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
-    memcpy (drec->info[recInfo_storeData], sgml_buf, sgml_len);
+    drec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
+    memcpy(drec->info[recInfo_storeData], sgml_buf, sgml_len);
     drec->size[recInfo_storeData] = sgml_len;
     drec->size[recInfo_storeData] = sgml_len;
-    
-    rec_put (zei->records, &drec);
+
+    rec_put(zei->records, &drec);
 }
 
 }
 
-static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
+static void zebraExplain_writeTarget(ZebraExplainInfo zei, int key_flush)
 {
     struct zebDatabaseInfoB *zdi;
     data1_node *node_tgtinfo, *node_list, *node_zebra;
 {
     struct zebDatabaseInfoB *zdi;
     data1_node *node_tgtinfo, *node_list, *node_zebra;
@@ -1382,116 +1299,72 @@ static void zebraExplain_writeTarget (ZebraExplainInfo zei, int key_flush)
     zei->dirty = 0;
 
     trec = rec_get_root(zei->records);
     zei->dirty = 0;
 
     trec = rec_get_root(zei->records);
-    xfree (trec->info[recInfo_storeData]);
+    xfree(trec->info[recInfo_storeData]);
 
 
-    node_tgtinfo = data1_search_tag (zei->dh, zei->data1_target,
+    node_tgtinfo = data1_search_tag(zei->dh, zei->data1_target,
                                      "/targetInfo");
                                      "/targetInfo");
-    assert (node_tgtinfo);
+    assert(node_tgtinfo);
 
 
-    zebraExplain_updateCommonInfo (zei, node_tgtinfo);
-    zebraExplain_updateAccessInfo (zei, node_tgtinfo, zei->accessInfo);
+    zebraExplain_updateCommonInfo(zei, node_tgtinfo);
+    zebraExplain_updateAccessInfo(zei, node_tgtinfo, zei->accessInfo);
 
 
+    node_zebra = data1_mk_tag_uni(zei->dh, zei->nmem,
+                                "zebraInfo", node_tgtinfo);
     /* convert to "SGML" and write it */
     if (key_flush)
        (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
 
     /* convert to "SGML" and write it */
     if (key_flush)
        (*zei->updateFunc)(zei->updateHandle, trec, zei->data1_target);
 
-    node_zebra = data1_mk_tag_uni (zei->dh, zei->nmem,
-                                "zebraInfo", node_tgtinfo);
-    data1_mk_tag_data_text (zei->dh, node_zebra, "version",
+    data1_mk_tag_data_text(zei->dh, node_zebra, "version",
                               ZEBRAVER, zei->nmem);
                               ZEBRAVER, zei->nmem);
-    node_list = data1_mk_tag (zei->dh, zei->nmem,
+    node_list = data1_mk_tag(zei->dh, zei->nmem,
                               "databaseList", 0 /* attr */, node_zebra);
     for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
     {
        data1_node *node_db;
                               "databaseList", 0 /* attr */, node_zebra);
     for (zdi = zei->databaseInfo; zdi; zdi = zdi->next)
     {
        data1_node *node_db;
-       node_db = data1_mk_tag (zei->dh, zei->nmem,
+       node_db = data1_mk_tag(zei->dh, zei->nmem,
                                 "database", 0 /* attr */, node_list);
                                 "database", 0 /* attr */, node_list);
-       data1_mk_tag_data_text (zei->dh, node_db, "name",
+       data1_mk_tag_data_text(zei->dh, node_db, "name",
                                 zdi->databaseName, zei->nmem);
                                 zdi->databaseName, zei->nmem);
-       data1_mk_tag_data_zint (zei->dh, node_db, "id",
+       data1_mk_tag_data_zint(zei->dh, node_db, "id",
                                zdi->sysno, zei->nmem);
                                zdi->sysno, zei->nmem);
-       data1_mk_tag_data_zint (zei->dh, node_db, "attributeDetailsId",
+       data1_mk_tag_data_zint(zei->dh, node_db, "attributeDetailsId",
                                zdi->attributeDetails->sysno, zei->nmem);
     }
                                zdi->attributeDetails->sysno, zei->nmem);
     }
-    data1_mk_tag_data_int (zei->dh, node_zebra, "ordinalSU",
+    data1_mk_tag_data_int(zei->dh, node_zebra, "ordinalSU",
                            zei->ordinalSU, zei->nmem);
 
                            zei->ordinalSU, zei->nmem);
 
-    data1_mk_tag_data_int (zei->dh, node_zebra, "ordinalDatabase",
+    data1_mk_tag_data_int(zei->dh, node_zebra, "ordinalDatabase",
                            zei->ordinalDatabase, zei->nmem);
 
                            zei->ordinalDatabase, zei->nmem);
 
-    data1_mk_tag_data_zint (zei->dh, node_zebra, "runNumber",
+    data1_mk_tag_data_zint(zei->dh, node_zebra, "runNumber",
                            zei->runNumber, zei->nmem);
 
 #if ZINFO_DEBUG
                            zei->runNumber, zei->nmem);
 
 #if ZINFO_DEBUG
-    data1_pr_tree (zei->dh, zei->data1_target, stderr);
+    data1_pr_tree(zei->dh, zei->data1_target, stderr);
 #endif
     sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
                                  0, &sgml_len);
 #endif
     sgml_buf = data1_nodetoidsgml(zei->dh, zei->data1_target,
                                  0, &sgml_len);
-    trec->info[recInfo_storeData] = (char *) xmalloc (sgml_len);
-    memcpy (trec->info[recInfo_storeData], sgml_buf, sgml_len);
+    trec->info[recInfo_storeData] = (char *) xmalloc(sgml_len);
+    memcpy(trec->info[recInfo_storeData], sgml_buf, sgml_len);
     trec->size[recInfo_storeData] = sgml_len;
     trec->size[recInfo_storeData] = sgml_len;
-    
-    rec_put (zei->records, &trec);
-}
-
-int zebraExplain_lookup_attr_su_any_index(ZebraExplainInfo zei,
-                                         int set, int use)
-{
-    struct zebSUInfoB *zsui;
-    int ord;
-
-    assert (zei->curDatabaseInfo);
-
-    ord = zebraExplain_lookup_attr_su(zei, 'w', set, use);
-    if (ord != -1)
-        return ord;
-    for (zsui = zei->curDatabaseInfo->attributeDetails->SUInfo;
-        zsui; zsui=zsui->next)
-        if (zsui->info.which == ZEB_SU_SET_USE &&
-           zsui->info.u.su.use == use && zsui->info.u.su.set == set)
-            return zsui->info.ordinal;
-    return -1;
-}
 
 
-int zebraExplain_lookup_attr_su(ZebraExplainInfo zei, int index_type,
-                               int set, int use)
-{
-    struct zebSUInfoB **zsui;
-
-#if 0
-    yaz_log(YLOG_LOG, "lookup_attr_su index_type=%d set=%d use=%d",
-            index_type, set, use);
-#endif
-    assert (zei->curDatabaseInfo);
-    for (zsui = &zei->curDatabaseInfo->attributeDetails->SUInfo;
-        *zsui; zsui = &(*zsui)->next)
-        if ((*zsui)->info.index_type == index_type &&
-           (*zsui)->info.which == ZEB_SU_SET_USE &&
-           (*zsui)->info.u.su.use == use && (*zsui)->info.u.su.set == set)
-        {
-            struct zebSUInfoB *zsui_this = *zsui;
-
-            /* take it out of the list and move to front */
-            *zsui = (*zsui)->next;
-            zsui_this->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
-            zei->curDatabaseInfo->attributeDetails->SUInfo = zsui_this;
-
-            return zsui_this->info.ordinal;
-        }
-    return -1;
+    rec_put(zei->records, &trec);
 }
 
 }
 
-int zebraExplain_lookup_attr_str(ZebraExplainInfo zei, int index_type,
+int zebraExplain_lookup_attr_str(ZebraExplainInfo zei,
+                                 zinfo_index_category_t cat,
+                                 const char *index_type,
                                 const char *str)
 {
     struct zebSUInfoB **zsui;
 
                                 const char *str)
 {
     struct zebSUInfoB **zsui;
 
-    assert (zei->curDatabaseInfo);
+    assert(zei->curDatabaseInfo);
     for (zsui = &zei->curDatabaseInfo->attributeDetails->SUInfo;
         *zsui; zsui = &(*zsui)->next)
     for (zsui = &zei->curDatabaseInfo->attributeDetails->SUInfo;
         *zsui; zsui = &(*zsui)->next)
-        if ((*zsui)->info.index_type == index_type
-            && (*zsui)->info.which == ZEB_SU_STR 
-            && !strcmp((*zsui)->info.u.str, str))
+        if ( (index_type == 0
+              || !strcmp((*zsui)->info.index_type, index_type))
+             && (*zsui)->info.cat == cat
+             && !yaz_matchstr((*zsui)->info.str, str))
         {
             struct zebSUInfoB *zsui_this = *zsui;
 
         {
             struct zebSUInfoB *zsui_this = *zsui;
 
@@ -1506,20 +1379,25 @@ int zebraExplain_lookup_attr_str(ZebraExplainInfo zei, int index_type,
 }
 
 int zebraExplain_trav_ord(ZebraExplainInfo zei, void *handle,
 }
 
 int zebraExplain_trav_ord(ZebraExplainInfo zei, void *handle,
-                         int (*f)(void *handle, int ord))
+                         int (*f)(void *handle, int ord,
+                                   const char *index_type,
+                                   const char *string_index,
+                                   zinfo_index_category_t cat))
 {
     struct zebDatabaseInfoB *zdb = zei->curDatabaseInfo;
     if (zdb)
     {
        struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
        for ( ;zsui; zsui = zsui->next)
 {
     struct zebDatabaseInfoB *zdb = zei->curDatabaseInfo;
     if (zdb)
     {
        struct zebSUInfoB *zsui = zdb->attributeDetails->SUInfo;
        for ( ;zsui; zsui = zsui->next)
-           (*f)(handle,  zsui->info.ordinal);
+           (*f)(handle,  zsui->info.ordinal,
+                 zsui->info.index_type, zsui->info.str,
+                 zsui->info.cat);
     }
     return 0;
 }
 
 
     }
     return 0;
 }
 
 
-struct zebSUInfoB *zebraExplain_get_sui_info (ZebraExplainInfo zei, int ord,
+struct zebSUInfoB *zebraExplain_get_sui_info(ZebraExplainInfo zei, int ord,
                                               int dirty_mark,
                                               const char **db)
 {
                                               int dirty_mark,
                                               const char **db)
 {
@@ -1530,14 +1408,14 @@ struct zebSUInfoB *zebraExplain_get_sui_info (ZebraExplainInfo zei, int ord,
        struct zebSUInfoB **zsui;
 
        if (zdb->attributeDetails->readFlag)
        struct zebSUInfoB **zsui;
 
        if (zdb->attributeDetails->readFlag)
-           zebraExplain_readAttributeDetails (zei, zdb->attributeDetails);
+           zebraExplain_readAttributeDetails(zei, zdb->attributeDetails);
 
        for (zsui = &zdb->attributeDetails->SUInfo; *zsui;
              zsui = &(*zsui)->next)
            if ((*zsui)->info.ordinal == ord)
             {
                 struct zebSUInfoB *zsui_this = *zsui;
 
        for (zsui = &zdb->attributeDetails->SUInfo; *zsui;
              zsui = &(*zsui)->next)
            if ((*zsui)->info.ordinal == ord)
             {
                 struct zebSUInfoB *zsui_this = *zsui;
-                
+
                 /* take it out of the list and move to front */
                 *zsui = (*zsui)->next;
                 zsui_this->next = zdb->attributeDetails->SUInfo;
                 /* take it out of the list and move to front */
                 *zsui = (*zsui)->next;
                 zsui_this->next = zdb->attributeDetails->SUInfo;
@@ -1599,17 +1477,12 @@ zint zebraExplain_ord_get_term_occurrences(ZebraExplainInfo zei, int ord)
 }
 
 int zebraExplain_lookup_ord(ZebraExplainInfo zei, int ord,
 }
 
 int zebraExplain_lookup_ord(ZebraExplainInfo zei, int ord,
-                           int *index_type, 
+                           const char **index_type,
                            const char **db,
                            const char **db,
-                           int *set, int *use,
                            const char **string_index)
 {
     struct zebSUInfoB *zsui;
 
                            const char **string_index)
 {
     struct zebSUInfoB *zsui;
 
-    if (set)
-       *set = -1;
-    if (use)
-       *use = -1;
     if (index_type)
        *index_type = 0;
     if (string_index)
     if (index_type)
        *index_type = 0;
     if (string_index)
@@ -1618,18 +1491,8 @@ int zebraExplain_lookup_ord(ZebraExplainInfo zei, int ord,
     zsui = zebraExplain_get_sui_info(zei, ord, 0, db);
     if (zsui)
     {
     zsui = zebraExplain_get_sui_info(zei, ord, 0, db);
     if (zsui)
     {
-        if (zsui->info.which == ZEB_SU_SET_USE)
-        {
-            if (set)
-                *set = zsui->info.u.su.set;
-            if (use)
-                *use = zsui->info.u.su.use;
-        }
-        
-        if (zsui->info.which == ZEB_SU_STR)
-            if (string_index)
-                *string_index = zsui->info.u.str;
-        
+        if (string_index)
+            *string_index = zsui->info.str;
         if (index_type)
             *index_type = zsui->info.index_type;
         return 0;
         if (index_type)
             *index_type = zsui->info.index_type;
         return 0;
@@ -1639,94 +1502,68 @@ int zebraExplain_lookup_ord(ZebraExplainInfo zei, int ord,
 
 
 
 
 
 
-zebAccessObject zebraExplain_announceOid (ZebraExplainInfo zei,
+zebAccessObject zebraExplain_announceOid(ZebraExplainInfo zei,
                                          zebAccessObject *op,
                                          Odr_oid *oid)
 {
     zebAccessObject ao;
                                          zebAccessObject *op,
                                          Odr_oid *oid)
 {
     zebAccessObject ao;
-    
+
     for (ao = *op; ao; ao = ao->next)
     for (ao = *op; ao; ao = ao->next)
-       if (!oid_oidcmp (oid, ao->oid))
+       if (!oid_oidcmp(oid, ao->oid))
            break;
     if (!ao)
     {
            break;
     if (!ao)
     {
-       ao = (zebAccessObject) nmem_malloc (zei->nmem, sizeof(*ao));
-       ao->handle = NULL;
+       ao = (zebAccessObject) nmem_malloc(zei->nmem, sizeof(*ao));
+       ao->handle = 0;
        ao->sysno = 0;
        ao->sysno = 0;
-       ao->oid = odr_oiddup_nmem (zei->nmem, oid);
+       ao->oid = odr_oiddup_nmem(zei->nmem, oid);
        ao->next = *op;
        *op = ao;
     }
     return ao;
 }
 
        ao->next = *op;
        *op = ao;
     }
     return ao;
 }
 
-void zebraExplain_addAttributeSet (ZebraExplainInfo zei, int set)
-{
-    oident oe;
-    int oid[OID_SIZE];
-
-    oe.proto = PROTO_Z3950;
-    oe.oclass = CLASS_ATTSET;
-    oe.value = (enum oid_value) set;
-
-    if (oid_ent_to_oid (&oe, oid))
-    {
-       zebraExplain_announceOid (zei, &zei->accessInfo->attributeSetIds, oid);
-       zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
-                                 accessInfo->attributeSetIds, oid);
-    }
-}
-
 struct zebSUInfoB *zebraExplain_add_sui_info(ZebraExplainInfo zei,
 struct zebSUInfoB *zebraExplain_add_sui_info(ZebraExplainInfo zei,
-                                             int index_type)
+                                             zinfo_index_category_t cat,
+                                             const char *index_type)
 {
     struct zebSUInfoB *zsui;
 
 {
     struct zebSUInfoB *zsui;
 
-    assert (zei->curDatabaseInfo);
-    zsui = (struct zebSUInfoB *) nmem_malloc (zei->nmem, sizeof(*zsui));
+    assert(zei->curDatabaseInfo);
+    zsui = (struct zebSUInfoB *) nmem_malloc(zei->nmem, sizeof(*zsui));
     zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
     zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
     zei->curDatabaseInfo->attributeDetails->dirty = 1;
     zei->dirty = 1;
     zsui->next = zei->curDatabaseInfo->attributeDetails->SUInfo;
     zei->curDatabaseInfo->attributeDetails->SUInfo = zsui;
     zei->curDatabaseInfo->attributeDetails->dirty = 1;
     zei->dirty = 1;
-    zsui->info.index_type = index_type;
+    zsui->info.index_type = nmem_strdup(zei->nmem, index_type);
+    zsui->info.cat = cat;
     zsui->info.doc_occurrences = 0;
     zsui->info.term_occurrences = 0;
     zsui->info.ordinal = (zei->ordinalSU)++;
     return zsui;
 }
 
     zsui->info.doc_occurrences = 0;
     zsui->info.term_occurrences = 0;
     zsui->info.ordinal = (zei->ordinalSU)++;
     return zsui;
 }
 
-int zebraExplain_add_attr_su(ZebraExplainInfo zei, int index_type,
-                            int set, int use)
-{
-    struct zebSUInfoB *zsui = zebraExplain_add_sui_info(zei, index_type);
-
-    zebraExplain_addAttributeSet (zei, set);
-    zsui->info.which = ZEB_SU_SET_USE;
-    zsui->info.u.su.set = set;
-    zsui->info.u.su.use = use;
-    return zsui->info.ordinal;
-}
-
-int zebraExplain_add_attr_str(ZebraExplainInfo zei, int index_type,
+int zebraExplain_add_attr_str(ZebraExplainInfo zei,
+                              zinfo_index_category_t cat,
+                              const char *index_type,
                              const char *index_name)
 {
                              const char *index_name)
 {
-    struct zebSUInfoB *zsui = zebraExplain_add_sui_info(zei, index_type);
+    struct zebSUInfoB *zsui = zebraExplain_add_sui_info(zei, cat, index_type);
 
 
-    zsui->info.which = ZEB_SU_STR;
-    zsui->info.u.str = nmem_strdup(zei->nmem, index_name);
+    zsui->info.str = nmem_strdup(zei->nmem, index_name);
     return zsui->info.ordinal;
 }
 
     return zsui->info.ordinal;
 }
 
-void zebraExplain_addSchema (ZebraExplainInfo zei, Odr_oid *oid)
+void zebraExplain_addSchema(ZebraExplainInfo zei, Odr_oid *oid)
 {
 {
-    zebraExplain_announceOid (zei, &zei->accessInfo->schemas, oid);
-    zebraExplain_announceOid (zei, &zei->curDatabaseInfo->
+    zebraExplain_announceOid(zei, &zei->accessInfo->schemas, oid);
+    zebraExplain_announceOid(zei, &zei->curDatabaseInfo->
                              accessInfo->schemas, oid);
 }
 
                              accessInfo->schemas, oid);
 }
 
-void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
+void zebraExplain_recordBytesIncrement(ZebraExplainInfo zei, int adjust_num)
 {
 {
-    assert (zei->curDatabaseInfo);
+    assert(zei->curDatabaseInfo);
 
     if (adjust_num)
     {
 
     if (adjust_num)
     {
@@ -1735,9 +1572,9 @@ void zebraExplain_recordBytesIncrement (ZebraExplainInfo zei, int adjust_num)
     }
 }
 
     }
 }
 
-void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
+void zebraExplain_recordCountIncrement(ZebraExplainInfo zei, int adjust_num)
 {
 {
-    assert (zei->curDatabaseInfo);
+    assert(zei->curDatabaseInfo);
 
     if (adjust_num)
     {
 
     if (adjust_num)
     {
@@ -1746,7 +1583,7 @@ void zebraExplain_recordCountIncrement (ZebraExplainInfo zei, int adjust_num)
     }
 }
 
     }
 }
 
-zint zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
+zint zebraExplain_runNumberIncrement(ZebraExplainInfo zei, int adjust_num)
 {
     if (adjust_num)
     {
 {
     if (adjust_num)
     {
@@ -1755,16 +1592,18 @@ zint zebraExplain_runNumberIncrement (ZebraExplainInfo zei, int adjust_num)
     return zei->runNumber += adjust_num;
 }
 
     return zei->runNumber += adjust_num;
 }
 
-RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
+RecordAttr *rec_init_attr(ZebraExplainInfo zei, Record rec)
 {
     RecordAttr *recordAttr;
 
     if (rec->info[recInfo_attr])
        return (RecordAttr *) rec->info[recInfo_attr];
 {
     RecordAttr *recordAttr;
 
     if (rec->info[recInfo_attr])
        return (RecordAttr *) rec->info[recInfo_attr];
-    recordAttr = (RecordAttr *) xmalloc (sizeof(*recordAttr));
+    recordAttr = (RecordAttr *) xmalloc(sizeof(*recordAttr));
+
+    memset(recordAttr, '\0', sizeof(*recordAttr));
     rec->info[recInfo_attr] = (char *) recordAttr;
     rec->size[recInfo_attr] = sizeof(*recordAttr);
     rec->info[recInfo_attr] = (char *) recordAttr;
     rec->size[recInfo_attr] = sizeof(*recordAttr);
-    
+
     recordAttr->recordSize = 0;
     recordAttr->recordOffset = 0;
     recordAttr->runNumber = zei->runNumber;
     recordAttr->recordSize = 0;
     recordAttr->recordOffset = 0;
     recordAttr->runNumber = zei->runNumber;
@@ -1775,7 +1614,7 @@ RecordAttr *rec_init_attr (ZebraExplainInfo zei, Record rec)
 static void att_loadset(void *p, const char *n, const char *name)
 {
     data1_handle dh = (data1_handle) p;
 static void att_loadset(void *p, const char *n, const char *name)
 {
     data1_handle dh = (data1_handle) p;
-    if (!data1_get_attset (dh, name))
+    if (!data1_get_attset(dh, name))
        yaz_log(YLOG_WARN, "Directive attset failed for %s", name);
 }
 
        yaz_log(YLOG_WARN, "Directive attset failed for %s", name);
 }
 
@@ -1786,7 +1625,7 @@ int zebraExplain_get_database_ord(ZebraExplainInfo zei)
     return zei->curDatabaseInfo->ordinalDatabase;
 }
 
     return zei->curDatabaseInfo->ordinalDatabase;
 }
 
-void zebraExplain_loadAttsets (data1_handle dh, Res res)
+void zebraExplain_loadAttsets(data1_handle dh, Res res)
 {
     res_trav(res, "attset", dh, att_loadset);
 }
 {
     res_trav(res, "attset", dh, att_loadset);
 }
@@ -1796,12 +1635,13 @@ void zebraExplain_loadAttsets (data1_handle dh, Res res)
      adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
      exist for the database.
 
      adds attributeSet (in AccessInfo area) to DatabaseInfo if it doesn't
      exist for the database.
 
-     If the database doesn't exist globally (in TargetInfo) an 
+     If the database doesn't exist globally (in TargetInfo) an
      AttributeSetInfo must be added (globally).
  */
 /*
  * Local variables:
  * c-basic-offset: 4
      AttributeSetInfo must be added (globally).
  */
 /*
  * Local variables:
  * c-basic-offset: 4
+ * c-file-style: "Stroustrup"
  * indent-tabs-mode: nil
  * End:
  * vim: shiftwidth=4 tabstop=8 expandtab
  * indent-tabs-mode: nil
  * End:
  * vim: shiftwidth=4 tabstop=8 expandtab