String attribute values for PQF. Proper C-backslash escaping for PQF.
[yaz-moved-to-github.git] / zutil / yaz-ccl.c
index 4233744..d1ab287 100644 (file)
@@ -1,10 +1,48 @@
 /*
- * Copyright (c) 1996-1998, Index Data.
+ * Copyright (c) 1996-2001, Index Data.
  * See the file LICENSE for details.
- * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: yaz-ccl.c,v $
- * Revision 1.1  1999-06-08 10:12:43  adam
+ * Revision 1.13  2001-05-09 23:31:35  adam
+ * String attribute values for PQF. Proper C-backslash escaping for PQF.
+ *
+ * Revision 1.12  2001/03/07 13:24:40  adam
+ * Member and_not in Z_Operator is kept for backwards compatibility.
+ * Added support for definition of CCL operators in field spec file.
+ *
+ * Revision 1.11  2001/02/21 13:46:54  adam
+ * C++ fixes.
+ *
+ * Revision 1.10  2001/02/20 11:23:50  adam
+ * Updated ccl_pquery to consider local attribute set too.
+ *
+ * Revision 1.9  2000/11/27 14:16:55  adam
+ * Fixed bug in ccl_rpn_simple regarding resultSetId's.
+ *
+ * Revision 1.8  2000/11/16 13:03:13  adam
+ * Function ccl_rpn_query sets attributeSet to Bib-1.
+ *
+ * Revision 1.7  2000/11/16 09:58:02  adam
+ * Implemented local AttributeSet setting for CCL field maps.
+ *
+ * Revision 1.6  2000/02/02 15:13:23  adam
+ * Minor change.
+ *
+ * Revision 1.5  2000/01/31 13:15:22  adam
+ * Removed uses of assert(3). Cleanup of ODR. CCL parser update so
+ * that some characters are not surrounded by spaces in resulting term.
+ * ILL-code updates.
+ *
+ * Revision 1.4  1999/12/20 15:20:13  adam
+ * Implemented ccl_pquery to convert from CCL tree to prefix query.
+ *
+ * Revision 1.3  1999/11/30 13:47:12  adam
+ * Improved installation. Moved header files to include/yaz.
+ *
+ * Revision 1.2  1999/06/16 12:00:08  adam
+ * Added proximity.
+ *
+ * Revision 1.1  1999/06/08 10:12:43  adam
  * Moved file to be part of zutil (instead of util).
  *
  * Revision 1.13  1998/03/31 15:13:20  adam
@@ -31,9 +69,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <assert.h>
 
-#include <yaz-ccl.h>
+#include <yaz/yaz-ccl.h>
 
 static Z_RPNStructure *ccl_rpn_structure (ODR o, struct ccl_rpn_node *p);
 
@@ -47,13 +84,10 @@ static Z_AttributesPlusTerm *ccl_rpn_term (ODR o, struct ccl_rpn_node *p)
     Z_AttributeElement **elements;
 
     zapt = (Z_AttributesPlusTerm *)odr_malloc (o, sizeof(*zapt));
-    assert (zapt);
 
     term_octet = (Odr_oct *)odr_malloc (o, sizeof(*term_octet));
-    assert (term_octet);
 
     term = (Z_Term *)odr_malloc (o, sizeof(*term));
-    assert(term);
 
     for (attr = p->u.t.attr_list; attr; attr = attr->next)
         num++;
@@ -68,11 +102,26 @@ static Z_AttributesPlusTerm *ccl_rpn_term (ODR o, struct ccl_rpn_node *p)
         {
             elements[i] = (Z_AttributeElement *)
                odr_malloc (o, sizeof(**elements));
-            assert (elements[i]);
             elements[i]->attributeType =
                (int *)odr_malloc(o, sizeof(int));
             *elements[i]->attributeType = attr->type;
            elements[i]->attributeSet = 0;
+           if (attr->set && *attr->set)
+           {
+               int value = oid_getvalbyname (attr->set);
+
+               if (value != VAL_NONE)
+               {
+                   int oid[OID_SIZE];
+                   struct oident ident;
+
+                   ident.oclass = CLASS_ATTSET;
+                   ident.proto = PROTO_Z3950;
+                   ident.value = (oid_value) value;
+                   elements[i]->attributeSet =
+                       odr_oiddup (o, oid_ent_to_oid (&ident, oid));
+               }
+           }
            elements[i]->which = Z_AttributeValue_numeric;
            elements[i]->value.numeric =
                (int *)odr_malloc (o, sizeof(int));
@@ -102,7 +151,6 @@ static Z_Operand *ccl_rpn_simple (ODR o, struct ccl_rpn_node *p)
     Z_Operand *zo;
 
     zo = (Z_Operand *)odr_malloc (o, sizeof(*zo));
-    assert (zo);
 
     switch (p->kind)
     {
@@ -112,10 +160,10 @@ static Z_Operand *ccl_rpn_simple (ODR o, struct ccl_rpn_node *p)
         break;
     case CCL_RPN_SET:
         zo->which = Z_Operand_resultSetId;
-        zo->u.resultSetId = p->u.setname;
+        zo->u.resultSetId = odr_strdup (o, p->u.setname);
         break;
     default:
-        assert (0);
+       return 0;
     }
     return zo;
 }
@@ -126,27 +174,55 @@ static Z_Complex *ccl_rpn_complex (ODR o, struct ccl_rpn_node *p)
     Z_Operator *zo;
 
     zc = (Z_Complex *)odr_malloc (o, sizeof(*zc));
-    assert (zc);
     zo = (Z_Operator *)odr_malloc (o, sizeof(*zo));
-    assert (zo);
 
     zc->roperator = zo;
     switch (p->kind)
     {
     case CCL_RPN_AND:
         zo->which = Z_Operator_and;
-        zo->u.and = odr_nullval();
+        zo->u.and_not = odr_nullval();
         break;
     case CCL_RPN_OR:
         zo->which = Z_Operator_or;
-        zo->u.and = odr_nullval();
+        zo->u.and_not = odr_nullval();
         break;
     case CCL_RPN_NOT:
         zo->which = Z_Operator_and_not;
-        zo->u.and = odr_nullval();
+        zo->u.and_not = odr_nullval();
         break;
+    case CCL_RPN_PROX:
+       zo->which = Z_Operator_prox;
+       zo->u.prox = (Z_ProximityOperator *)
+           odr_malloc (o, sizeof(*zo->u.prox));
+       zo->u.prox->exclusion = 0;
+
+       zo->u.prox->distance = (int *)
+           odr_malloc (o, sizeof(*zo->u.prox->distance));
+       *zo->u.prox->distance = 2;
+
+       zo->u.prox->ordered = (bool_t *)
+           odr_malloc (o, sizeof(*zo->u.prox->ordered));
+       *zo->u.prox->ordered = 0;
+
+       zo->u.prox->relationType = (int *)
+           odr_malloc (o, sizeof(*zo->u.prox->relationType));
+#ifdef ASN_COMPILED
+       *zo->u.prox->relationType = Z_ProximityOperator_Prox_lessThan;
+       zo->u.prox->which = Z_ProximityOperator_known;
+       zo->u.prox->u.known = 
+           (Z_ProxUnit *) odr_malloc (o, sizeof(*zo->u.prox->u.known));
+       *zo->u.prox->u.known = Z_ProxUnit_word;
+#else
+       *zo->u.prox->relationType = Z_Prox_lessThan;
+       zo->u.prox->which = Z_ProxCode_known;
+       zo->u.prox->proximityUnitCode = (int*)
+           odr_malloc (o, sizeof(*zo->u.prox->proximityUnitCode));
+       *zo->u.prox->proximityUnitCode = Z_ProxUnit_word;
+#endif
+       break;
     default:
-        assert (0);
+       return 0;
     }
     zc->s1 = ccl_rpn_structure (o, p->u.p[0]);
     zc->s2 = ccl_rpn_structure (o, p->u.p[1]);
@@ -158,7 +234,6 @@ static Z_RPNStructure *ccl_rpn_structure (ODR o, struct ccl_rpn_node *p)
     Z_RPNStructure *zs;
 
     zs = (Z_RPNStructure *)odr_malloc (o, sizeof(*zs));
-    assert (zs);
     switch (p->kind)
     {
     case CCL_RPN_AND:
@@ -174,7 +249,7 @@ static Z_RPNStructure *ccl_rpn_structure (ODR o, struct ccl_rpn_node *p)
         zs->u.simple = ccl_rpn_simple (o, p);
         break;
     default:
-        assert (0);
+       return 0;
     }
     return zs;
 }
@@ -182,10 +257,14 @@ static Z_RPNStructure *ccl_rpn_structure (ODR o, struct ccl_rpn_node *p)
 Z_RPNQuery *ccl_rpn_query (ODR o, struct ccl_rpn_node *p)
 {
     Z_RPNQuery *zq;
+    oident bib1;
+    int oid[OID_SIZE];
+    bib1.proto = PROTO_Z3950;
+    bib1.oclass = CLASS_ATTSET;
+    bib1.value = VAL_BIB1;
 
     zq = (Z_RPNQuery *)odr_malloc (o, sizeof(*zq));
-    assert (zq);
-    zq->attributeSetId = NULL;
+    zq->attributeSetId = odr_oiddup (o, oid_ent_to_oid (&bib1, oid));
     zq->RPNStructure = ccl_rpn_structure (o, p);
     return zq;
 }
@@ -196,3 +275,68 @@ Z_AttributesPlusTerm *ccl_scan_query (ODR o, struct ccl_rpn_node *p)
         return NULL;
     return ccl_rpn_term (o, p);
 }
+
+static void ccl_pquery_complex (WRBUF w, struct ccl_rpn_node *p)
+{
+    switch (p->kind)
+    {
+    case CCL_RPN_AND:
+       wrbuf_puts (w, "@and ");
+       break;
+    case CCL_RPN_OR:
+       wrbuf_puts(w, "@or ");
+       break;
+    case CCL_RPN_NOT:
+       wrbuf_puts(w, "@not ");
+       break;
+    case CCL_RPN_PROX:
+       wrbuf_puts(w, "@prox 0 2 0 1 known 2 ");
+       break;
+    default:
+       wrbuf_puts(w, "@ bad op (unknown) ");
+    };
+    ccl_pquery(w, p->u.p[0]);
+    ccl_pquery(w, p->u.p[1]);
+}
+       
+void ccl_pquery (WRBUF w, struct ccl_rpn_node *p)
+{
+    struct ccl_rpn_attr *att;
+    const char *cp;
+
+    switch (p->kind)
+    {
+    case CCL_RPN_AND:
+    case CCL_RPN_OR:
+    case CCL_RPN_NOT:
+    case CCL_RPN_PROX:
+       ccl_pquery_complex (w, p);
+       break;
+    case CCL_RPN_SET:
+       wrbuf_puts (w, "@set ");
+       wrbuf_puts (w, p->u.setname);
+       wrbuf_puts (w, " ");
+       break;
+    case CCL_RPN_TERM:
+       for (att = p->u.t.attr_list; att; att = att->next)
+       {
+           char tmpattr[128];
+           wrbuf_puts (w, "@attr ");
+           if (att->set)
+           {
+               wrbuf_puts (w, att->set);
+               wrbuf_puts (w, " ");
+           }
+           sprintf(tmpattr, "%d=%d ", att->type, att->value);
+           wrbuf_puts (w, tmpattr);
+       }
+       for (cp = p->u.t.term; *cp; cp++)
+       {
+           if (*cp == ' ' || *cp == '\\')
+               wrbuf_putc (w, '\\');
+           wrbuf_putc (w, *cp);
+       }
+       wrbuf_puts (w, " ");
+       break;
+    }
+}