Merge branch 'master' of ssh://git.indexdata.com/home/git/pub/yaz
authorDennis Schafroth <dennis@indexdata.com>
Fri, 11 Mar 2011 12:36:52 +0000 (13:36 +0100)
committerDennis Schafroth <dennis@indexdata.com>
Fri, 11 Mar 2011 12:36:52 +0000 (13:36 +0100)
17 files changed:
NEWS
buildconf.sh
client/client.c
configure.ac
debian/changelog
debian/rules
doc/zoom.xml
include/yaz/marcdisp.h
src/opacdisp.c
src/record_render.c
src/solr.c
src/sru-p.h
src/srw.c
src/srwutil.c
src/stemmer.c
src/zoom-c.c
yaz.spec

diff --git a/NEWS b/NEWS
index ff42413..2775141 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,29 @@
---- 4.1.3 2011/01/27
+--- 4.1.6 2011/03/10
+
+fix problem with record_render: records were converted (character set
+wise) even if no charset was given. Problem introduced in YAZ 4.1.5.
+
+--- 4.1.5 2011/03/08
+
+SRU: add methods for handling DADS SRU-proxy facets.
+
+Separate OPAC record character set for ZOOM_record. yaz_record_render
+allows a character set given as charset=from/opacfrom,to where 'from' is
+the character set of a bibliographic record, 'opacfrom' is character set
+of OPAC record and 'to' is the target character set.
 
+--- 4.1.4 2011/02/21
+
+yaz-client: show may XML format records. Command show followed by 'format'
+will format XML records retrieved using Libxml2's xmlDocDumpFormatMemory
+function.
+
+src/stemmer.c: Avoid using unnamed union. It is not supported by some
+older C compilers.
+
+For PHPYAZ: set YAZVERSION, not YAZ_VERSION.
+
+--- 4.1.3 2011/01/27
 Update yaz.spec to operate on both SLES11 / Centos 5.5.
 
 RPM: Release includes 'indexdata' name. Use indexdata in release name so
index f844bce..c82194a 100755 (executable)
@@ -14,11 +14,11 @@ fi
 if [ "`uname -s`" = FreeBSD ]; then
     # FreeBSD intalls the various auto* tools with version numbers
     echo "Using special configuration for FreeBSD ..."
-    automake=automake19
-    aclocal="aclocal19 -I /usr/local/share/aclocal"
-    autoconf=autoconf259
-    libtoolize=libtoolize15
-    autoheader=autoheader259
+    automake=automake
+    aclocal="aclocal -I /usr/local/share/aclocal"
+    autoconf=autoconf
+    libtoolize=libtoolize
+    autoheader=autoheader
 fi
 
 if [ "`uname -s`" = Darwin ]; then
@@ -129,8 +129,9 @@ EOF
     if [ "`uname -s`" = FreeBSD ]; then
         cat <<EOF
 When building from a Git, you need these FreeBSD Ports:
-  autoconf259, automake19, libtool15, bison, tcl84,
-  docbook-xsl, libxml2, libxslt, g++-4.0, make
+  pkg_add -r autoconf262 automake110 libtool bison tcl84 \\
+             docbook-xsl libxml2 libxslt
+  pkg_add -r icu4
 EOF
     fi
 fi
index e8a3289..71432b4 100644 (file)
@@ -148,6 +148,8 @@ static int scan_size = 20;
 static char cur_host[200];
 static Odr_int last_hit_count = 0;
 
+static int pretty_xml = 0;
+
 typedef enum {
     QueryType_Prefix,
     QueryType_CCL,
@@ -849,6 +851,31 @@ static void print_record(const char *buf, size_t len)
         printf("\n");
 }
 
