xml_GList*
xml_path_pcre_to_list (xml_GNode* node, const gchar* xpath, xml_GList* list)
{
if (! node) return list;
if (! xpath) xpath = ".";
if (xpath[0] == '.') xpath++;
if (! xpath[0]) return xml_g_list_prepend (list, node);
___ int depth = 0;
while (xpath[0] == '/')
___ const gchar* end = advance_to_name_end (xpath);
if (end == xpath) return (*end ? list : xml_g_list_prepend (list, node));
___ pcre* regex = 0; const char* errmsg; int erridx; int ovector[33];
if (strchr("^(?+|\\", *xpath))
{
gchar* name = g_strndup (xpath, end-xpath);
if (*name == '+')
regex = pcre_compile (name+1, 0, &errmsg, &erridx, 0);
else if (*name == '?' || *name == '^')
regex = pcre_compile (name+1, PCRE_ANCHORED, &errmsg, &erridx, 0);
else
regex = pcre_compile (name, PCRE_ANCHORED, &errmsg, &erridx, 0);
g_free (name);
if (! regex) return list;
} |
___ int len = end-xpath;
if (end[0] == '@' && len == 1 && xpath[0] == '*')
{
const gchar* nxt = end; if ((nxt = attr(node, nxt)))
{ return xml_path_pcre_to_list (node, nxt, list); } |
} |
___ int serial = 0;
if (end[0] == '[' && g_ascii_isdigit (end[1]))
{
serial = strtol (&end[1], (gchar**) &end, 0);
if (! end[0] == ']') goto returns; else end++;
} |
if (0) {
if (serial)
g_printerr ("<%.*s[%i]>", len, xpath, serial);
else
g_printerr ("<%.*s>", len, xpath);
} |
node = node->children;
for (; node ; node = node->next)
{
if (! node->name) continue;
if (memcmp (node->name, xpath, len) || node->name[len])
goto match;
found:
if (--serial > 0) continue;
___ const gchar* nxt = end;
if (*nxt == '@') if (!(nxt = attr(node, nxt))) goto deeper;
list = xml_path_pcre_to_list (node, nxt, list); ____;
if (! serial) goto returns;
continue;
match:
if (*xpath == '*')
{
if (len == 1) goto found;
if (xml_g_strstr (node->name, xpath+1, len-1)) goto found;
} |
else if (regex)
{
if (0< pcre_exec_KEY (regex, 0, node->name, ovector, 33 ) &&
(*xpath == '+' || *xpath == '^' || ! node->name[ovector[1]]))
goto found;
} |
deeper:
if (depth > 1)
list = xml_path_pcre_to_list (node, xpath-depth, list);
} |
returns:
if (regex) pcre_free (regex);
return list;
____;____;____;____;____;
} |
|