SOAP, SRW codecs and HTTP transport for YAZ using libxml2.
[yaz-moved-to-github.git] / zutil / yaz-ccl.c
1 /*
2  * Copyright (c) 1996-2003, Index Data.
3  * See the file LICENSE for details.
4  *
5  * $Id: yaz-ccl.c,v 1.19 2003-02-12 15:06:44 adam Exp $
6  */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <ctype.h>
12
13 #include <yaz/yaz-ccl.h>
14 #include <yaz/pquery.h>
15
16 Z_RPNQuery *ccl_rpn_query (ODR o, struct ccl_rpn_node *p)
17 {
18     YAZ_PQF_Parser parser = yaz_pqf_create();
19     WRBUF wr = wrbuf_alloc();
20     Z_RPNQuery *q;
21
22     ccl_pquery(wr, p);
23
24     q = yaz_pqf_parse(parser, o, wrbuf_buf(wr));
25
26     wrbuf_free(wr, 1);
27     yaz_pqf_destroy(parser);
28     return q;
29 }
30
31 Z_AttributesPlusTerm *ccl_scan_query (ODR o, struct ccl_rpn_node *p)
32 {
33     YAZ_PQF_Parser parser = yaz_pqf_create();
34     WRBUF wr = wrbuf_alloc();
35     Z_AttributesPlusTerm *q;
36     Odr_oid *setp;
37
38     ccl_pquery(wr, p);
39
40     q = yaz_pqf_scan(parser, o, &setp, wrbuf_buf(wr));
41
42     wrbuf_free(wr, 1);
43     yaz_pqf_destroy(parser);
44     return q;
45 }
46
47 static void ccl_pquery_complex (WRBUF w, struct ccl_rpn_node *p)
48 {
49     switch (p->kind)
50     {
51     case CCL_RPN_AND:
52         wrbuf_puts(w, "@and ");
53         break;
54     case CCL_RPN_OR:
55         wrbuf_puts(w, "@or ");
56         break;
57     case CCL_RPN_NOT:
58         wrbuf_puts(w, "@not ");
59         break;
60     case CCL_RPN_PROX:
61         if (p->u.p[2] && p->u.p[2]->kind == CCL_RPN_TERM)
62         {
63             const char *cp = p->u.p[2]->u.t.term;
64             /* exlusion distance ordered relation which-code unit-code */
65             if (*cp == '!')
66             {   
67                 /* word order specified */
68                 if (isdigit(cp[1]))
69                     wrbuf_printf(w, "@prox 0 %s 1 2 k 2 ", cp+1);
70                 else
71                     wrbuf_printf(w, "@prox 0 1 1 2 k 2 ");
72             } 
73             else if (*cp == '%')
74             {
75                 /* word order not specified */
76                 if (isdigit(cp[1]))
77                     wrbuf_printf(w, "@prox 0 %s 0 2 k 2 ", cp+1);
78                 else
79                     wrbuf_printf(w, "@prox 0 1 0 2 k 2 ");
80             }
81         }
82         else
83             wrbuf_puts(w, "@prox 0 2 0 1 k 2 ");
84         break;
85     default:
86         wrbuf_puts(w, "@ bad op (unknown) ");
87     };
88     ccl_pquery(w, p->u.p[0]);
89     ccl_pquery(w, p->u.p[1]);
90 }
91         
92 void ccl_pquery (WRBUF w, struct ccl_rpn_node *p)
93 {
94     struct ccl_rpn_attr *att;
95     const char *cp;
96
97     switch (p->kind)
98     {
99     case CCL_RPN_AND:
100     case CCL_RPN_OR:
101     case CCL_RPN_NOT:
102     case CCL_RPN_PROX:
103         ccl_pquery_complex (w, p);
104         break;
105     case CCL_RPN_SET:
106         wrbuf_puts (w, "@set ");
107         wrbuf_puts (w, p->u.setname);
108         wrbuf_puts (w, " ");
109         break;
110     case CCL_RPN_TERM:
111         for (att = p->u.t.attr_list; att; att = att->next)
112         {
113             char tmpattr[128];
114             wrbuf_puts (w, "@attr ");
115             if (att->set)
116             {
117                 wrbuf_puts (w, att->set);
118                 wrbuf_puts (w, " ");
119             }
120             sprintf(tmpattr, "%d=%d ", att->type, att->value);
121             wrbuf_puts (w, tmpattr);
122         }
123         for (cp = p->u.t.term; *cp; cp++)
124         {
125             if (*cp == ' ' || *cp == '\\')
126                 wrbuf_putc (w, '\\');
127             wrbuf_putc (w, *cp);
128         }
129         wrbuf_puts (w, " ");
130         break;
131     }
132 }