Updates to faciliate non-private character set negotiations
[yaz-moved-to-github.git] / zutil / pquery.c
index 0df4c1b..6fd0fc0 100644 (file)
@@ -1,13 +1,14 @@
 /*
- * Copyright (c) 1995-2001, Index Data.
+ * Copyright (c) 1995-2002, Index Data.
  * See the file LICENSE for details.
  *
- * $Id: pquery.c,v 1.11 2001-11-13 23:00:43 adam Exp $
+ * $Id: pquery.c,v 1.16 2002-07-25 12:48:39 adam Exp $
  */
 
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
+#include <ctype.h>
 
 #include <yaz/proto.h>
 #include <yaz/oid.h>
@@ -70,7 +71,13 @@ static int query_token (struct lex_info *li)
         ++(*qptr);
     }
     li->lex_buf = *qptr;
-    
+   
+    if (**qptr == li->escape_char && isdigit ((*qptr)[1]))
+    {
+       ++(li->lex_len);
+       ++(*qptr);
+       return 'l';
+    }
     while (**qptr && **qptr != sep_char)
     {
        if (**qptr == '\\')
@@ -83,7 +90,8 @@ static int query_token (struct lex_info *li)
     }
     if (**qptr)
        ++(*qptr);
-    if (li->lex_len >= 1 && li->lex_buf[0] == li->escape_char)
+    if (sep_char == ' ' &&
+        li->lex_len >= 1 && li->lex_buf[0] == li->escape_char)
     {
        if (compare_term (li, "and", 1))
            return 'a';
@@ -253,6 +261,7 @@ static Z_AttributesPlusTerm *rpn_term (struct lex_info *li, ODR o,
             elements[k]->attributeType = &attr_tmp[2*i];
            elements[k]->attributeSet =
                yaz_oidval_to_z3950oid(o, CLASS_ATTSET, attr_set[i]);
+
            if (attr_clist[i])
            {
                elements[k]->which = Z_AttributeValue_complex;
@@ -288,11 +297,35 @@ static Z_AttributesPlusTerm *rpn_term (struct lex_info *li, ODR o,
     zapt->attributes->attributes = elements;
 
     zapt->term = term;
-    term->which = Z_Term_general;
-    term->u.general = term_octet;
-    term_octet->buf = (unsigned char *)odr_malloc (o, li->lex_len);
+
+    term_octet->buf = (unsigned char *)odr_malloc (o, 1 + li->lex_len);
     term_octet->size = term_octet->len =
-       escape_string ((char *) (term_octet->buf), li->lex_buf, li->lex_len);
+        escape_string ((char *) (term_octet->buf), li->lex_buf, li->lex_len);
+    term_octet->buf[term_octet->size] = 0;  /* null terminate */
+    
+    switch (li->term_type)
+    {
+    case Z_Term_general:
+        term->which = Z_Term_general;
+        term->u.general = term_octet;
+        break;
+    case Z_Term_characterString:
+        term->which = Z_Term_characterString;
+        term->u.characterString = term_octet->buf;  /* null terminated above */
+        break;
+    case Z_Term_numeric:
+        term->which = Z_Term_numeric;
+        term->u.numeric = odr_intdup (o, atoi(term_octet->buf));
+        break;
+    case Z_Term_null:
+        term->which = Z_Term_null;
+        term->u.null = odr_nullval();
+        break;
+    default:
+        term->which = Z_Term_null;
+        term->u.null = odr_nullval();
+        break;
+    }
     return zapt;
 }
 
@@ -310,13 +343,13 @@ static Z_Operand *rpn_simple (struct lex_info *li, ODR o, oid_proto proto,
         if (!(zo->u.attributesPlusTerm =
               rpn_term (li, o, proto, num_attr, attr_list, attr_clist,
                        attr_set)))
-            return NULL;
+            return 0;
         lex (li);
         break;
     case 's':
         lex (li);
         if (!li->query_look)
-            return NULL;
+            return 0;
         zo->which = Z_Operand_resultSetId;
         zo->u.resultSetId = (char *)odr_malloc (o, li->lex_len+1);
         memcpy (zo->u.resultSetId, li->lex_buf, li->lex_len);
@@ -324,7 +357,7 @@ static Z_Operand *rpn_simple (struct lex_info *li, ODR o, oid_proto proto,
         lex (li);
         break;
     default:
-        return NULL;
+        return 0;
     }
     return zo;
 }
@@ -426,6 +459,25 @@ static Z_Complex *rpn_complex (struct lex_info *li, ODR o, oid_proto proto,
     return zc;
 }
 
+static void rpn_term_type (struct lex_info *li, ODR o)
+{
+    if (!li->query_look)
+        return ;
+    if (compare_term (li, "general", 0))
+        li->term_type = Z_Term_general;
+    else if (compare_term (li, "numeric", 0))
+        li->term_type = Z_Term_numeric;
+    else if (compare_term (li, "string", 0))
+        li->term_type = Z_Term_characterString;
+    else if (compare_term (li, "oid", 0))
+        li->term_type = Z_Term_oid;
+    else if (compare_term (li, "datetime", 0))
+        li->term_type = Z_Term_dateTime;
+    else if (compare_term (li, "null", 0))
+        li->term_type = Z_Term_null;
+    lex (li);
+}
+                           
 static Z_RPNStructure *rpn_structure (struct lex_info *li, ODR o,
                                       oid_proto proto, 
                                       int num_attr, int max_attr, 
@@ -462,7 +514,9 @@ static Z_RPNStructure *rpn_structure (struct lex_info *li, ODR o,
             return NULL;
         if (num_attr >= max_attr)
             return NULL;
-       p_query_parse_attr(li, o, num_attr, attr_list, attr_clist, attr_set);
+       if (!p_query_parse_attr(li, o, num_attr, attr_list,
+                                attr_clist, attr_set))
+            return 0;
        num_attr++;
         lex (li);
         return
@@ -470,21 +524,7 @@ static Z_RPNStructure *rpn_structure (struct lex_info *li, ODR o,
                           attr_clist,  attr_set);
     case 'y':
        lex (li);
-       if (!li->query_look)
-           return NULL;
-       if (compare_term (li, "general", 0))
-           li->term_type = Z_Term_general;
-       else if (compare_term (li, "numeric", 0))
-           li->term_type = Z_Term_numeric;
-       else if (compare_term (li, "string", 0))
-           li->term_type = Z_Term_characterString;
-       else if (compare_term (li, "oid", 0))
-           li->term_type = Z_Term_oid;
-       else if (compare_term (li, "datetime", 0))
-           li->term_type = Z_Term_dateTime;
-       else if (compare_term (li, "null", 0))
-           li->term_type = Z_Term_null;
-       lex (li);
+        rpn_term_type (li, o);
         return
             rpn_structure (li, o, proto, num_attr, max_attr, attr_list,
                           attr_clist, attr_set);
@@ -571,16 +611,28 @@ Z_AttributesPlusTerm *p_query_scan_mk (struct lex_info *li,
 
     *attributeSetP = yaz_oidval_to_z3950oid (o, CLASS_ATTSET, topSet);
 
-    while (li->query_look == 'l')
+    while (1)
     {
-        lex (li);
-        if (!li->query_look)
-            return NULL;
-        if (num_attr >= max_attr)
-            return NULL;
-        p_query_parse_attr(li, o, num_attr, attr_list, attr_clist, attr_set);
-        num_attr++;
-        lex (li);
+        if (li->query_look == 'l')
+        {
+            lex (li);
+            if (!li->query_look)
+                return 0;
+            if (num_attr >= max_attr)
+                return 0;
+            if (!p_query_parse_attr(li, o, num_attr, attr_list,
+                                    attr_clist, attr_set))
+                return 0;
+            num_attr++;
+            lex (li);
+        }
+        else if (li->query_look == 'y')
+        {
+            lex (li);
+            rpn_term_type (li, o);
+        }
+        else
+            break;
     }
     if (!li->query_look)
         return NULL;