YAZ  5.34.0
cclptree.c
Go to the documentation of this file.
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) Index Data
3  * See the file LICENSE for details.
4  */
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 
23 static void ccl_pquery_indent(WRBUF w, struct ccl_rpn_node *p, int indent);
24 
25 static 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 
73 static void ccl_prterm(WRBUF w, const char *term)
74 {
75  yaz_encode_pqf_term(w, term, strlen(term));
76 }
77 
78 static 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  {
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 
135 void ccl_pquery(WRBUF w, struct ccl_rpn_node *p)
136 {
137  ccl_pquery_indent(w, p, -1);
138 }
139 
140 void 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 
Header with public definitions for CCL.
#define CCL_RPN_ATTR_STRING
Definition: ccl.h:108
#define CCL_RPN_ATTR_NUMERIC
Definition: ccl.h:107
@ CCL_RPN_AND
Definition: ccl.h:119
@ CCL_RPN_TERM
Definition: ccl.h:122
@ CCL_RPN_PROX
Definition: ccl.h:124
@ CCL_RPN_NOT
Definition: ccl.h:121
@ CCL_RPN_SET
Definition: ccl.h:123
@ CCL_RPN_OR
Definition: ccl.h:120
static void ccl_pquery_complex(WRBUF w, struct ccl_rpn_node *p, int indent)
Definition: cclptree.c:25
void ccl_pquery(WRBUF w, struct ccl_rpn_node *p)
Definition: cclptree.c:135
void ccl_pr_tree(struct ccl_rpn_node *rpn, FILE *fd_out)
Definition: cclptree.c:140
static void ccl_pquery_indent(WRBUF w, struct ccl_rpn_node *p, int indent)
Definition: cclptree.c:78
static void ccl_prterm(WRBUF w, const char *term)
Definition: cclptree.c:73
void yaz_encode_pqf_term(WRBUF b, const char *term, int len)
Definition: querytowrbuf.c:19
Query to WRBUF (to strings)
attribute node (type, value) pair as used in RPN
Definition: ccl.h:98
char * str
string attribute value
Definition: ccl.h:113
int kind
attribute value type (numeric or string)
Definition: ccl.h:106
int numeric
numeric attribute value
Definition: ccl.h:111
int type
attribute type, Bib-1: 1=use, 2=relation, 3=position, etc
Definition: ccl.h:104
union ccl_rpn_attr::@7 value
char * set
attribute set
Definition: ccl.h:102
struct ccl_rpn_attr * next
next attribute
Definition: ccl.h:100
RPN tree structure node.
Definition: ccl.h:128
struct ccl_rpn_node * p[3]
Boolean including proximity 0=left, 1=right, 2=prox parms.
Definition: ccl.h:133
char * setname
Definition: ccl.h:141
struct ccl_rpn_node::@8::@9 t
Attributes + Term.
enum ccl_rpn_kind kind
node type, one of CCL_RPN_AND, CCL_RPN_OR, etc
Definition: ccl.h:130
union ccl_rpn_node::@8 u
string buffer
Definition: wrbuf.h:43
void wrbuf_destroy(WRBUF b)
destroy WRBUF and its buffer
Definition: wrbuf.c:38
WRBUF wrbuf_alloc(void)
construct WRBUF
Definition: wrbuf.c:25
void wrbuf_printf(WRBUF b, const char *fmt,...)
writes printf result to WRBUF
Definition: wrbuf.c:178
const char * wrbuf_cstr(WRBUF b)
returns WRBUF content as C-string
Definition: wrbuf.c:281
void wrbuf_puts(WRBUF b, const char *buf)
appends C-string to WRBUF
Definition: wrbuf.c:89
#define wrbuf_putc(b, c)
Definition: wrbuf.h:268
Header for YAZ iconv interface.
#define yaz_isdigit(x)
Definition: yaz-iconv.h:86