#define USE_XML_ATTR_DATA
#include <xml/greptree.h>
#include <xml/attrnode.h>
#include <xml/attrdata.h>
#include <string.h>
#include <pcre.h>

#define ___ {
#define ____ }

/*
   like => xml_node_find but name is a pcre being an anchored-match
   by default unless the first char is a '*'.
 */
xml_GNode* xml_node_grep (xml_GNode* root, 
			    GTraverseType order,
			    GTraverseFlags flags,
			    const gchar* name)
{
    g_return_val_if_fail (root, 0);
    if (! name) return 0;
    
    g_error ("not implemented");
    return 0;
}
/*
   like => xml_node_find_child but name may be an pcre.
 */
xml_GNode* xml_node_grep_child       (xml_GNode       *node,
				      GTraverseFlags   flags,
				      const gchar*     name)
{
    g_return_val_if_fail (node, 0);
    g_return_val_if_fail (flags <= G_TRAVERSE_MASK, NULL);
    if (! name || ! *name || !node->children) return 0;

    if (! strchr ("^(?+|\\*", *name))
	return xml_node_find_child (node, flags, name);

    ___ pcre* regex; const char* errmsg; int erridx; int ovector[33];
    if (*name == '*' || *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);

    if (! regex) return 0;
  
    node = node->children;
    while (node)
    
{
	if (0< pcre_exec (regex, 0, node->name, strlen(node->name), 
			  0, PCRE_NOTEMPTY, ovector, 33 ))
        
{
	    if (*name == '*' || *name == '+' || ! node->name[ovector[1]])
	    
{
		if (G_NODE_IS_LEAF (node))
		
{
		    if (flags & G_TRAVERSE_LEAFS)
			goto returns;
		}
else
{
		    if (flags & G_TRAVERSE_NON_LEAFS)
			goto returns;
		}
}
}
node = node->next; }
/* break: assert (node == NULL) */ returns: pcre_free (regex); return node; ____; }
/*
   like => xml_node_attribute_lookup but name is a pcre being an 
   anchored-match by default unless the first char is a '*'.
 */
gchar*   xml_node_grep_attribute (xml_GNode* node, const gchar* key)
{
    g_return_val_if_fail (node, 0);
    if (! key) return 0;

    if (! strchr ("^(?+|\\*", *key))
	return xml_node_attribute_lookup (node, key);

    ___ pcre* regex; const char* errmsg; int erridx; int ovector[33];
    if (*key == '*' || *key == '+') 
	regex = pcre_compile (key+1, 0, &errmsg, &erridx, 0);
    else if (*key == '?' || *key == '^') 
	regex = pcre_compile (key+1, PCRE_ANCHORED, &errmsg, &erridx, 0);
    else
	regex = pcre_compile (key, PCRE_ANCHORED, &errmsg, &erridx, 0);

    if (! regex) return 0; 

    ___ xml_AttrList* list = node->attributes;
    for (; list ; list = list->next)
    
{
	gchar* name = list->data->name;
	if (0< pcre_exec (regex, 0, name, strlen(name), 
			  0, PCRE_NOTEMPTY, ovector, 33 ))
	
{
	    if (*key == '*' || *key == '+' || ! name[ovector[1]])
		break;
	}
}
pcre_free (regex); return (! list ? (gchar*) list : list->data->value); ____;____; }
/* 
   Local variables:
   c-file-style: "stroustrup"
   End:
 */