mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-28 07:58:08 +01:00
Fix prefix matching to accept letters constituting the first part of a
digraph tile when at the end of a prefix so that e.g. GORIL in Catalan will list GORIL·LA (rather than nothing since GORIL, ending with the L tile, is not a prefix.)
This commit is contained in:
parent
fddd2c4ed5
commit
145317426d
4 changed files with 90 additions and 57 deletions
|
@ -1568,13 +1568,9 @@ Java_org_eehouse_android_xw4_jni_XwJNI_dict_1iter_1getStartsWith
|
|||
jint result = -1;
|
||||
DictIterData* data = (DictIterData*)closure;
|
||||
if ( NULL != data ) {
|
||||
Tile tiles[MAX_COLS];
|
||||
XP_U16 nTiles = VSIZE(tiles);
|
||||
const char* prefix = (*env)->GetStringUTFChars( env, jprefix, NULL );
|
||||
if ( dict_tilesForString( data->dict, prefix, tiles, &nTiles ) ) {
|
||||
if ( dict_findStartsWith( &data->iter, NULL, tiles, nTiles ) ) {
|
||||
result = dict_getPosition( &data->iter );
|
||||
}
|
||||
if ( 0 <= dict_findStartsWith( &data->iter, prefix ) ) {
|
||||
result = dict_getPosition( &data->iter );
|
||||
}
|
||||
(*env)->ReleaseStringUTFChars( env, jprefix, prefix );
|
||||
}
|
||||
|
|
|
@ -170,7 +170,7 @@ prevWord( DictIter* iter )
|
|||
}
|
||||
|
||||
static XP_Bool
|
||||
findStartsWith( DictIter* iter, const Tile* tiles, XP_U16 nTiles )
|
||||
findStartsWithTiles( DictIter* iter, const Tile* tiles, XP_U16 nTiles )
|
||||
{
|
||||
const DictionaryCtxt* dict = iter->dict;
|
||||
array_edge* edge = dict_getTopEdge( dict );
|
||||
|
@ -189,6 +189,44 @@ findStartsWith( DictIter* iter, const Tile* tiles, XP_U16 nTiles )
|
|||
return 0 == nTiles;
|
||||
}
|
||||
|
||||
static XP_S16
|
||||
findStartsWithChars( DictIter* iter, const XP_UCHAR* chars, XP_U16 charsOffset,
|
||||
array_edge* edge, XP_U16 nTilesUsed )
|
||||
{
|
||||
XP_S16 result = -1;
|
||||
if ( NULL == edge || ( '\0' == chars[charsOffset] ) ) {
|
||||
iter->nEdges = nTilesUsed;
|
||||
result = charsOffset;
|
||||
} else {
|
||||
const DictionaryCtxt* dict = iter->dict;
|
||||
XP_U16 nodeSize = dict->nodeSize;
|
||||
XP_U16 charsLen = XP_STRLEN( &chars[charsOffset] );
|
||||
for ( ; ; ) {
|
||||
Tile tile = EDGETILE( dict, edge );
|
||||
const XP_UCHAR* facep = dict_getTileString( dict, tile );
|
||||
XP_U16 faceLen = XP_STRLEN( facep );
|
||||
if ( faceLen > charsLen ) {
|
||||
faceLen = charsLen;
|
||||
}
|
||||
if ( 0 == XP_STRNCMP( facep, &chars[charsOffset], faceLen ) ) {
|
||||
XP_S16 newOffset = findStartsWithChars( iter, chars,
|
||||
charsOffset + faceLen,
|
||||
dict_follow( dict, edge ),
|
||||
nTilesUsed + 1 );
|
||||
if ( result < newOffset ) {
|
||||
iter->edges[nTilesUsed] = edge;
|
||||
result = newOffset;
|
||||
}
|
||||
}
|
||||
if ( IS_LAST_EDGE( dict, edge ) ) {
|
||||
break;
|
||||
}
|
||||
edge += nodeSize;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static XP_Bool
|
||||
startsWith( const DictIter* iter, const Tile* tiles, XP_U16 nTiles )
|
||||
{
|
||||
|
@ -203,7 +241,7 @@ static XP_Bool
|
|||
findWordStartsWith( DictIter* iter, const Tile* tiles, XP_U16 nTiles )
|
||||
{
|
||||
XP_Bool found = XP_FALSE;
|
||||
if ( findStartsWith( iter, tiles, nTiles ) ) {
|
||||
if ( findStartsWithTiles( iter, tiles, nTiles ) ) {
|
||||
found = ACCEPT_ITER( iter, iter->nEdges );
|
||||
if ( !found ) {
|
||||
found = nextWord( iter ) && startsWith( iter, tiles, nTiles );
|
||||
|
@ -586,37 +624,41 @@ dict_getNthWord( DictIter* iter, DictPosition position, XP_U16 depth,
|
|||
return success;
|
||||
} /* dict_getNthWord */
|
||||
|
||||
XP_Bool
|
||||
dict_findStartsWith( DictIter* iter, const IndexData* data,
|
||||
const Tile* prefix, XP_U16 len )
|
||||
static DictPosition
|
||||
figurePosition( DictIter* iter )
|
||||
{
|
||||
XP_Bool success = XP_FALSE;
|
||||
ASSERT_INITED( iter );
|
||||
XP_USE(data);
|
||||
XP_LOGF( "%s: not using data", __func__ );
|
||||
DictPosition result = 0;
|
||||
DictIter iterZero;
|
||||
dict_initIterFrom( &iterZero, iter );
|
||||
if ( !firstWord( &iterZero ) ) {
|
||||
XP_ASSERT( 0 );
|
||||
}
|
||||
|
||||
DictIter targetIter;
|
||||
dict_initIterFrom( &targetIter, iter );
|
||||
if ( findWordStartsWith( &targetIter, prefix, len ) ) {
|
||||
|
||||
DictPosition result = 0;
|
||||
DictIter iterZero;
|
||||
dict_initIterFrom( &iterZero, iter );
|
||||
if ( !firstWord( &iterZero ) ) {
|
||||
while ( ! wordsEqual( &iterZero, iter ) ) {
|
||||
++result;
|
||||
if ( !nextWord( &iterZero ) ) {
|
||||
XP_ASSERT( 0 );
|
||||
}
|
||||
|
||||
while ( ! wordsEqual( &iterZero, &targetIter ) ) {
|
||||
++result;
|
||||
if ( !nextWord( &iterZero ) ) {
|
||||
XP_ASSERT( 0 );
|
||||
}
|
||||
}
|
||||
copyIter( iter, &iterZero );
|
||||
iter->position = result;
|
||||
success = XP_TRUE;
|
||||
}
|
||||
return success;
|
||||
copyIter( iter, &iterZero );
|
||||
return result;
|
||||
}
|
||||
|
||||
XP_S16
|
||||
dict_findStartsWith( DictIter* iter, const XP_UCHAR* prefix )
|
||||
{
|
||||
ASSERT_INITED( iter );
|
||||
array_edge* edge = dict_getTopEdge( iter->dict );
|
||||
XP_S16 offset = findStartsWithChars( iter, prefix, 0, edge, 0 );
|
||||
if ( 0 < offset ) {
|
||||
if ( nextWord( iter ) ) {
|
||||
DictPosition result = figurePosition( iter );
|
||||
iter->position = result;
|
||||
} else {
|
||||
offset = -1;
|
||||
}
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -74,8 +74,7 @@ XP_Bool dict_getPrevWord( DictIter* iter );
|
|||
XP_Bool dict_getNthWord( DictIter* iter, DictPosition position, XP_U16 depth,
|
||||
const IndexData* data );
|
||||
void dict_wordToString( const DictIter* iter, XP_UCHAR* buf, XP_U16 buflen );
|
||||
XP_Bool dict_findStartsWith( DictIter* iter, const IndexData* data,
|
||||
const Tile* prefix, XP_U16 len );
|
||||
XP_S16 dict_findStartsWith( DictIter* iter, const XP_UCHAR* prefix );
|
||||
DictPosition dict_getPosition( const DictIter* iter );
|
||||
#ifdef CPLUS
|
||||
}
|
||||
|
|
|
@ -1305,31 +1305,27 @@ walk_dict_test( const LaunchParams* XP_UNUSED_DBG(params),
|
|||
guint count = g_slist_length( testPrefixes );
|
||||
for ( ii = 0; ii < count; ++ii ) {
|
||||
gchar* prefix = (gchar*)g_slist_nth_data( testPrefixes, ii );
|
||||
Tile tiles[MAX_COLS_DICT];
|
||||
XP_U16 nTiles = VSIZE(tiles);
|
||||
if ( dict_tilesForString( dict, prefix, tiles, &nTiles ) ) {
|
||||
if ( dict_findStartsWith( &iter, NULL, tiles, nTiles ) ) {
|
||||
XP_UCHAR buf[32];
|
||||
XP_UCHAR bufPrev[32] = {0};
|
||||
dict_wordToString( &iter, buf, VSIZE(buf) );
|
||||
XP_S16 lenMatched = dict_findStartsWith( &iter, prefix );
|
||||
if ( 0 < lenMatched ) {
|
||||
XP_UCHAR buf[32];
|
||||
XP_UCHAR bufPrev[32] = {0};
|
||||
dict_wordToString( &iter, buf, VSIZE(buf) );
|
||||
|
||||
XP_ASSERT( 0 == strncmp( buf, prefix, strlen(prefix) ) );
|
||||
XP_ASSERT( 0 == strncmp( buf, prefix, lenMatched ) );
|
||||
|
||||
DictPosition pos = dict_getPosition( &iter );
|
||||
XP_ASSERT( 0 == strcmp( buf, words[pos] ) );
|
||||
if ( pos > 0 ) {
|
||||
if ( !dict_getNthWord( &iter, pos-1, depth,
|
||||
&data ) ) {
|
||||
XP_ASSERT( 0 );
|
||||
}
|
||||
dict_wordToString( &iter, bufPrev, VSIZE(bufPrev) );
|
||||
XP_ASSERT( 0 == strcmp( bufPrev, words[pos-1] ) );
|
||||
DictPosition pos = dict_getPosition( &iter );
|
||||
XP_ASSERT( 0 == strncmp( buf, words[pos], lenMatched ) );
|
||||
if ( pos > 0 ) {
|
||||
if ( !dict_getNthWord( &iter, pos-1, depth, &data ) ) {
|
||||
XP_ASSERT( 0 );
|
||||
}
|
||||
XP_LOGF( "dict_getStartsWith(%s) => %s (prev=%s)",
|
||||
prefix, buf, bufPrev );
|
||||
} else {
|
||||
XP_LOGF( "nothing starts with %s", prefix );
|
||||
dict_wordToString( &iter, bufPrev, VSIZE(bufPrev) );
|
||||
XP_ASSERT( 0 == strcmp( bufPrev, words[pos-1] ) );
|
||||
}
|
||||
XP_LOGF( "dict_getStartsWith(%s) => %s (prev=%s)",
|
||||
prefix, buf, bufPrev );
|
||||
} else {
|
||||
XP_LOGF( "nothing starts with %s", prefix );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue