fix problems iterating backwards with start-with pattern

This commit is contained in:
Eric House 2020-08-07 11:05:58 -07:00
parent e5dd43ee1b
commit e8175d69aa
4 changed files with 42 additions and 28 deletions

View file

@ -59,7 +59,7 @@ public class DictBrowseDelegate extends DelegateBase
implements View.OnClickListener {
private static final String TAG = DictBrowseDelegate.class.getSimpleName();
private static final String DELIM = ".";
private static final boolean SHOW_NUM = false;
private static final boolean SHOW_NUM = BuildConfig.DEBUG;
private static final String[] FAQ_PARAMS = {"filters", "intro"};
private static final String DICT_NAME = "DICT_NAME";
@ -159,7 +159,8 @@ public class DictBrowseDelegate extends DelegateBase
String str = XwJNI.di_nthWord( m_diClosure, position, m_browseState.m_delim );
if ( null != str ) {
if ( SHOW_NUM ) {
str = String.format( "%1$5d %2$s", position, str );
// Yep, 7 digits. Polish.
str = String.format( "%1$7d %2$s", 1+position, str );
}
text.setText( str );
text.setOnClickListener( DictBrowseDelegate.this );

View file

@ -2818,12 +2818,12 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1getIndices
JNIEXPORT jstring JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_di_1nthWord
( JNIEnv* env, jclass C, jlong closure, jint nn, jstring jdelim )
( JNIEnv* env, jclass C, jlong closure, jint jposn, jstring jdelim )
{
jstring result = NULL;
DI_HEADER(XP_TRUE);
if ( NULL != data ) {
if ( di_getNthWord( data->iter, env, nn, data->depth, &data->idata ) ) {
if ( di_getNthWord( data->iter, env, jposn, data->depth, &data->idata ) ) {
XP_UCHAR buf[64];
const XP_UCHAR* delim = NULL == jdelim ? NULL
: (*env)->GetStringUTFChars( env, jdelim, NULL );
@ -2832,6 +2832,8 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1nthWord
if ( !!delim ) {
(*env)->ReleaseStringUTFChars( env, jdelim, delim );
}
} else {
XP_LOGFF( "failed to get %dth word", jposn );
}
}
DI_HEADER_END();

View file

@ -604,6 +604,15 @@ formatCurWord( const DictIter* iter, XP_UCHAR* buf, XP_U16 bufLen )
}
}
/* static void */
/* logCurWord( const DictIter* iter, const XP_UCHAR* note ) */
/* { */
/* XP_UCHAR buf[32]; */
/* XP_U16 bufLen = VSIZE(buf); */
/* formatCurWord( iter, buf, bufLen ); */
/* XP_LOGFF( "note: %s; word: %s", note, buf ); */
/* } */
#endif
typedef struct _FaceTile {
@ -979,7 +988,6 @@ patMatchFinished( const DictIter* iter, XP_Bool log )
XP_UCHAR word[32];
formatCurWord( iter, word, VSIZE(word) );
if ( result ) {
XP_UCHAR elemBuf[64];
PrintState prs = { .iter = iter, .buf = elemBuf, .bufLen = VSIZE(elemBuf), };
@ -995,14 +1003,14 @@ patMatchFinished( const DictIter* iter, XP_Bool log )
}
static XP_Bool
prevPeerMatch( DictIter* iter, array_edge** edgeP, PatMatch* matchP )
prevPeerMatch( DictIter* iter, array_edge** edgeP, PatMatch* matchP, XP_Bool log )
{
const DictionaryCtxt* dict = iter->dict;
array_edge* edge = *edgeP;
XP_Bool found = XP_FALSE;
for ( ; ; ) {
PatMatch match = { 0 };
found = HAS_MATCH( iter, edge, &match, XP_FALSE );
found = HAS_MATCH( iter, edge, &match, log );
if ( found ) {
*edgeP = edge;
*matchP = match;
@ -1131,11 +1139,10 @@ isFirstEdge( const DictionaryCtxt* dict, array_edge* edge )
return result;
}
static XP_Bool
lastEdges( DictIter* iter )
static void
pushLastEdges( DictIter* iter, array_edge* edge, XP_Bool log )
{
const DictionaryCtxt* dict = iter->dict;
array_edge* edge = popEdge( iter );
while ( iter->nEdges < iter->max ) {
/* walk to the end ... */
@ -1144,7 +1151,7 @@ lastEdges( DictIter* iter )
}
/* ... so we can then move back, testing */
PatMatch match = {0};
if ( ! prevPeerMatch( iter, &edge, &match ) ) {
if ( ! prevPeerMatch( iter, &edge, &match, log ) ) {
break;
}
pushEdge( iter, edge, &match );
@ -1154,13 +1161,13 @@ lastEdges( DictIter* iter )
break;
}
}
return ACCEPT_ITER( iter, XP_FALSE );
}
static XP_Bool
prevWord( DictIter* iter, XP_Bool log )
{
const DictionaryCtxt* dict = iter->dict;
XP_Bool success = XP_FALSE;
while ( 0 < iter->nEdges && ! success ) {
if ( isFirstEdge( dict, iter->stack[iter->nEdges-1].edge ) ) {
@ -1173,20 +1180,14 @@ prevWord( DictIter* iter, XP_Bool log )
array_edge* edge = popEdge(iter);
XP_ASSERT( !isFirstEdge( dict, edge ) );
edge -= dict->nodeSize;
PatMatch match = {0};
if ( prevPeerMatch( iter, &edge, &match ) ) {
if ( prevPeerMatch( iter, &edge, &match, log ) ) {
pushEdge( iter, edge, &match );
if ( iter->nEdges < iter->max ) {
edge = dict_follow( dict, edge );
if ( NULL != edge ) {
PatMatch match = {0};
if ( HAS_MATCH( iter, edge, &match, log ) ) {
pushEdge( iter, edge, &match );
success = lastEdges( iter ) && iter->min <= iter->nEdges;
if ( success ) {
continue;
}
}
pushLastEdges( iter, edge, log );
}
}
}
@ -1757,11 +1758,21 @@ di_getNextWord( DictIter* iter )
XP_Bool
di_lastWord( DictIter* iter )
{
ASSERT_INITED( iter );
iter->nEdges = 1;
iter->stack[0].edge = dict_getTopEdge( iter->dict );
const XP_Bool log = XP_FALSE;
XP_Bool success = lastEdges( iter ) || prevWord( iter, XP_FALSE );
ASSERT_INITED( iter );
while ( 0 < iter->nEdges ) {
popEdge( iter );
}
pushLastEdges( iter, dict_getTopEdge( iter->dict ), log );
XP_Bool success = ACCEPT_ITER( iter, log )
&& iter->min <= iter->nEdges
&& iter->nEdges <= iter->max;
if ( !success ) {
success = prevWord( iter, log );
}
if ( success ) {
iter->position = iter->nWords - 1;
}
@ -1848,8 +1859,8 @@ di_getNthWord( DictIter* iter, XWEnv xwe, DictPosition position, XP_U16 depth,
}
while ( repeats-- ) {
if ( !(*finder)( iter, XP_FALSE ) ) {
break;
XP_ASSERT(0); /* firing */
XP_ASSERT(0);
break; /* prevents crash on release builds? */
}
}

View file

@ -2014,7 +2014,7 @@ patsParamsToIter( const LaunchParams* params, const DictionaryCtxt* dict )
}
DictIter* iter = di_makeIter( dict, NULL_XWE, dimmp, strPats, nStrPats,
descs, nPatDescs );
0 == nPatDescs ? NULL : descs, nPatDescs );
return iter;
}