+static void print_xml_record(const char *buf, size_t len)
+{
+    int has_printed = 0;
+#if YAZ_HAVE_XML2
+    if (pretty_xml)
+    {
+        xmlDocPtr doc;
+        xmlKeepBlanksDefault(0); /* get get xmlDocFormatMemory to work! */
+        doc = xmlParseMemory(buf, len);
+        if (doc)
+        {
+            xmlChar *xml_mem;
+            int xml_size;
+            xmlDocDumpFormatMemory(doc, &xml_mem, &xml_size, 1);
+            fwrite(xml_mem, 1, xml_size, stdout);
+            xmlFree(xml_mem);
+            xmlFreeDoc(doc);
+            has_printed = 1;
+        }
+    }
+#endif
+    if (!has_printed)
+        fwrite(buf, 1, len, stdout);
+}
+
 static void display_record(Z_External *r)
 {
     const Odr_oid *oid = r->direct_reference;
@@ -908,7 +935,8 @@ static void display_record(Z_External *r)
             || !oid_oidcmp(oid, yaz_oid_recsyn_xml)
             || !oid_oidcmp(oid, yaz_oid_recsyn_html))
         {
-            fwrite(octet_buf, 1, octet_len, stdout);
+            print_xml_record(octet_buf, octet_len);
+
         }
         else if (yaz_oid_is_iso2709(oid))
         {
@@ -2988,21 +3016,50 @@ static int cmd_setnames(const char *arg)
 
 /* PRESENT SERVICE ----------------------------- */
 
+size_t check_token(const char *haystack, const char *token)
+{
+    size_t len = strlen(token);
+    size_t extra;
+    if (strncmp(haystack, token, len))
+        return 0;
+    for (extra = 0; haystack[extra + len] != '\0'; extra++)
+        if (!strchr(" \r\n\t", haystack[extra + len]))
+        {
+            if (extra)
+                break;
+            else
+                return 0;  /* no whitespace after token */
+        }
+    return extra + len;
+}
+
 static int parse_show_args(const char *arg_c, char *setstring,
                            Odr_int *start, Odr_int *number)
 {
     char *end_ptr;
     Odr_int start_position;
+    size_t token_len;
 
     if (setnumber >= 0)
         sprintf(setstring, "%d", setnumber);
     else
         *setstring = '\0';
+    
+    token_len = check_token(arg_c, "format");
+    if (token_len)
+    {
+        pretty_xml = 1;
+        arg_c += token_len;
+    }
+    else
+        pretty_xml = 0;
 
-    if (!strcmp(arg_c, "all"))
+    token_len = check_token(arg_c, "all");
+    if (token_len)
     {
         *number = last_hit_count;
         *start = 1;
+        return 1;
     }
     start_position = odr_strtol(arg_c, &end_ptr, 10);
     if (end_ptr == arg_c)
@@ -4285,7 +4342,7 @@ static void handle_srw_record(Z_SRW_record *rec)
     printf("\n");
     if (rec->recordData_buf && rec->recordData_len)
     {
-        printf("%.*s", rec->recordData_len, rec->recordData_buf);
+        print_xml_record(rec->recordData_buf, rec->recordData_len);
         marc_file_write(rec->recordData_buf, rec->recordData_len);
     }
     else
index d6cd276..bc71bc2 100644 (file)
@@ -1,7 +1,7 @@
 dnl This file is part of the YAZ toolkit.
 dnl Copyright (C) 1995-2011 Index Data
 AC_PREREQ([2.60])
-AC_INIT([yaz],[4.1.3],[yaz-help@indexdata.dk])
+AC_INIT([yaz],[4.1.6],[yaz-help@indexdata.dk])
 AC_CONFIG_HEADERS(include/config.h)
 AC_CONFIG_SRCDIR([configure.ac])
 AC_CONFIG_AUX_DIR([config])
index b3d30a9..1be65a5 100644 (file)
@@ -1,3 +1,21 @@
+yaz (4.1.6-1indexdata) unstable; urgency=low
+
+  * Upstream.
+
+ -- Adam Dickmeiss <adam@indexdata.dk>  Thu, 10 Mar 2011 10:25:48 +0100
+
+yaz (4.1.5-1indexdata) unstable; urgency=low
+
+  * Upstream.
+
+ -- Adam Dickmeiss <adam@indexdata.dk>  Tue, 08 Mar 2011 13:53:17 +0100
+
+yaz (4.1.4-1indexdata) unstable; urgency=low
+
+  * Upstream.
+
+ -- Adam Dickmeiss <adam@indexdata.dk>  Mon, 21 Feb 2011 12:51:04 +0100
+
 yaz (4.1.3-1indexdata) unstable; urgency=low
 
   * Upstream.
index 144918f..db5e508 100755 (executable)
@@ -98,7 +98,7 @@ binary-arch: build install
        dh_fixperms
 #      dh_perl
 #      dh_python
-       dh_makeshlibs -V 'libyaz4 (>= 4.1.0)'
+       dh_makeshlibs -V 'libyaz4 (>= 4.1.5)'
        dh_installdeb
        dh_shlibdeps  -l debian/libyaz4/usr/lib
        dh_gencontrol
index da8f0a9..8a6bb92 100644 (file)
@@ -750,18 +750,29 @@ ZOOM_query_cql2rpn(ZOOM_query s, const char *str, ZOOM_connection conn)
     The <parameter>type</parameter> is a string of the format:
    </para>
    <para>
-    <replaceable>form</replaceable>[;charset=<replaceable>from</replaceable>[,<replaceable>to</replaceable>]][;format=<replaceable>v</replaceable>]
+    <replaceable>format</replaceable>[;charset=<replaceable>from</replaceable>[/<replaceable>opacfrom</replaceable>][,<replaceable>to</replaceable>]][;format=<replaceable>v</replaceable>]
    </para>
    <para>
-    where <replaceable>form</replaceable> specifies the format of the
+    where <replaceable>format</replaceable> specifies the format of the
     returned record, <replaceable>from</replaceable>
     specifies the character set of the record in its original form
     (as returned by the server), <replaceable>to</replaceable> specifies
     the output (returned)
     character set encoding.
-    If charset is not given, then no character set conversion takes place.
     If <replaceable>to</replaceable> is omitted UTF-8 is assumed.
+    If charset is not given, then no character set conversion takes place.
+   </para>
+   
+   <para>OPAC records may be returned in a different
+     set from the bibliographic MARC record. If this is this the case,
+    <replaceable>opacfrom</replaceable> should be set to the character set
+    of the OPAC record part.
    </para>
+   <note>
+     <para>
+       Specifying the OPAC record character set requires YAZ 4.1.5 or later.
+     </para>
+   </note>
    <para>
     The format argument controls whether record data should be XML
     pretty-printed (post process operation).
index 6c64854..c650fca 100644 (file)
@@ -419,10 +419,25 @@ void yaz_marc_write_using_libxml2(yaz_marc_t mt, int enable);
     \param mt handle
     \param r OPAC record
     \param wrbuf WRBUF for resulting display string
+    
+    This function uses iconv_handle of yaz_marc_t for character set
+    conversion of both OPAC + ISO2709 part.
     \*/
 YAZ_EXPORT void yaz_opac_decode_wrbuf(yaz_marc_t mt, Z_OPACRecord *r,
                                       WRBUF wrbuf);
 
+/** \brief Performs "pretty" display of OPAC record to WRBUF using marc_t
+    \param mt handle
+    \param r OPAC record
+    \param wrbuf WRBUF for resulting display string
+    \param cd iconv handle for OPAC content (not ISO2709 part)
+
+    This function uses iconv handle of yaz_marc_t for character set
+    conversion of ISO2709 part and supplied handle (cd) for OPAC part.
+    \*/
+YAZ_EXPORT void yaz_opac_decode_wrbuf2(yaz_marc_t mt, Z_OPACRecord *r,
+                                       WRBUF wrbuf, yaz_iconv_t cd);
+
 /** \brief flushes records
     \param mt handle
     \param wr WRBUF for output
index 7e96839..807ca2b 100644 (file)
@@ -52,10 +52,10 @@ static void opac_element_bool(WRBUF wrbuf, int l, const char *elem, int *data)
     }
 }
 
-void yaz_opac_decode_wrbuf(yaz_marc_t mt, Z_OPACRecord *r, WRBUF wrbuf)
+void yaz_opac_decode_wrbuf2(yaz_marc_t mt, Z_OPACRecord *r, WRBUF wrbuf,
+                            yaz_iconv_t cd)
 {
     int i;
-    yaz_iconv_t cd = yaz_marc_get_iconv(mt);
 
     wrbuf_puts(wrbuf, "<opacRecord>\n");
     if (r->bibliographicRecord)
@@ -163,6 +163,11 @@ void yaz_opac_decode_wrbuf(yaz_marc_t mt, Z_OPACRecord *r, WRBUF wrbuf)
     wrbuf_puts(wrbuf, "</opacRecord>\n");
 }
 
+void yaz_opac_decode_wrbuf(yaz_marc_t mt, Z_OPACRecord *r, WRBUF wrbuf)
+{
+    yaz_opac_decode_wrbuf2(mt, r, wrbuf, yaz_marc_get_iconv(mt));
+}
+
 /*
  * Local variables:
  * c-basic-offset: 4
index cf306ef..ddfd391 100644 (file)
 #include <yaz/proto.h>
 #include <yaz/oid_db.h>
 
-static yaz_iconv_t iconv_create_charset(const char *record_charset)
+static yaz_iconv_t iconv_create_charset(const char *record_charset,
+                                        yaz_iconv_t *cd2)
 {
-    char to[40];
-    char from[40];
+    char charset_buf[40];
     yaz_iconv_t cd = 0;
-
-    *from = '\0';
-    strcpy(to, "UTF-8");
+    char *from_set1 = 0;
+    char *from_set2 = 0;
+    char *to_set = 0;
     if (record_charset && *record_charset)
     {
-        /* Use "from,to" or just "from" */
-        const char *cp = strchr(record_charset, ',');
-        size_t clen = strlen(record_charset);
-        if (cp && cp[1])
+        char *cp = charset_buf;
+        
+        strncpy(charset_buf, record_charset, sizeof(charset_buf)-1);
+        charset_buf[sizeof(charset_buf)-1] = '\0';
+        
+        from_set1 = cp;
+        while (*cp && *cp != ',' && *cp != '/')
+            cp++;
+        if (*cp == '/')
         {
-            strncpy( to, cp+1, sizeof(to)-1);
-            to[sizeof(to)-1] = '\0';
-            clen = cp - record_charset;
+            *cp++ = '\0'; /* terminate from_set1 */
+            from_set2 = cp;
+            while (*cp && *cp != ',')
+                cp++;
+        }
+        if (*cp == ',')
+        {
+            *cp++ = '\0';  /* terminate from_set1 or from_set2 */
+            to_set = cp;
+            while (*cp)
+                cp++;
         }
-        if (clen > sizeof(from)-1)
-            clen = sizeof(from)-1;
-        
-        if (clen)
-            strncpy(from, record_charset, clen);
-        from[clen] = '\0';
     }
-    if (*from && *to)
-        cd = yaz_iconv_open(to, from);
+    
+    if (from_set1)
+        cd = yaz_iconv_open(to_set ? to_set : "UTF-8", from_set1);
+    if (cd2)
+    {
+        if (from_set2)
+            *cd2 = yaz_iconv_open(to_set ? to_set : "UTF-8", from_set2);
+        else
+            *cd2 = 0;
+    }
     return cd;
 }
 
