1 /* This file is part of the Zebra server.
2 Copyright (C) 1994-2010 Index Data
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
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
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
26 #include <zebra_xpath.h>
28 static char *get_xp_part (char **strs, NMEM mem, int *literal)
38 if (strchr("()", *cp))
40 else if (strchr("><=", *cp))
42 while (strchr("><=", *cp))
45 else if (*cp == '"' || *cp == '\'')
50 while (*cp && *cp != sep)
52 res = nmem_malloc(mem, cp - str + 1);
54 memcpy (res, str, (cp-str));
62 while (*cp && !strchr("><=()]\" ", *cp))
67 res = nmem_malloc(mem, cp - str + 1);
69 memcpy (res, str, (cp-str));
76 static struct xpath_predicate *get_xpath_boolean(char **pr, NMEM mem,
77 char **look, int *literal);
79 static struct xpath_predicate *get_xpath_relation(char **pr, NMEM mem,
80 char **look, int *literal)
82 struct xpath_predicate *res = 0;
83 if (!*literal && !strcmp(*look, "("))
85 *look = get_xp_part(pr, mem, literal);
86 res = get_xpath_boolean(pr, mem, look, literal);
87 if (!strcmp(*look, ")"))
88 *look = get_xp_part(pr, mem, literal);
94 res=nmem_malloc(mem, sizeof(struct xpath_predicate));
95 res->which = XPATH_PREDICATE_RELATION;
96 res->u.relation.name = *look;
98 *look = get_xp_part(pr, mem, literal);
99 if (*look && !*literal && strchr("><=", **look))
101 res->u.relation.op = *look;
103 *look = get_xp_part(pr, mem, literal);
105 return 0; /* error */
106 res->u.relation.value = *look;
107 *look = get_xp_part(pr, mem, literal);
111 res->u.relation.op = "";
112 res->u.relation.value = "";
118 static struct xpath_predicate *get_xpath_boolean(char **pr, NMEM mem,
119 char **look, int *literal)
121 struct xpath_predicate *left = 0;
123 left = get_xpath_relation(pr, mem, look, literal);
127 while (*look && !*literal &&
128 (!strcmp(*look, "and") || !strcmp(*look, "or") ||
129 !strcmp(*look, "not")))
131 struct xpath_predicate *res, *right;
133 res = nmem_malloc(mem, sizeof(struct xpath_predicate));
134 res->which = XPATH_PREDICATE_BOOLEAN;
135 res->u.boolean.op = *look;
136 res->u.boolean.left = left;
138 *look = get_xp_part(pr, mem, literal); /* skip the boolean name */
139 right = get_xpath_relation(pr, mem, look, literal);
141 res->u.boolean.right = right;
148 static struct xpath_predicate *get_xpath_predicate(char *predicate, NMEM mem)
151 char **pr = &predicate;
152 char *look = get_xp_part(pr, mem, &literal);
156 return get_xpath_boolean(pr, mem, &look, &literal);
159 int zebra_parse_xpath_str(const char *xpath_string,
160 struct xpath_location_step *xpath, int max, NMEM mem)
167 if (!xpath_string || *xpath_string != '/')
171 while (*cp && no < max)
174 while (*cp && !strchr("/[",*cp))
179 xpath[no].predicate = 0;
180 xpath[no].part = nmem_malloc (mem, i+1);
182 memcpy (xpath[no].part, cp - i, i);
183 xpath[no].part[i] = 0;
192 xpath[no].predicate = get_xpath_predicate(a, mem);
193 while(*cp && *cp != ']') {
198 } /* end of ] predicate */
205 /* for debugging .. */
207 dump_xp_steps(xpath, no);
213 void dump_xp_predicate (struct xpath_predicate *p)
216 if (p->which == XPATH_PREDICATE_RELATION &&
217 p->u.relation.name[0]) {
218 fprintf (stderr, "%s,%s,%s",
221 p->u.relation.value);
223 fprintf (stderr, "(");
224 dump_xp_predicate(p->u.boolean.left);
225 fprintf (stderr, ") %s (", p->u.boolean.op);
226 dump_xp_predicate(p->u.boolean.right);
227 fprintf (stderr, ")");
232 void dump_xp_steps (struct xpath_location_step *xpath, int no)
235 for (i=0; i<no; i++) {
236 fprintf (stderr, "Step %d: %s ",i,xpath[i].part);
237 dump_xp_predicate(xpath[i].predicate);
238 fprintf (stderr, "\n");
245 * c-file-style: "Stroustrup"
246 * indent-tabs-mode: nil
248 * vim: shiftwidth=4 tabstop=8 expandtab