IDZEBRA  2.2.7
xpath.c
Go to the documentation of this file.
1 /* This file is part of the Zebra server.
2  Copyright (C) Index Data
3 
4 Zebra is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
7 version.
8 
9 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 for more details.
13 
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, 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 
31 static 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 
79 static struct xpath_predicate *get_xpath_boolean(char **pr, NMEM mem,
80  char **look, int *literal);
81 
82 static 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 
121 static 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 
151 static 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 
162 int 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) {
219  if (p->which == XPATH_PREDICATE_RELATION &&
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, "(");
227  dump_xp_predicate(p->u.boolean.left);
228  fprintf (stderr, ") %s (", p->u.boolean.op);
229  dump_xp_predicate(p->u.boolean.right);
230  fprintf (stderr, ")");
231  }
232  }
233 }
234 
235 void 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
static struct xpath_predicate * get_xpath_predicate(char *predicate, NMEM mem)
Definition: xpath.c:151
void dump_xp_predicate(struct xpath_predicate *p)
Definition: xpath.c:216
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_relation(char **pr, NMEM mem, char **look, int *literal)
Definition: xpath.c:82
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