From f5891a26d8d3ed87b059856650b2bdb0c7ea355e Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 28 Sep 2009 12:31:55 +0000 Subject: Implement the shortest stem first search order for pattern-specific variables and pattern rules. --- variable.c | 52 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 9 deletions(-) (limited to 'variable.c') diff --git a/variable.c b/variable.c index 90c447c..6a74dcd 100644 --- a/variable.c +++ b/variable.c @@ -35,28 +35,62 @@ this program. If not, see . */ static struct pattern_var *pattern_vars; -/* Pointer to last struct in the chain, so we can add onto the end. */ +/* Pointer to the last struct in the pack of a specific size, from 1 to 255.*/ -static struct pattern_var *last_pattern_var; +static struct pattern_var *last_pattern_vars[256]; -/* Create a new pattern-specific variable struct. */ +/* Create a new pattern-specific variable struct. The new variable is + inserted into the PATTERN_VARS list in the shortest patterns first + order to support the shortest stem matching (the variables are + matched in the reverse order so the ones with the longest pattern + will be considered first). Variables with the same pattern length + are inserted in the definition order. */ struct pattern_var * create_pattern_var (const char *target, const char *suffix) { + register unsigned int len = strlen (target); register struct pattern_var *p = xmalloc (sizeof (struct pattern_var)); - if (last_pattern_var != 0) - last_pattern_var->next = p; + if (pattern_vars != 0) + { + if (len < 256 && last_pattern_vars[len] != 0) + { + p->next = last_pattern_vars[len]->next; + last_pattern_vars[len]->next = p; + } + else + { + /* Find the position where we can insert this variable. */ + register struct pattern_var **v; + + for (v = &pattern_vars; ; v = &(*v)->next) + { + /* Insert at the end of the pack so that patterns with the + same length appear in the order they were defined .*/ + + if (*v == 0 || (*v)->len > len) + { + p->next = *v; + *v = p; + break; + } + } + } + } else - pattern_vars = p; - last_pattern_var = p; - p->next = 0; + { + pattern_vars = p; + p->next = 0; + } p->target = target; - p->len = strlen (target); + p->len = len; p->suffix = suffix + 1; + if (len < 256) + last_pattern_vars[len] = p; + return p; } -- cgit v1.2.3