New function, p_query_rpn, to convert from prefix (ascii) to rpn (asn).
authorAdam Dickmeiss <adam@indexdata.dk>
Mon, 22 May 1995 15:31:05 +0000 (15:31 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Mon, 22 May 1995 15:31:05 +0000 (15:31 +0000)
include/pquery.h [new file with mode: 0644]
util/Makefile
util/pquery.c [new file with mode: 0644]

diff --git a/include/pquery.h b/include/pquery.h
new file mode 100644 (file)
index 0000000..e845eb2
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 1995, Index Data.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation, in whole or in part, for any purpose, is hereby granted,
+ * provided that:
+ *
+ * 1. This copyright and permission notice appear in all copies of the
+ * software and its documentation. Notices of copyright or attribution
+ * which appear at the beginning of any file must remain unchanged.
+ *
+ * 2. The name of Index Data or the individual authors may not be used to
+ * endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED, OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ * IN NO EVENT SHALL INDEX DATA BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR
+ * NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ *
+ * $Log: pquery.h,v $
+ * Revision 1.1  1995-05-22 15:31:05  adam
+ * New function, p_query_rpn, to convert from prefix (ascii) to rpn (asn).
+ *
+ */
+
+#ifndef PQUERY_H
+#define PQUERY_H
+
+#include <proto.h>
+
+Z_RPNQuery *p_query_rpn (ODR o, const char *qbuf);
+#endif
index 2e3efcb..43d171c 100644 (file)
@@ -1,7 +1,7 @@
 # Copyright (C) 1994, Index Data I/S 
 # All rights reserved.
 # Sebastian Hammer, Adam Dickmeiss
-# $Id: Makefile,v 1.9 1995-05-22 11:32:15 quinn Exp $
+# $Id: Makefile,v 1.10 1995-05-22 15:31:48 adam Exp $
 
 SHELL=/bin/sh
 INCLUDE=-I../include -I.
@@ -11,7 +11,7 @@ LIBINCLUDE=-L$(LIBDIR)
 DEFS=$(INCLUDE)
 LIB=$(LIBDIR)/libutil.a
 LIBS=
-PO = options.o log.o marcdisp.o yaz-ccl.o # dmalloc.o
+PO = options.o log.o marcdisp.o yaz-ccl.o pquery.o # dmalloc.o
 CPP=$(CC) -E
 
 all: $(LIBDIR) $(LIB) marcdump
diff --git a/util/pquery.c b/util/pquery.c
new file mode 100644 (file)
index 0000000..40e243d
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 1995, Index Data.
+ * See the file LICENSE for details.
+ * Sebastian Hammer, Adam Dickmeiss
+ *
+ * $Log: pquery.c,v $
+ * Revision 1.1  1995-05-22 15:31:49  adam
+ * New function, p_query_rpn, to convert from prefix (ascii) to rpn (asn).
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <proto.h>
+#include <oid.h>
+
+#include <pquery.h>
+
+static const char *query_buf;
+static const char *query_lex_buf;
+static int query_lex_len;
+static int query_look = 0;
+static char *left_sep = "{\"";
+static char *right_sep = "}\"";
+static int escape_char = '@';
+
+static Z_RPNStructure *rpn_structure (ODR o, int num_attr, int max_attr, 
+                                      int *attr_list);
+
+static int query_token (const char **qptr, const char **lex_buf, int *lex_len)
+{
+    const char *sep_match;
+
+    while (**qptr == ' ')
+        (*qptr)++;
+    if (**qptr == '\0')
+        return 0;
+    *lex_len = 0;
+    if ((sep_match = strchr (left_sep, **qptr)))
+    {
+        int sep_index = sep_match - left_sep;
+        
+        ++(*qptr);
+        *lex_buf = *qptr;
+        while (**qptr && **qptr != right_sep[sep_index])
+        {
+            ++(*lex_len);
+            ++(*qptr);
+        }
+        if (**qptr)
+            ++(*qptr);
+    }
+    else
+    {
+        *lex_buf = *qptr;
+        while (**qptr && **qptr != ' ')
+        {
+            ++(*lex_len);
+            ++(*qptr);
+        }
+    }
+    if (*lex_len >= 1 && (*lex_buf)[0] == escape_char)
+    {
+        if (*lex_len == 4 && !memcmp (*lex_buf+1, "and", 3))
+            return 'a';
+        if (*lex_len == 3 && !memcmp (*lex_buf+1, "or", 2))
+            return 'o';
+        if (*lex_len == 4 && !memcmp (*lex_buf+1, "not", 3))
+            return 'n';
+        if (*lex_len == 5 && !memcmp (*lex_buf+1, "attr", 4))
+            return 'l';
+        if (*lex_len == 4 && !memcmp (*lex_buf+1, "set", 3))
+            return 's';
+    }
+    return 't';
+}
+
+static void lex (void)
+{
+    query_look = query_token (&query_buf, &query_lex_buf, &query_lex_len);
+}
+
+static Z_AttributesPlusTerm *rpn_term (ODR o, int num_attr, int *attr_list)
+{
+    Z_AttributesPlusTerm *zapt;
+    Odr_oct *term_octet;
+    Z_Term *term;
+
+    zapt = odr_malloc (o, sizeof(*zapt));
+    term_octet = odr_malloc (o, sizeof(*term_octet));
+    term = odr_malloc (o, sizeof(*term));
+
+    zapt->num_attributes = num_attr;
+    if (num_attr)
+    {
+        int i;
+        zapt->attributeList = odr_malloc (o, num_attr * 
+                                          sizeof(*zapt->attributeList));
+        for (i = 0; i < num_attr; i++)
+        {
+            zapt->attributeList[i] =
+                odr_malloc (o,sizeof(**zapt->attributeList));
+            zapt->attributeList[i]->attributeType = &attr_list[2*i];
+            zapt->attributeList[i]->attributeValue = &attr_list[2*i+1];
+        }
+    }
+    else
+        zapt->attributeList = ODR_NULLVAL;
+    zapt->term = term;
+    term->which = Z_Term_general;
+    term->u.general = term_octet;
+    term_octet->buf = odr_malloc (o, query_lex_len);
+    term_octet->size = term_octet->len = query_lex_len;
+    memcpy (term_octet->buf, query_lex_buf, query_lex_len);
+    return zapt;
+}
+
+static Z_Operand *rpn_simple (ODR o, int num_attr, int *attr_list)
+{
+    Z_Operand *zo;
+
+    zo = odr_malloc (o, sizeof(*zo));
+    switch (query_look)
+    {
+    case 't':
+        zo->which = Z_Operand_APT;
+        if (!(zo->u.attributesPlusTerm = rpn_term (o, num_attr, attr_list)))
+            return NULL;
+        lex ();
+        break;
+    case 's':
+        lex ();
+        if (!query_look)
+            return NULL;
+        zo->which = Z_Operand_resultSetId;
+        zo->u.resultSetId = odr_malloc (o, query_lex_len+1);
+        memcpy (zo->u.resultSetId, query_lex_buf, query_lex_len);
+        zo->u.resultSetId[query_lex_len] = '\0';
+        lex ();
+        break;
+    default:
+        return NULL;
+    }
+    return zo;
+}
+
+static Z_Complex *rpn_complex (ODR o, int num_attr, int max_attr, 
+                               int *attr_list)
+{
+    Z_Complex *zc;
+    Z_Operator *zo;
+
+    zc = odr_malloc (o, sizeof(*zc));
+    zo = odr_malloc (o, sizeof(*zo));
+    zc->operator = zo;
+    switch (query_look)
+    {
+    case 'a':
+        zo->which = Z_Operator_and;
+        zo->u.and = ODR_NULLVAL;
+        break;
+    case 'o':
+        zo->which = Z_Operator_or;
+        zo->u.and = ODR_NULLVAL;
+        break;
+    case 'n':
+        zo->which = Z_Operator_and_not;
+        zo->u.and = ODR_NULLVAL;
+        break;
+    default:
+        return NULL;
+    }
+    lex ();
+    if (!(zc->s1 = rpn_structure (o, num_attr, max_attr, attr_list)))
+        return NULL;
+    if (!(zc->s2 = rpn_structure (o, num_attr, max_attr, attr_list)))
+        return NULL;
+    return zc;
+}
+
+static Z_RPNStructure *rpn_structure (ODR o, int num_attr, int max_attr, 
+                                      int *attr_list)
+{
+    Z_RPNStructure *sz;
+    const char *cp;
+
+    sz = odr_malloc (o, sizeof(*sz));
+    switch (query_look)
+    {
+    case 'a':
+    case 'o':
+    case 'n':
+        sz->which = Z_RPNStructure_complex;
+        if (!(sz->u.complex = rpn_complex (o, num_attr, max_attr, attr_list)))
+            return NULL;
+        break;
+    case 't':
+    case 's':
+        sz->which = Z_RPNStructure_simple;
+        if (!(sz->u.simple = rpn_simple (o, num_attr, attr_list)))
+            return NULL;
+        break;
+    case 'l':
+        lex ();
+        if (!query_look)
+            return NULL;
+        if (!(cp = strchr (query_lex_buf, '=')))
+            return NULL;
+        if (num_attr >= max_attr)
+            return NULL;
+        attr_list[2*num_attr] = atoi (query_lex_buf);
+        attr_list[2*num_attr+1] = atoi (cp+1);
+        num_attr++;
+        lex ();
+        return rpn_structure (o, num_attr, max_attr, attr_list);
+    case 0:                /* operator/operand expected! */
+        return NULL;
+    }
+    return sz;
+}
+
+Z_RPNQuery *p_query_rpn (ODR o, const char *qbuf)
+{
+    Z_RPNQuery *zq;
+    int attr_array[1024];
+
+    query_buf = qbuf;
+    zq = odr_malloc (o, sizeof(*zq));
+    zq->attributeSetId = NULL;
+    lex ();
+    if (!(zq->RPNStructure = rpn_structure (o, 0, 512, attr_array)))
+        return NULL;
+    return zq;
+}
+