source: yaz/trunk/fuentes/src/cclptree.c @ 255

Last change on this file since 255 was 255, checked in by mabarracus, 4 years ago

added trusty code to xenial

File size: 3.9 KB
Line 
1/* This file is part of the YAZ toolkit.
2 * Copyright (C) Index Data
3 * See the file LICENSE for details.
4 */
5/**
6 * \file cclptree.c
7 * \brief Implements CCL parse tree printing
8 *
9 * This source file implements functions to parse and print
10 * a CCL node tree (as a result of parsing).
11 */
12#if HAVE_CONFIG_H
13#include <config.h>
14#endif
15
16#include <stdio.h>
17#include <string.h>
18
19#include <yaz/querytowrbuf.h>
20#include <yaz/yaz-iconv.h>
21#include <yaz/ccl.h>
22
23static void ccl_pquery_indent(WRBUF w, struct ccl_rpn_node *p, int indent);
24
25static void ccl_pquery_complex(WRBUF w, struct ccl_rpn_node *p, int indent)
26{
27    int sep_char = indent == -1 ? ' ' : '\n';
28    int next_indent = indent == -1 ? indent : indent+1;
29    switch (p->kind)
30    {
31    case CCL_RPN_AND:
32        wrbuf_puts(w, "@and");
33        break;
34    case CCL_RPN_OR:
35        wrbuf_puts(w, "@or");
36        break;
37    case CCL_RPN_NOT:
38        wrbuf_puts(w, "@not");
39        break;
40    case CCL_RPN_PROX:
41        if (p->u.p[2] && p->u.p[2]->kind == CCL_RPN_TERM)
42        {
43            const char *cp = p->u.p[2]->u.t.term;
44            /* exlusion distance ordered relation which-code unit-code */
45            if (*cp == '!')
46            {
47                /* word order specified */
48                if (yaz_isdigit(cp[1]))
49                    wrbuf_printf(w, "@prox 0 %s 1 2 k 2", cp+1);
50                else
51                    wrbuf_printf(w, "@prox 0 1 1 2 k 2");
52            }
53            else if (*cp == '%')
54            {
55                /* word order not specified */
56                if (yaz_isdigit(cp[1]))
57                    wrbuf_printf(w, "@prox 0 %s 0 2 k 2", cp+1);
58                else
59                    wrbuf_printf(w, "@prox 0 1 0 2 k 2");
60            }
61        }
62        else
63            wrbuf_puts(w, "@prox 0 2 0 1 k 2");
64        break;
65    default:
66        wrbuf_puts(w, "@ bad op (unknown)");
67    }
68    wrbuf_putc(w, sep_char);
69    ccl_pquery_indent(w, p->u.p[0], next_indent);
70    ccl_pquery_indent(w, p->u.p[1], next_indent);
71}
72
73static void ccl_prterm(WRBUF w, const char *term)
74{
75    yaz_encode_pqf_term(w, term, strlen(term));
76}
77
78static void ccl_pquery_indent(WRBUF w, struct ccl_rpn_node *p, int indent)
79{
80    struct ccl_rpn_attr *att;
81
82    if (!p)
83        return;
84    if (indent != -1)
85    {
86        int i;
87        for (i = 0; i < indent; i++)
88            wrbuf_putc(w, ' ');
89    }
90    switch (p->kind)
91    {
92    case CCL_RPN_AND:
93    case CCL_RPN_OR:
94    case CCL_RPN_NOT:
95    case CCL_RPN_PROX:
96        ccl_pquery_complex(w, p, indent);
97        break;
98    case CCL_RPN_SET:
99        wrbuf_puts(w, "@set ");
100        ccl_prterm(w, p->u.setname);
101        if (indent != -1)
102            wrbuf_putc(w, '\n');
103        break;
104    case CCL_RPN_TERM:
105        for (att = p->u.t.attr_list; att; att = att->next)
106        {
107            char tmpattr[128];
108            wrbuf_puts(w, "@attr ");
109            if (att->set)
110            {
111                wrbuf_puts(w, att->set);
112                wrbuf_puts(w, " ");
113            }
114            switch(att->kind)
115            {
116            case CCL_RPN_ATTR_NUMERIC:
117                sprintf(tmpattr, "%d=%d ", att->type, att->value.numeric);
118                wrbuf_puts(w, tmpattr);
119                break;
120            case CCL_RPN_ATTR_STRING:
121                sprintf(tmpattr, "%d=", att->type);
122                wrbuf_puts(w, tmpattr);
123                wrbuf_puts(w, att->value.str);
124                wrbuf_puts(w, " ");
125                break;
126            }
127        }
128        ccl_prterm(w, p->u.t.term);
129        if (indent != -1)
130            wrbuf_putc(w, '\n');
131        break;
132    }
133}
134
135void ccl_pquery(WRBUF w, struct ccl_rpn_node *p)
136{
137    ccl_pquery_indent(w, p, -1);
138}
139
140void ccl_pr_tree(struct ccl_rpn_node *rpn, FILE *fd_out)
141{
142    WRBUF w = wrbuf_alloc();
143
144    ccl_pquery_indent(w, rpn, 0);
145
146    fputs(wrbuf_cstr(w), fd_out);
147    wrbuf_destroy(w);
148}
149
150/*
151 * Local variables:
152 * c-basic-offset: 4
153 * c-file-style: "Stroustrup"
154 * indent-tabs-mode: nil
155 * End:
156 * vim: shiftwidth=4 tabstop=8 expandtab
157 */
158
Note: See TracBrowser for help on using the repository browser.