diff --git a/qse/include/qse/cmn/lda.h b/qse/include/qse/cmn/lda.h index 6a635acd..3f9bb88c 100644 --- a/qse/include/qse/cmn/lda.h +++ b/qse/include/qse/cmn/lda.h @@ -1,5 +1,5 @@ /* - * $Id: lda.h 323 2010-04-05 12:50:01Z hyunghwan.chung $ + * $Id: lda.h 327 2010-05-10 13:15:55Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -344,16 +344,30 @@ void qse_lda_clear ( qse_lda_t* lda ); -void qse_lda_walk ( +/** + * The qse_lda_walk() function calls the @a walker function for each + * element in the array beginning from the first. The @a walker function + * should return one of #QSE_LDA_WALK_FORWARD, #QSE_LDA_WALK_BACKWARD, + * #QSE_LDA_WALK_STOP. + * @return number of calls to the @a walker fucntion made + */ +qse_size_t qse_lda_walk ( qse_lda_t* lda, qse_lda_walker_t walker, - void* arg + void* ctx ); -void qse_lda_rwalk ( +/** + * The qse_lda_rwalk() function calls the @a walker function for each + * element in the array beginning from the last. The @a walker function + * should return one of #QSE_LDA_WALK_FORWARD, #QSE_LDA_WALK_BACKWARD, + * #QSE_LDA_WALK_STOP. + * @return number of calls to the @a walker fucntion made + */ +qse_size_t qse_lda_rwalk ( qse_lda_t* lda, qse_lda_walker_t walker, - void* arg + void* ctx ); /** diff --git a/qse/include/qse/cmn/map.h b/qse/include/qse/cmn/map.h index 91eba0f3..cd8e1acc 100644 --- a/qse/include/qse/cmn/map.h +++ b/qse/include/qse/cmn/map.h @@ -1,5 +1,5 @@ /* - * $Id: map.h 287 2009-09-15 10:01:02Z hyunghwan.chung $ + * $Id: map.h 327 2010-05-10 13:15:55Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -323,43 +323,32 @@ void qse_map_setscale ( ); /******/ -/****f* Common/qse_map_getcopier - * NAME - * qse_map_getcopier - get a data copier - * PARAMETERS - * * id - QSE_MAP_KEY or QSE_MAP_VAL - * SYNOPSIS +/** + * The qse_map_getcopier() function gets a data copier. */ qse_map_copier_t qse_map_getcopier ( qse_map_t* map, - qse_map_id_t id + qse_map_id_t id /**< QSE_MAP_KEY or QSE_MAP_VAL */ ); -/*****/ -/****f* Common/qse_map_setcopier - * NAME - * qse_map_setcopier - specify how to clone an element - * - * DESCRIPTION +/** + * The qse_map_setcopier() function specifies how to clone an element. * A special copier QSE_MAP_COPIER_INLINE is provided. This copier enables * you to copy the data inline to the internal node. No freeer is invoked * when the node is freeed. * * You may set the copier to QSE_NULL to perform no special operation * when the data pointer is rememebered. - * - * SYNOPSIS */ void qse_map_setcopier ( - qse_map_t* map /* a map */, - qse_map_id_t id /* QSE_MAP_KEY or QSE_MAP_VAL */, - qse_map_copier_t copier /* an element copier */ + qse_map_t* map, /**< a map */ + qse_map_id_t id, /**< QSE_MAP_KEY or QSE_MAP_VAL */ + qse_map_copier_t copier /**< element copier */ ); -/******/ qse_map_freeer_t qse_map_getfreeer ( - qse_map_t* map /* a map */, - qse_map_id_t id /* QSE_MAP_KEY or QSE_MAP_VAL */ + qse_map_t* map, /**< map */ + qse_map_id_t id /**< QSE_MAP_KEY or QSE_MAP_VAL */ ); /** @@ -494,10 +483,10 @@ void qse_map_clear ( ); /* traverse a map */ -void qse_map_walk ( +qse_size_t qse_map_walk ( qse_map_t* map /* a map */, qse_map_walker_t walker /* the pointer to the function for each pair */, - void* arg /* a pointer to user-specific data */ + void* ctx /* a pointer to user-specific data */ ); /* get the pointer to the first pair in the map. */ diff --git a/qse/lib/cmn/lda.c b/qse/lib/cmn/lda.c index 28c64e7e..c8192224 100644 --- a/qse/lib/cmn/lda.c +++ b/qse/lib/cmn/lda.c @@ -1,5 +1,5 @@ /* - * $Id: lda.c 323 2010-04-05 12:50:01Z hyunghwan.chung $ + * $Id: lda.c 327 2010-05-10 13:15:55Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -514,59 +514,69 @@ void qse_lda_clear (lda_t* lda) lda->size = 0; } -void qse_lda_walk (lda_t* lda, walker_t walker, void* arg) +size_t qse_lda_walk (lda_t* lda, walker_t walker, void* ctx) { qse_lda_walk_t w = QSE_LDA_WALK_FORWARD; - size_t i = 0; + size_t i = 0, nwalks = 0; - if (lda->size <= 0) return; + if (lda->size <= 0) return 0; while (1) { if (lda->node[i] != QSE_NULL) - w = walker (lda, i, arg); + { + w = walker (lda, i, ctx); + nwalks++; + } - if (w == QSE_LDA_WALK_STOP) return; + if (w == QSE_LDA_WALK_STOP) break; if (w == QSE_LDA_WALK_FORWARD) { i++; - if (i >= lda->size) return; + if (i >= lda->size) break; } if (w == QSE_LDA_WALK_BACKWARD) { - if (i <= 0) return; + if (i <= 0) break; i--; } } + + return nwalks; } -void qse_lda_rwalk (lda_t* lda, walker_t walker, void* arg) +size_t qse_lda_rwalk (lda_t* lda, walker_t walker, void* ctx) { qse_lda_walk_t w = QSE_LDA_WALK_BACKWARD; - size_t i; + size_t i, nwalks = 0; - if (lda->size <= 0) return; + if (lda->size <= 0) return 0; i = lda->size - 1; while (1) { if (lda->node[i] != QSE_NULL) - w = walker (lda, i, arg); + { + w = walker (lda, i, ctx); + nwalks++; + } - if (w == QSE_LDA_WALK_STOP) return; + if (w == QSE_LDA_WALK_STOP) break; if (w == QSE_LDA_WALK_FORWARD) { i++; - if (i >= lda->size) return; + if (i >= lda->size) break; } if (w == QSE_LDA_WALK_BACKWARD) { - if (i <= 0) return; + if (i <= 0) break; i--; } } + + return nwalks; } size_t qse_lda_pushstack (lda_t* lda, void* dptr, size_t dlen) diff --git a/qse/lib/cmn/map.c b/qse/lib/cmn/map.c index 7473b13a..fc113bc1 100644 --- a/qse/lib/cmn/map.c +++ b/qse/lib/cmn/map.c @@ -1,5 +1,5 @@ /* - * $Id: map.c 289 2009-09-16 06:35:29Z hyunghwan.chung $ + * $Id: map.c 327 2010-05-10 13:15:55Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -572,9 +572,9 @@ void qse_map_clear (map_t* map) } -void qse_map_walk (map_t* map, walker_t walker, void* arg) +size_t qse_map_walk (map_t* map, walker_t walker, void* arg) { - size_t i; + size_t i, nwalks = 0; pair_t* pair, * next; for (i = 0; i < map->capa; i++) @@ -584,10 +584,14 @@ void qse_map_walk (map_t* map, walker_t walker, void* arg) while (pair != QSE_NULL) { next = NEXT(pair); - if (walker(map, pair, arg) == QSE_MAP_WALK_STOP) return; + if (walker(map, pair, arg) == QSE_MAP_WALK_STOP) + return nwalks; + nwalks++; pair = next; } } + + return nwalks; } pair_t* qse_map_getfirstpair (map_t* map, size_t* buckno) diff --git a/qse/lib/cmn/rex.c b/qse/lib/cmn/rex.c index 7a2cd18a..810483f4 100644 --- a/qse/lib/cmn/rex.c +++ b/qse/lib/cmn/rex.c @@ -1,5 +1,5 @@ /* - * $Id: rex.c 326 2010-05-09 13:44:39Z hyunghwan.chung $ + * $Id: rex.c 327 2010-05-10 13:15:55Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -910,6 +910,36 @@ static qse_rex_node_t* comp_atom (comp_t* com) return atom; } +#if 0 +static qse_rex_node_t* zero_or_more (comp_t* c, qse_rex_node_t* atom) +{ + qse_rex_node_t* b; + + b = newbranchnode (c, QSE_NULL, atom); + if (b == QSE_NULL) return QSE_NULL; + + atom->occ.min = 1; + atom->occ.max = 1; + atom->next = b; + + return b; +} + +static qse_rex_node_t* one_or_more (comp_t* c, qse_rex_node_t* atom) +{ + qse_rex_node_t* b; + + b = newbranchnode (c, atom, QSE_NULL); + + atom->occ.min = 1; + atom->occ.max = 1; + atom->next = b; + + TODO: return b as the tail.... + return atom; +} +#endif + static qse_rex_node_t* pseudo_group (comp_t* c, qse_rex_node_t* atom) { qse_rex_node_t* g, *ge, * b; @@ -962,20 +992,41 @@ static qse_rex_node_t* comp_branch (comp_t* c, pair_t* pair) { qse_rex_node_t* atom = comp_atom (c); if (atom == QSE_NULL) return QSE_NULL; + if (atom->occ.min <= 0) { - /* - * Given an atom, this function encloses it with a pseudogroup - * head and a psuedo-group tail. the pseudogroup head is - * followed by a branch that conntects to the pseudogroup tail - * and the atom given. The atom given gets connected to the - * pseudogroup tail. - * Head -> BR -> Tail - * -> ORG(atom) -> Tail - */ - atom = pseudo_group (c, atom); + #if 0 + if (atom->occ.max >= OCC_MAX) + { + /* + * +-----------next--+ + * v | + * BR --alter----> ORG(atom) + * | + * +----next-------------------> + * + */ + atom = zero_or_more (c, atom); + } + else + { + #endif + /* + * Given an atom, enclose it with a + * pseudogroup head and a psuedogroup + * tail. the head is followed by a + * branch that conntects to the tail + * and the atom given. The atom given + * gets connected to the tail. + * Head -> BR -> Tail + * -> ORG(atom) -> Tail + */ + atom = pseudo_group (c, atom); + } if (atom == QSE_NULL) return QSE_NULL; + #if 0 } + #endif if (pair->tail == QSE_NULL) { @@ -1340,22 +1391,21 @@ static int addcands ( exec_t* e, group_t* group, qse_rex_node_t* prevnode, qse_rex_node_t* candnode, const qse_char_t* mptr) { + qse_rex_node_t* curcand = candnode; + warpback: -#ifndef DONOT_SKIP_NOP /* skip all NOP nodes */ - while (candnode != QSE_NULL && candnode->id == QSE_REX_NODE_NOP) - candnode = candnode->next; -#endif + while (curcand != QSE_NULL && curcand->id == QSE_REX_NODE_NOP) + curcand = curcand->next; /* nothing to add */ - if (candnode == QSE_NULL) return 0; + if (curcand == QSE_NULL) return 0; - switch (candnode->id) + switch (curcand->id) { case QSE_REX_NODE_END: { -/*qse_printf (QSE_T("== ADDING THE END(MATCH) NODE MEANING MATCH FOUND == \n"));*/ if (e->matchend == QSE_NULL || mptr >= e->matchend) e->matchend = mptr; e->nmatches++; @@ -1373,52 +1423,33 @@ warpback: if (gx == QSE_NULL) return -1; } -#if 0 - refupgroupstack (group); - refupgroupstack (gx); - - n = addcands (e, group, - prevnode, candnode->next, mptr); - if (n >= 0) - { - n = addcands (e, gx, - prevnode, candnode->u.b.alter, mptr); - } - - refdowngroupstack (gx, e->rex->mmgr); - refdowngroupstack (group, e->rex->mmgr); - if (n <= -1) return -1; - break; - -#endif refupgroupstack (gx); n = addcands (e, gx, - prevnode, candnode->u.b.alter, mptr); + prevnode, curcand->u.b.alter, mptr); refdowngroupstack (gx, e->rex->mmgr); if (n <= -1) return -1; - candnode = candnode->next; + curcand = curcand->next; goto warpback; } case QSE_REX_NODE_GROUP: { - int n; qse_rex_node_t* front; group_t* gx; #ifdef XTRA_DEBUG qse_printf (QSE_T("DEBUG: GROUP %p(pseudo=%d) PREV %p\n"), - candnode, candnode->u.g.pseudo, prevnode); + curcand, curcand->u.g.pseudo, prevnode); #endif - if (candnode->u.g.pseudo) + if (curcand->u.g.pseudo) { - candnode = candnode->u.g.head; + curcand = curcand->u.g.head; goto warpback; } /* skip all NOP nodes */ - front = candnode->u.g.head; + front = curcand->u.g.head; while (front->id == QSE_REX_NODE_NOP) front = front->next; @@ -1429,22 +1460,18 @@ warpback: * regardless of its occurrence. * however, this will never be reached * as it has been removed in comp() */ - candnode = candnode->next; + curcand = curcand->next; goto warpback; } - gx = groupstackpush (e, group, candnode); + gx = groupstackpush (e, group, curcand); if (gx == QSE_NULL) return -1; /* add the first node in the group to * the candidate array */ - refupgroupstack (gx); - n = addcands (e, gx, prevnode, front, mptr); - refdowngroupstack (gx, e->rex->mmgr); - - if (n <= -1) return -1; - - break; + group = gx; + curcand = front; + goto warpback; } case QSE_REX_NODE_GROUPEND: @@ -1456,12 +1483,12 @@ warpback: #ifdef XTRA_DEBUG qse_printf (QSE_T("DEBUG: GROUPEND %p(pseudo=%d) PREV %p\n"), - candnode, candnode->u.ge.pseudo, prevnode); + curcand, curcand->u.ge.pseudo, prevnode); #endif - if (candnode->u.ge.pseudo) + if (curcand->u.ge.pseudo) { - candnode = candnode->u.ge.group->next; + curcand = curcand->u.ge.group->next; goto warpback; } @@ -1469,7 +1496,7 @@ warpback: group != QSE_NULL && group->next != QSE_NULL, "GROUPEND must be paired up with GROUP"); - if (prevnode == candnode) + if (prevnode == curcand) { /* consider a pattern like (x*)*. * when GROUPEND is reached, an 'if' block @@ -1488,7 +1515,7 @@ warpback: occ = top->occ; node = top->node; - QSE_ASSERTX (node == candnode->u.ge.group, + QSE_ASSERTX (node == curcand->u.ge.group, "The GROUP node in the group stack must be the " "one pairing up with the GROUPEND node." ); @@ -1539,7 +1566,7 @@ warpback: prevnode->id == QSE_REX_NODE_GROUPEND) n = addcands (e, gx, prevnode, node->next, mptr); else - n = addcands (e, gx, candnode, node->next, mptr); + n = addcands (e, gx, curcand, node->next, mptr); refdowngroupstack (gx, e->rex->mmgr); if (n <= -1) return -1; @@ -1548,18 +1575,9 @@ warpback: if (occ < node->occ.max) { /* repeat itself. */ - /* BEGIN avoid recursion */ - #if 0 - refupgroupstack (group); - n = addcands (e, group, prevnode, node->u.g.head, mptr); - refdowngroupstack (group, e->rex->mmgr); - if (n <= -1) return -1; - #endif - - prevnode = candnode; - candnode = node->u.g.head; + prevnode = curcand; + curcand = node->u.g.head; goto warpback; - /* END avoid recursion */ } break; @@ -1570,7 +1588,7 @@ warpback: int n; if (group) refupgroupstack (group); - n = addsimplecand (e, group, candnode, 1, mptr); + n = addsimplecand (e, group, curcand, 1, mptr); if (group) refdowngroupstack (group, e->rex->mmgr); if (n <= -1) return -1; @@ -1664,152 +1682,142 @@ static int charset_matched (exec_t* e, qse_rex_node_t* node, qse_char_t c) return matched; } -static int match (exec_t* e) +static qse_lda_walk_t walk_cands_for_match ( + qse_lda_t* lda, qse_size_t index, void* ctx) { - qse_size_t i; + exec_t* e = (exec_t*)ctx; + cand_t* cand = QSE_LDA_DPTR(lda,index); + qse_rex_node_t* node = cand->node; + const qse_char_t* nmptr = QSE_NULL; - QSE_ASSERT (QSE_LDA_SIZE(&e->cand.set[e->cand.active]) > 0); - - for (i = 0; i < QSE_LDA_SIZE(&e->cand.set[e->cand.active]); i++) + switch (node->id) { - cand_t* cand = QSE_LDA_DPTR(&e->cand.set[e->cand.active],i); - qse_rex_node_t* node = cand->node; - const qse_char_t* nmptr = QSE_NULL; - - switch (node->id) - { -#ifdef DONOT_SKIP_NOP - case QSE_REX_NODE_NOP: + case QSE_REX_NODE_BOL: + if (cand->mptr == e->str.ptr) + { + /* the next match pointer remains + * the same as ^ matches a position, + * not a character. */ nmptr = cand->mptr; - break; -#endif + #ifdef XTRA_DEBUG + qse_printf (QSE_T("DEBUG: matched <^>\n")); + #endif + } + break; - case QSE_REX_NODE_BOL: - if (cand->mptr == e->str.ptr) - { - /* the next match pointer remains - * the same as ^ matches a position, - * not a character. */ - nmptr = cand->mptr; - #ifdef XTRA_DEBUG - qse_printf (QSE_T("DEBUG: matched <^>\n")); - #endif - } - break; + case QSE_REX_NODE_EOL: + if (cand->mptr >= e->str.end) + { + /* the next match pointer remains + * the same as $ matches a position, + * not a character. */ + nmptr = cand->mptr; + #ifdef XTRA_DEBUG + qse_printf (QSE_T("DEBUG: matched <$>\n")); + #endif + } + break; - case QSE_REX_NODE_EOL: - if (cand->mptr >= e->str.end) - { - /* the next match pointer remains - * the same as $ matches a position, - * not a character. */ - nmptr = cand->mptr; - #ifdef XTRA_DEBUG - qse_printf (QSE_T("DEBUG: matched <$>\n")); - #endif - } - break; + case QSE_REX_NODE_ANY: + if (cand->mptr < e->sub.end) + { + /* advance the match pointer to the + * next chracter.*/ + nmptr = cand->mptr + 1; + #ifdef XTRA_DEBUG + qse_printf (QSE_T("DEBUG: matched <.>\n")); + #endif + } + break; - case QSE_REX_NODE_ANY: - if (cand->mptr < e->sub.end) + case QSE_REX_NODE_CHAR: + { + if (cand->mptr < e->sub.end) + { + int equal; + + equal =(e->rex->option & QSE_REX_IGNORECASE)? + (QSE_TOUPPER(node->u.c) == QSE_TOUPPER(*cand->mptr)): + (node->u.c == *cand->mptr) ; + + if (equal) { /* advance the match pointer to the * next chracter.*/ nmptr = cand->mptr + 1; - #ifdef XTRA_DEBUG - qse_printf (QSE_T("DEBUG: matched <.>\n")); - #endif } - break; - - case QSE_REX_NODE_CHAR: - { - - if (cand->mptr < e->sub.end) - { - int equal; - - equal =(e->rex->option & QSE_REX_IGNORECASE)? - (QSE_TOUPPER(node->u.c) == QSE_TOUPPER(*cand->mptr)): - (node->u.c == *cand->mptr) ; - - if (equal) - { - /* advance the match pointer to the - * next chracter.*/ - nmptr = cand->mptr + 1; - } - #ifdef XTRA_DEBUG - qse_printf (QSE_T("DEBUG: matched %c\n"), node->u.c); - #endif - } - break; - } - - case QSE_REX_NODE_CSET: - { - if (cand->mptr < e->sub.end && - charset_matched(e, node, *cand->mptr)) - { - /* advance the match pointer - * to the next chracter.*/ - nmptr = cand->mptr + 1; - } - - break; - } - - default: - { - QSE_ASSERTX (0, - "SHOUL NEVER HAPPEN - node ID must be" - "one of QSE_REX_NODE_BOL, " - "QSE_REX_NODE_EOL, " - "QSE_REX_NODE_ANY, " - "QSE_REX_NODE_CHAR, " - "QSE_REX_NODE_CSET, " - "QSE_REX_NODE_NOP"); - - break; + #ifdef XTRA_DEBUG + qse_printf (QSE_T("DEBUG: matched %c\n"), node->u.c); + #endif } + break; } - if (nmptr != QSE_NULL) + case QSE_REX_NODE_CSET: { - int n; - - if (cand->occ >= node->occ.min) + if (cand->mptr < e->sub.end && + charset_matched(e, node, *cand->mptr)) { - group_t* gx; - - if (cand->occ < node->occ.max && cand->group != QSE_NULL) - { - gx = dupgroupstack (e, cand->group); - if (gx == QSE_NULL) return -1; - } - else gx = cand->group; - - /* move on to the next candidate */ - refupgroupstack (gx); - n = addcands (e, gx, node, node->next, nmptr); - refdowngroupstack (gx, e->rex->mmgr); - - if (n <= -1) return -1; + /* advance the match pointer + * to the next chracter.*/ + nmptr = cand->mptr + 1; } - if (cand->occ < node->occ.max) - { - /* repeat itself more */ - refupgroupstack (cand->group); - n = addsimplecand (e, cand->group, node, cand->occ+1, nmptr); - refdowngroupstack (cand->group, e->rex->mmgr); + break; + } - if (n <= -1) return -1; - } + default: + { + QSE_ASSERTX (0, + "SHOULD NEVER HAPPEN - node ID must be" + "one of QSE_REX_NODE_BOL, " + "QSE_REX_NODE_EOL, " + "QSE_REX_NODE_ANY, " + "QSE_REX_NODE_CHAR, " + "QSE_REX_NODE_CSET, " + "QSE_REX_NODE_NOP"); + + break; } } - return 0; + if (nmptr != QSE_NULL) + { + int n; + + if (cand->occ >= node->occ.min) + { + group_t* gx; + + if (cand->occ < node->occ.max && cand->group != QSE_NULL) + { + gx = dupgroupstack (e, cand->group); + if (gx == QSE_NULL) return QSE_LDA_WALK_STOP; + } + else gx = cand->group; + + /* move on to the next candidate */ + refupgroupstack (gx); + n = addcands (e, gx, node, node->next, nmptr); + refdowngroupstack (gx, e->rex->mmgr); + + if (n <= -1) return QSE_LDA_WALK_STOP; + } + + if (cand->occ < node->occ.max) + { + /* repeat itself more */ + refupgroupstack (cand->group); + n = addsimplecand ( + e, cand->group, + node, cand->occ + 1, nmptr); + refdowngroupstack (cand->group, e->rex->mmgr); + + if (n <= -1) return QSE_LDA_WALK_STOP; + } + } + + return QSE_LDA_WALK_FORWARD; } static int exec (exec_t* e) @@ -1828,7 +1836,7 @@ static int exec (exec_t* e) /* the first node must be the START node */ QSE_ASSERT (e->rex->code->id == QSE_REX_NODE_START); - /* addcands() collects a set of candidates into the pending set */ + /* collect an initial set of candidates into the pending set */ n = addcands ( e, /* execution structure */ QSE_NULL, /* doesn't belong to any groups yet */ @@ -1840,6 +1848,8 @@ static int exec (exec_t* e) do { + qse_size_t ncands_active; + /* swap the pending and active set indices. * the pending set becomes active after which the match() * function tries each candidate in it. New candidates @@ -1849,7 +1859,8 @@ static int exec (exec_t* e) e->cand.pending = e->cand.active; e->cand.active = tmp; - if (QSE_LDA_SIZE(&e->cand.set[e->cand.active]) <= 0) + ncands_active = QSE_LDA_SIZE(&e->cand.set[e->cand.active]); + if (ncands_active <= 0) { /* we can't go on with no candidates in the * active set. */ @@ -1863,7 +1874,7 @@ static int exec (exec_t* e) { int i; qse_printf (QSE_T("SET=")); - for (i = 0; i < QSE_LDA_SIZE(&e->cand.set[e->cand.active]); i++) + for (i = 0; i < ncands_active; i++) { cand_t* cand = QSE_LDA_DPTR(&e->cand.set[e->cand.active],i); qse_rex_node_t* node = cand->node; @@ -1881,7 +1892,15 @@ static int exec (exec_t* e) } #endif - if (match (e) <= -1) return -1; + if (qse_lda_walk ( + &e->cand.set[e->cand.active], + walk_cands_for_match, e) != ncands_active) + { + /* if the number of walks is different the number of + * candidates, traversal must have been aborted for + * an error. */ + return -1; + } } while (1); @@ -1910,6 +1929,7 @@ static int comp_cand (qse_lda_t* lda, { cand_t* c1 = (cand_t*)dptr1; cand_t* c2 = (cand_t*)dptr2; +//qse_printf (QSE_T("%p(%d) %p(%d), %p %p, %d %d\n"), c1->node,c1->node->id, c2->node,c1->node->id, c1->mptr, c2->mptr, (int)c1->occ, (int)c2->occ); return (c1->node == c2->node && c1->mptr == c2->mptr && c1->occ == c2->occ)? 0: 1;