From b0da03b33f14aa9c8edac191512f89dfa8fdef6f Mon Sep 17 00:00:00 2001 From: Dave Beazley Date: Mon, 10 Apr 2000 15:25:07 +0000 Subject: [PATCH] Rewrote. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@399 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- SWIG/Source/Swig/tree.c | 224 +++++++++++----------------------------- 1 file changed, 61 insertions(+), 163 deletions(-) diff --git a/SWIG/Source/Swig/tree.c b/SWIG/Source/Swig/tree.c index 04b03bae5..52992b976 100644 --- a/SWIG/Source/Swig/tree.c +++ b/SWIG/Source/Swig/tree.c @@ -1,9 +1,8 @@ /* ----------------------------------------------------------------------------- * tree.c * - * This file provides some general purpose functions for manipulating - * parse trees. Note: This is primarily a debugging module at this - * point. Maybe it will evolve into something else later. + * This file provides some general purpose functions for walking through + * parse trees. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * @@ -15,6 +14,8 @@ static char cvsroot[] = "$Header$"; +static DOHHash *rules = 0; + /* ----------------------------------------------------------------------------- * Swig_dump_tags() * @@ -46,178 +47,75 @@ Swig_dump_tags(DOH *obj, DOH *root) { /* ----------------------------------------------------------------------------- * Swig_add_rule() * - * Adds a new rule to a ruleset. Rules are specified using a subset of CSS2 - * (Cascading Style Sheet) syntax. For example: - * - * "function" - Applies to a function - * "class function" - Applies to any function inside a class - * "class > function" - Applies to an immediate child. - * "foo * bar" - Wildcard. Matches zero or more tags in between. - * - * Note: "foo * bar" is the same as "foo bar". + * Adds a new rule to the tree walking code. * ----------------------------------------------------------------------------- */ -void -Swig_add_rule(DOH *ruleset, DOH *ruleobj, DOH *action) { - DOH *rule, *rulelist, *nextruleset, *r, *robj; - int c, i, ntags = 0, lastid = 0, isid = 0; - rule = NewString(ruleobj); - /* Split the rule into a list */ - rulelist = NewList(); - Seek(rule,0,SEEK_SET); - r = NewString(""); - while ((c = Getc(rule)) != EOF) { - if (c == ' ') { - if (lastid && isid) { - Insert(rulelist,0,"*"); - ntags++; - } - ntags++; - Insert(rulelist,0,r); - r = NewString(""); - lastid = isid; - isid = 0; - } else if (isalnum(c)) { - isid = 1; - Putc(c,r); - } else { - Putc(c,r); - } - } - if (lastid && isid) { - Insert(rulelist,0,"*"); - ntags++; - } - ntags++; - Insert(rulelist,0,r); - - nextruleset = ruleset; - /* Now, try to insert the rule into the table */ - for (i = 0; i < ntags; i++) { - ruleset = nextruleset; - r = Getitem(rulelist,i); - if (Cmp(r,">")) { - robj = Getattr(ruleset,r); /* Get a rule entry (if any) */ - if (robj) { - /* If the rule already exists, extract the next ruleset in case we need it */ - nextruleset = Getattr(robj,"ruleset"); - } else { - /* No rule exists. Create an entry and store it in the ruleset */ - robj = NewHash(); - nextruleset = NewHash(); - Setattr(robj,"ruleset",nextruleset); - Setattr(ruleset, r, robj); - } - } - } - - /* For the last rule, insert the action into robj */ - Setattr(robj,"action",action); - - /* Printf(stdout,"%s\n", rulelist); */ - Delete(rule); - Delete(rulelist); -} - -/* ----------------------------------------------------------------------------- - * Swig_match_rule() - * - * Given a ruleset and a list of nodes, this function tries to find the longest - * matching rule. - * ----------------------------------------------------------------------------- */ - -DOH * -Swig_match_rule(DOH *ruleset, DOH *nodelist) +void +Swig_add_rule(DOHString_or_char *name, int (*action)(DOH *node, void *clientdata)) { - DOH *tag, *action = 0, *robj = 0, *wobj = 0, *bestobj = 0, *candidates; - int i, ntags, bestlen = 0, wildcard = 0; - ntags = Len(nodelist); - if (ntags <= 0) return 0; - - i = ntags - 1; - - while (i >= 0) { - tag = Getattr(Getitem(nodelist,i),"tag"); - - /* See if there is any matching tag at all */ - robj = Getattr(ruleset,tag); - if (robj) { - wobj = 0; - wildcard = 0; - } else if (!robj && wildcard) { - robj = wobj; - wildcard++; - } else if (!robj) { - robj = Getattr(ruleset,"*"); - if (robj) { - wildcard = 1; - wobj = robj; - } - } - if (!robj) - return bestobj; - - /* Got at least one match. Search for others */ - action = Getattr(robj,"action"); - if (action) { - bestobj = action; - } - if (wildcard != 1) - i--; - ruleset = Getattr(robj,"ruleset"); - } - return bestobj; + if (!rules) rules = NewHash(); + if (action) + Setattr(rules,name,NewVoid((void *) action,0)); + else + Delattr(rules,name); } /* ----------------------------------------------------------------------------- - * Swig_emit_rules() + * Swig_add_rules() * - * Given a node, this function fires all of the rules for its siblings by - * invoking a user-supplied callback function. The ruleset is a set of - * handling rules as created by Swig_add_rule. context is a list containing - * the context of node (all enclosing parent nodes). - * - * Note: child nodes are not processed (as a handler function might want to - * take special action or ignore the children). + * Add a complete set of rules to the rule system * ----------------------------------------------------------------------------- */ -void -Swig_emit_rules(DOH *ruleset, DOH *context, DOH *node, - int (*actionhandler)(DOH *ruleset, DOH *context, DOH *node, DOH *action)) { - - DOH *act; - DOH *next; - - while (node) { - Append(context,node); - act = Swig_match_rule(ruleset,context); - if (act) { - (*actionhandler)(ruleset,context,node,act); - } - Delitem(context, DOH_END); - node = Getattr(node,"sibling"); +void +Swig_add_rules(SwigRule ruleset[]) { + int i = 0; + while (ruleset[i].name) { + Swig_add_rule(ruleset[i].name, ruleset[i].action); + i++; } } -#ifdef TEST - -int main() { - DOH *a; - DOH *tags; - DOH *action = NewString("*action*"); - DOH *ruleset = NewHash(); - Swig_add_rule(ruleset,"function","*function*"); - Swig_add_rule(ruleset,"class *","*memberfunction*"); - Swig_add_rule(ruleset,"foo","*foo*"); - tags = NewList(); - Append(tags,"includefile"); - Append(tags,"class"); - Append(tags,"function"); - Append(tags,"foo"); - a = Swig_match_rule(ruleset, tags); - if (a) - Printf(stdout,"%s\n", a); +/* ----------------------------------------------------------------------------- + * Swig_clear_rules() + * + * Clears all of the existing rules + * ----------------------------------------------------------------------------- */ +void +Swig_clear_rules() +{ + if (rules) Delete(rules); + rules = NewHash(); } -#endif +/* ----------------------------------------------------------------------------- + * int Swig_emit() + * + * Emit an action for a specific object + * ----------------------------------------------------------------------------- */ + +int +Swig_emit(DOH *obj, void *clientdata) { + DOH *tag; + DOH *actionobj; + int (*action)(DOH *obj, void *clientdata); + + int ret; + + assert(obj); + + if (!rules) return -1; + while (obj) { + tag = Getattr(obj,"tag"); + actionobj = Getattr(rules,tag); + if (!actionobj) return -1; + action = (int (*)(DOH *, void *)) Data(actionobj); + ret = (*action)(obj,clientdata); + if (ret < 0) return -1; + obj = Getattr(obj,"sibling"); + } + return 0; +} + + +