@@ -57,7 +72,7 @@ static const char *return_marc_record(WRBUF wrbuf,
                                       const char *buf, int sz,
                                       const char *record_charset)
 {
-    yaz_iconv_t cd = iconv_create_charset(record_charset);
+    yaz_iconv_t cd = iconv_create_charset(record_charset, 0);
     yaz_marc_t mt = yaz_marc_create();
     const char *ret_string = 0;
 
@@ -82,18 +97,25 @@ static const char *return_opac_record(WRBUF wrbuf,
                                       Z_OPACRecord *opac_rec,
                                       const char *record_charset)
 {
-    yaz_iconv_t cd = iconv_create_charset(record_charset);
+    yaz_iconv_t cd2;
+    yaz_iconv_t cd = iconv_create_charset(record_charset, &cd2);
     yaz_marc_t mt = yaz_marc_create();
 
     if (cd)
         yaz_marc_iconv(mt, cd);
     yaz_marc_xml(mt, marc_type);
 
-    yaz_opac_decode_wrbuf(mt, opac_rec, wrbuf);
+    if (cd2)
+        yaz_opac_decode_wrbuf2(mt, opac_rec, wrbuf, cd2);
+    else
+        yaz_opac_decode_wrbuf(mt, opac_rec, wrbuf);
+        
     yaz_marc_destroy(mt);
 
     if (cd)
         yaz_iconv_close(cd);
+    if (cd2)
+        yaz_iconv_close(cd2);
     if (len)
         *len = wrbuf_len(wrbuf);
     return wrbuf_cstr(wrbuf);
@@ -104,7 +126,7 @@ static const char *return_string_record(WRBUF wrbuf,
                                         const char *buf, int sz,
                                         const char *record_charset)
 {
-    yaz_iconv_t cd = iconv_create_charset(record_charset);
+    yaz_iconv_t cd = iconv_create_charset(record_charset, 0);
 
     if (cd)
     {
index 659d16f..569125b 100644 (file)
 #include <libxml/parser.h>
 #include <libxml/tree.h>
 
-const char *xml_node_attribute_value_get(xmlNodePtr ptr, const char *node_name, const char *attribute_name) {
-
-    struct _xmlAttr *attr;
-    // check if the node name matches
-    if (strcmp((const char*) ptr->name, node_name))
-        return 0;
-    // check if the attribute name and return the value
-    for (attr = ptr->properties; attr; attr = attr->next)
-        if (attr->children && attr->children->type == XML_TEXT_NODE) {
-            if (!strcmp((const char *) attr->name, attribute_name))
-                return (const char *) attr->children->content;
-        }
-    return 0;
-}
-
-
 static int match_xml_node_attribute(xmlNodePtr ptr, const char *node_name, const char *attribute_name, const char *value)
 {
     const char *attribute_value;
     // check if the node name matches
     if (strcmp((const char*) ptr->name, node_name))
         return 0;
-    attribute_value = xml_node_attribute_value_get(ptr, node_name, attribute_name);
-    if (attribute_value && !strcmp(attribute_value, value))
+    if (attribute_name) {
+        attribute_value = yaz_element_attribute_value_get(ptr, node_name, attribute_name);
+        if (attribute_value && !strcmp(attribute_value, value))
+            return 1;
+    }
+    else /* No attribute to check */
         return 1;
     return 0;
 }
@@ -117,38 +105,9 @@ static int  yaz_solr_decode_result(ODR o, xmlNodePtr ptr, Z_SRW_searchRetrieveRe
     return -1;
 }
 
-static Z_AttributeList *yaz_solr_use_atttribute_create(ODR o, const char *name) {
-    Z_AttributeList *attributes= (Z_AttributeList *) odr_malloc(o, sizeof(*attributes));
-    Z_AttributeElement ** elements;
-    attributes->num_attributes = 1;
-    /* TODO check on name instead
-    if (!attributes->num_attributes) {
-        attributes->attributes = (Z_AttributeElement**)odr_nullval();
-        return attributes;
-    }
-    */
-    elements = (Z_AttributeElement**) odr_malloc (o, attributes->num_attributes * sizeof(*elements));
-    elements[0] = (Z_AttributeElement*)odr_malloc(o,sizeof(**elements));
-    elements[0]->attributeType = odr_malloc(o, sizeof(*elements[0]->attributeType));
-   *elements[0]->attributeType = 1;
-    elements[0]->attributeSet = odr_nullval();
-    elements[0]->which = Z_AttributeValue_complex;
-    elements[0]->value.complex = (Z_ComplexAttribute *) odr_malloc(o, sizeof(Z_ComplexAttribute));
-    elements[0]->value.complex->num_list = 1;
-    elements[0]->value.complex->list = (Z_StringOrNumeric **) odr_malloc(o, 1 * sizeof(Z_StringOrNumeric *));
-    elements[0]->value.complex->list[0] = (Z_StringOrNumeric *) odr_malloc(o, sizeof(Z_StringOrNumeric));
-    elements[0]->value.complex->list[0]->which = Z_StringOrNumeric_string;
-    elements[0]->value.complex->list[0]->u.string = (Z_InternationalString *) odr_strdup(o, name);
-    elements[0]->value.complex->semanticAction = 0;
-    elements[0]->value.complex->num_semanticAction = 0;
-    attributes->attributes = elements;
-    return attributes;
-}
-
-
 static const char *get_facet_term_count(xmlNodePtr node, int *freq) {
 
-    const char *term = xml_node_attribute_value_get(node, "int", "name");
+    const char *term = yaz_element_attribute_value_get(node, "int", "name");
     xmlNodePtr child;
     WRBUF wrbuf = wrbuf_alloc();
     if (!term)
@@ -172,13 +131,13 @@ Z_FacetField *yaz_solr_decode_facet_field(ODR o, xmlNodePtr ptr, Z_SRW_searchRet
     int index = 0;
     xmlNodePtr node;
     // USE attribute
-    const char* name = xml_node_attribute_value_get(ptr, "lst", "name");
+    const char* name = yaz_element_attribute_value_get(ptr, "lst", "name");
     char *pos = strstr(name, "_exact");
     /* HACK */
     if (pos) {
         pos[0] = 0;
     }
-    list = yaz_solr_use_atttribute_create(o, name);
+    list = yaz_use_atttribute_create(o, name);
     for (node = ptr->children; node; node = node->next) {
         num_terms++;
     }
index 1458d8e..9cd2597 100644 (file)
@@ -34,6 +34,15 @@ void yaz_add_name_value_str(ODR o, char **name, char **value,  int *i,
 
 void yaz_add_name_value_int(ODR o, char **name, char **value, int *i,
                             char *a_name, Odr_int *val);
+
+Z_AttributeList *yaz_use_atttribute_create(ODR o, const char *name);
+
+#if YAZ_HAVE_XML2
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+const char *yaz_element_attribute_value_get(xmlNodePtr ptr, const char *node_name, const char *attribute_name);
+#endif
+
 /*
  * Local variables:
  * c-basic-offset: 4
index d0f8309..bd3c577 100644 (file)
--- a/src/srw.c
+++ b/src/srw.c
 #include <config.h>
 #endif
 
+#include <stdlib.h>
+
 #include <yaz/srw.h>
+#include <yaz/wrbuf.h>
 #if YAZ_HAVE_XML2
 #include <libxml/parser.h>
 #include <libxml/tree.h>
 #include <assert.h>
 
+#include "sru-p.h"
+
 static void add_XML_n(xmlNodePtr ptr, const char *elem, char *val, int len,
                       xmlNsPtr ns_ptr)
 {
@@ -442,11 +447,91 @@ static int yaz_srw_versions(ODR o, xmlNodePtr pptr,
     return 0;
 }
 
+Z_FacetTerm *yaz_sru_proxy_get_facet_term_count(ODR odr, xmlNodePtr node) {
+
+    int freq;
+    xmlNodePtr child;
+    WRBUF wrbuf = wrbuf_alloc();
+    const char *freq_string = yaz_element_attribute_value_get(node, "facetvalue", "est_representation");
+    Z_Term *term;
+    if (freq_string)
+        freq =  atoi(freq_string);
+    else
+        freq = -1;
+
+    for (child = node->children; child ; child = child->next) {
+        if (child->type == XML_TEXT_NODE)
+        wrbuf_puts(wrbuf, (const char *) child->content);
+    }
+    term = term_create(odr, wrbuf_cstr(wrbuf));
+    yaz_log(YLOG_DEBUG, "sru-proxy facet: %s %d", wrbuf_cstr(wrbuf), freq);
+    wrbuf_destroy(wrbuf);
+    return facet_term_create(odr, term, freq);
+};
+
+static Z_FacetField *yaz_sru_proxy_decode_facet_field(ODR odr, xmlNodePtr ptr) {
+    Z_AttributeList *list;
+    Z_FacetField *facet_field;
+    int num_terms = 0;
+    int index = 0;
+    xmlNodePtr node;
+    // USE attribute
+    const char* name = yaz_element_attribute_value_get(ptr, "facet", "code");
+    yaz_log(YLOG_DEBUG, "sru-proxy facet type: %s", name);
+
+    list = yaz_use_atttribute_create(odr, name);
+    for (node = ptr->children; node; node = node->next) {
+        if (match_element(node, "facetvalue"))
+            num_terms++;
+    }
+    facet_field = facet_field_create(odr, list, num_terms);
+    index = 0;
+    for (node = ptr->children; node; node = node->next) {
+        if (match_element(node, "facetvalue")) {
+            facet_field_term_set(odr, facet_field, yaz_sru_proxy_get_facet_term_count(odr, node), index);
+        index++;
+        }
+    }
+    return facet_field;
+}
+
+static int yaz_sru_proxy_decode_facets(ODR o, xmlNodePtr root, Z_FacetList **facetList)
+{
+    xmlNodePtr ptr;
+
+    for (ptr = root->children; ptr; ptr = ptr->next)
+    {
+        if (match_element(ptr, "facets"))
+        {
+            xmlNodePtr node;
+            Z_FacetList *facet_list;
+            int num_facets = 0;
+            for (node = ptr->children; node; node= node->next)
+            {
+                if (node->type == XML_ELEMENT_NODE)
+                    num_facets++;
+            }
+            facet_list = facet_list_create(o, num_facets);
+            num_facets = 0;
+            for (node = ptr->children; node; node= node->next)
+            {
+                if (match_element(node, "facet")) {
+                    facet_list_field_set(o, facet_list, yaz_sru_proxy_decode_facet_field(o, node), num_facets);
+                    num_facets++;
+                }
+            }
+            *facetList = facet_list;
+            break;
+        }
+    }
+    return 0;
+}
+
+
 
 static int yaz_srw_decode_diagnostics(ODR o, xmlNodePtr pptr,
                                       Z_SRW_diagnostic **recs, int *num,
                                       void *client_data, const char *ns)
-    
 {
     int i;
     xmlNodePtr ptr;
@@ -768,6 +853,8 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data,
                     yaz_srw_diagnostics(o, ptr, &res->diagnostics,
                                         &res->num_diagnostics,
                                         client_data, ns);
+                else if (match_element(ptr, "facet_analysis"))
+                    yaz_sru_proxy_decode_facets(o, ptr, &res->facetList);
             }
         }
         else if (!xmlStrcmp(method->name, BAD_CAST "explainRequest"))
index 7e05318..353286f 100644 (file)
@@ -36,7 +36,51 @@ char *yaz_encode_sru_dbpath_odr(ODR out, const char *db)
     return dst;
 }
 
+Z_AttributeList *yaz_use_atttribute_create(ODR o, const char *name) {
+    Z_AttributeList *attributes= (Z_AttributeList *) odr_malloc(o, sizeof(*attributes));
+    Z_AttributeElement ** elements;
+    attributes->num_attributes = 1;
+    /* TODO check on name instead
+    if (!attributes->num_attributes) {
+        attributes->attributes = (Z_AttributeElement**)odr_nullval();
+        return attributes;
+    }
+    */
+    elements = (Z_AttributeElement**) odr_malloc (o, attributes->num_attributes * sizeof(*elements));
+    elements[0] = (Z_AttributeElement*)odr_malloc(o,sizeof(**elements));
+    elements[0]->attributeType = odr_malloc(o, sizeof(*elements[0]->attributeType));
+   *elements[0]->attributeType = 1;
+    elements[0]->attributeSet = odr_nullval();
+    elements[0]->which = Z_AttributeValue_complex;
+    elements[0]->value.complex = (Z_ComplexAttribute *) odr_malloc(o, sizeof(Z_ComplexAttribute));
+    elements[0]->value.complex->num_list = 1;
+    elements[0]->value.complex->list = (Z_StringOrNumeric **) odr_malloc(o, 1 * sizeof(Z_StringOrNumeric *));
+    elements[0]->value.complex->list[0] = (Z_StringOrNumeric *) odr_malloc(o, sizeof(Z_StringOrNumeric));
+    elements[0]->value.complex->list[0]->which = Z_StringOrNumeric_string;
+    elements[0]->value.complex->list[0]->u.string = (Z_InternationalString *) odr_strdup(o, name);
+    elements[0]->value.complex->semanticAction = 0;
+    elements[0]->value.complex->num_semanticAction = 0;
+    attributes->attributes = elements;
+    return attributes;
+}
+
 #if YAZ_HAVE_XML2
+const char *yaz_element_attribute_value_get(xmlNodePtr ptr, const char *node_name, const char *attribute_name) {
+
+    struct _xmlAttr *attr;
+    // check if the node name matches
+    if (strcmp((const char*) ptr->name, node_name))
+        return 0;
+    // check if the attribute name and return the value
+    for (attr = ptr->properties; attr; attr = attr->next)
+        if (attr->children && attr->children->type == XML_TEXT_NODE) {
+            if (!strcmp((const char *) attr->name, attribute_name))
+                return (const char *) attr->children->content;
+        }
+    return 0;
+}
+
+
 static int yaz_base64decode(const char *in, char *out)
 {
     const char *map = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -1193,6 +1237,7 @@ int yaz_sru_get_encode(Z_HTTP_Request *hreq, Z_SRW_PDU *srw_pdu,
         odr_malloc(encode, strlen(hreq->path) + strlen(uri_args) + 4);
 
     sprintf(path, "%s?%s", hreq->path, uri_args);
+    yaz_log(YLOG_DEBUG, "SRU HTTP Get Request %s", path);
     hreq->path = path;
 
     z_HTTP_header_add_content_type(encode, &hreq->headers,
index a8bf02a..7ee2633 100644 (file)
@@ -27,9 +27,7 @@ struct yaz_stemmer_t
     // Required for cloning.
     char *locale;
     char *rule;
-    union {
-        struct sb_stemmer *sb_stemmer;
-    };
+    struct sb_stemmer *sb_stemmer;
 };
 
 const char* yaz_stemmer_lookup_charenc(const char *charenc, const char *rule) {
index 51cd83e..005e724 100644 (file)
@@ -40,6 +40,7 @@ static zoom_ret do_write_ex(ZOOM_connection c, char *buf_out, int len_out);
 static void initlog(void)
 {
     static int log_level_initialized = 0;
+
     if (!log_level_initialized)
     {
         log_api0 = yaz_log_module_level("zoom");
@@ -609,6 +610,27 @@ void ZOOM_resultset_addref(ZOOM_resultset r)
     }
 }
 
+static int g_resultsets = 0;
+static YAZ_MUTEX g_resultset_mutex = 0;
+
+/* TODO We need to initialize this before running threaded:
+ * call resultset_use(0)  */
+
+static int resultset_use(int delta) {
+    int resultset_count;
+    if (g_resultset_mutex == 0)
+        yaz_mutex_create(&g_resultset_mutex);
+    yaz_mutex_enter(g_resultset_mutex);
+    g_resultsets += delta;
+    resultset_count = g_resultsets;
+    yaz_mutex_leave(g_resultset_mutex);
+    return resultset_count;
+}
+
+int resultsets_count(void) {
+    return resultset_use(0);
+}
+
 ZOOM_resultset ZOOM_resultset_create(void)
 {
     int i;
@@ -642,6 +664,7 @@ ZOOM_resultset ZOOM_resultset_create(void)
         YAZ_SHPTR_INIT(r->record_wrbuf, w);
     }
 #endif
+    resultset_use(1);
     return r;
 }
 
@@ -831,6 +854,7 @@ static void resultset_destroy(ZOOM_resultset r)
 #if SHPTR
         YAZ_SHPTR_DEC(r->record_wrbuf, wrbuf_destroy);
 #endif
+        resultset_use(-1);
         xfree(r);
     }
     else
index e0c1052..fb7f68e 100644 (file)
--- a/yaz.spec
+++ b/yaz.spec
@@ -5,7 +5,7 @@
 
 Name: yaz
 Summary: Z39.50 Programs
-Version: 4.1.3
+Version: 4.1.6
 Release: 1indexdata
 
 # determine system