IDZEBRA 2.2.8
xpath.c
Go to the documentation of this file.
1/* This file is part of the Zebra server.
2 Copyright (C) Index Data
3
4Zebra is free software; you can redistribute it and/or modify it under
5the terms of the GNU General Public License as published by the Free
6Software Foundation; either version 2, or (at your option) any later
7version.
8
9Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10WARRANTY; without even the implied warranty of MERCHANTABILITY or
11FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
18*/
19
20
21#if HAVE_CONFIG_H
22#include <config.h>
23#endif
24#include <stdio.h>
25#include <string.h>
26#include <assert.h>
27#include <ctype.h>
28#include <yaz/nmem.h>
29#include <zebra_xpath.h>
30
31static char *get_xp_part (char **strs, NMEM mem, int *literal)
32{
33 char *cp = *strs;
34 char *str = 0;
35 char *res = 0;
36
37 *literal = 0;
38 while (*cp == ' ')
39 cp++;
40 str = cp;
41 if (strchr("()", *cp))
42 cp++;
43 else if (strchr("><=", *cp))
44 {
45 while (strchr("><=", *cp))
46 cp++;
47 }
48 else if (*cp == '"' || *cp == '\'')
49 {
50 int sep = *cp;
51 str++;
52 cp++;
53 while (*cp && *cp != sep)
54 cp++;
55 res = nmem_malloc(mem, cp - str + 1);
56 if ((cp - str))
57 memcpy (res, str, (cp-str));
58 res[cp-str] = '\0';
59 if (*cp)
60 cp++;
61 *literal = 1;
62 }
63 else
64 {
65 while (*cp && !strchr("><=()]\" ", *cp))
66 cp++;
67 }
68 if (!res)
69 {
70 res = nmem_malloc(mem, cp - str + 1);
71 if ((cp - str))
72 memcpy (res, str, (cp-str));
73 res[cp-str] = '\0';
74 }
75 *strs = cp;
76 return res;
77}
78
79static struct xpath_predicate *get_xpath_boolean(char **pr, NMEM mem,
80 char **look, int *literal);
81
82static struct xpath_predicate *get_xpath_relation(char **pr, NMEM mem,
83 char **look, int *literal)
84{
85 struct xpath_predicate *res = 0;
86 if (!*literal && !strcmp(*look, "("))
87 {
88 *look = get_xp_part(pr, mem, literal);
89 res = get_xpath_boolean(pr, mem, look, literal);
90 if (!strcmp(*look, ")"))
91 *look = get_xp_part(pr, mem, literal);
92 else
93 res = 0; /* error */
94 }
95 else
96 {
97 res=nmem_malloc(mem, sizeof(struct xpath_predicate));
99 res->u.relation.name = *look;
100
101 *look = get_xp_part(pr, mem, literal);
102 if (*look && !*literal && strchr("><=", **look))
103 {
104 res->u.relation.op = *look;
105
106 *look = get_xp_part(pr, mem, literal);
107 if (!*look)
108 return 0; /* error */
109 res->u.relation.value = *look;
110 *look = get_xp_part(pr, mem, literal);
111 }
112 else
113 {
114 res->u.relation.op = "";
115 res->u.relation.value = "";
116 }
117 }
118 return res;
119}
120
121static struct xpath_predicate *get_xpath_boolean(char **pr, NMEM mem,
122 char **look, int *literal)
123{
124 struct xpath_predicate *left = 0;
125
126 left = get_xpath_relation(pr, mem, look, literal);
127 if (!left)
128 return 0;
129
130 while (*look && !*literal &&
131 (!strcmp(*look, "and") || !strcmp(*look, "or") ||
132 !strcmp(*look, "not")))
133 {
134 struct xpath_predicate *res, *right;
135
136 res = nmem_malloc(mem, sizeof(struct xpath_predicate));
138 res->u.boolean.op = *look;
139 res->u.boolean.left = left;
140
141 *look = get_xp_part(pr, mem, literal); /* skip the boolean name */
142 right = get_xpath_relation(pr, mem, look, literal);
143
144 res->u.boolean.right = right;
145
146 left = res;
147 }
148 return left;
149}
150
151static struct xpath_predicate *get_xpath_predicate(char *predicate, NMEM mem)
152{
153 int literal;
154 char **pr = &predicate;
155 char *look = get_xp_part(pr, mem, &literal);
156
157 if (!look)
158 return 0;
159 return get_xpath_boolean(pr, mem, &look, &literal);
160}
161
162int zebra_parse_xpath_str(const char *xpath_string,
163 struct xpath_location_step *xpath, int max, NMEM mem)
164{
165 const char *cp;
166 char *a;
167
168 int no = 0;
169
170 if (!xpath_string || *xpath_string != '/')
171 return -1;
172 cp = xpath_string;
173
174 while (*cp && no < max)
175 {
176 int i = 0;
177 while (*cp && !strchr("/[",*cp))
178 {
179 i++;
180 cp++;
181 }
182 xpath[no].predicate = 0;
183 xpath[no].part = nmem_malloc (mem, i+1);
184 if (i)
185 memcpy (xpath[no].part, cp - i, i);
186 xpath[no].part[i] = 0;
187
188 if (*cp == '[')
189 {
190 cp++;
191 while (*cp == ' ')
192 cp++;
193
194 a = (char *)cp;
195 xpath[no].predicate = get_xpath_predicate(a, mem);
196 while(*cp && *cp != ']') {
197 cp++;
198 }
199 if (*cp == ']')
200 cp++;
201 } /* end of ] predicate */
202 no++;
203 if (*cp != '/')
204 break;
205 cp++;
206 }
207
208/* for debugging .. */
209#if 0
210 dump_xp_steps(xpath, no);
211#endif
212
213 return no;
214}
215
217{
218 if (p) {
220 p->u.relation.name[0]) {
221 fprintf (stderr, "%s,%s,%s",
222 p->u.relation.name,
223 p->u.relation.op,
224 p->u.relation.value);
225 } else {
226 fprintf (stderr, "(");
228 fprintf (stderr, ") %s (", p->u.boolean.op);
230 fprintf (stderr, ")");
231 }
232 }
233}
234
235void dump_xp_steps (struct xpath_location_step *xpath, int no)
236{
237 int i;
238 for (i=0; i<no; i++) {
239 fprintf (stderr, "Step %d: %s ",i,xpath[i].part);
240 dump_xp_predicate(xpath[i].predicate);
241 fprintf (stderr, "\n");
242 }
243}
244
245/*
246 * Local variables:
247 * c-basic-offset: 4
248 * c-file-style: "Stroustrup"
249 * indent-tabs-mode: nil
250 * End:
251 * vim: shiftwidth=4 tabstop=8 expandtab
252 */
253
struct xpath_predicate * predicate
Definition zebra_xpath.h:46
struct xpath_predicate * right
Definition zebra_xpath.h:39
union xpath_predicate::@8 u
struct xpath_predicate::@8::@9 relation
struct xpath_predicate::@8::@10 boolean
struct xpath_predicate * left
Definition zebra_xpath.h:38
void dump_xp_predicate(struct xpath_predicate *p)
Definition xpath.c:216
static struct xpath_predicate * get_xpath_relation(char **pr, NMEM mem, char **look, int *literal)
Definition xpath.c:82
void dump_xp_steps(struct xpath_location_step *xpath, int no)
Definition xpath.c:235
static char * get_xp_part(char **strs, NMEM mem, int *literal)
Definition xpath.c:31
int zebra_parse_xpath_str(const char *xpath_string, struct xpath_location_step *xpath, int max, NMEM mem)
Definition xpath.c:162
static struct xpath_predicate * get_xpath_predicate(char *predicate, NMEM mem)
Definition xpath.c:151
static struct xpath_predicate * get_xpath_boolean(char **pr, NMEM mem, char **look, int *literal)
Definition xpath.c:121
#define XPATH_PREDICATE_BOOLEAN
Definition zebra_xpath.h:35
#define XPATH_PREDICATE_RELATION
Definition zebra_xpath.h:29