diff --git a/src/runtime/c/pgf/linearizer.cxx b/src/runtime/c/pgf/linearizer.cxx index d44ca838f..fdf434f70 100644 --- a/src/runtime/c/pgf/linearizer.cxx +++ b/src/runtime/c/pgf/linearizer.cxx @@ -646,8 +646,14 @@ void PgfLinearizer::reverse_and_label(bool add_linref) } } +PGF_INTERNAL_DECL bool +pgf_is_case_sensitive(ref concr); + void PgfLinearizer::flush_pre_stack(PgfLinearizationOutputIface *out, PgfText *token) { + bool (*cmp)(PgfText *t, PgfText *prefix) = + pgf_is_case_sensitive(concr) ? textstarts : textistarts; + while (pre_stack != NULL) { PreStack *pre = pre_stack; pre_stack = pre->next; @@ -657,7 +663,7 @@ void PgfLinearizer::flush_pre_stack(PgfLinearizationOutputIface *out, PgfText *t PgfAlternative *alt = &pre->sym_kp->alts.data[i]; for (size_t j = 0; j < alt->prefixes->len; j++) { ref prefix = *vector_elem(alt->prefixes,j); - if (textstarts(token, &(*prefix))) { + if (cmp(token, &(*prefix))) { pre->node->linearize_seq(out, this, alt->form); goto done; } diff --git a/src/runtime/c/pgf/pgf.cxx b/src/runtime/c/pgf/pgf.cxx index bfd45e4d5..50c5e6f5e 100644 --- a/src/runtime/c/pgf/pgf.cxx +++ b/src/runtime/c/pgf/pgf.cxx @@ -819,7 +819,7 @@ void pgf_iter_lins(PgfDB *db, PgfConcrRevision cnc_revision, } PGF_API_END } -static bool +PGF_INTERNAL bool pgf_is_case_sensitive(ref concr) { PgfText *case_sensitive = (PgfText *) diff --git a/src/runtime/c/pgf/text.cxx b/src/runtime/c/pgf/text.cxx index d29126aa9..63a8b98eb 100644 --- a/src/runtime/c/pgf/text.cxx +++ b/src/runtime/c/pgf/text.cxx @@ -74,6 +74,29 @@ bool textstarts(PgfText *t, PgfText *prefix) return true; } +PGF_INTERNAL +bool textistarts(PgfText *t, PgfText *prefix) +{ + const uint8_t *s1 = (uint8_t*) &t->text; + const uint8_t *e1 = s1+t->size; + + const uint8_t *s2 = (uint8_t*) &prefix->text; + const uint8_t *e2 = s2+prefix->size; + + for (;;) { + if (s1 >= e1) + return false; + if (s2 >= e2) + return true; + + uint32_t ucs1 = pgf_utf8_to_upper(pgf_utf8_decode(&s1)); + uint32_t ucs2 = pgf_utf8_to_upper(pgf_utf8_decode(&s2)); + + if (ucs1 != ucs2) + return false; + } +} + PGF_INTERNAL PgfText* textdup(PgfText *t1) { diff --git a/src/runtime/c/pgf/text.h b/src/runtime/c/pgf/text.h index 31cf7f59c..919bea8e4 100644 --- a/src/runtime/c/pgf/text.h +++ b/src/runtime/c/pgf/text.h @@ -17,6 +17,9 @@ void texticmp(PgfText *t1, PgfText *t2, int res[2]); PGF_INTERNAL_DECL bool textstarts(PgfText *t, PgfText *prefix); +PGF_INTERNAL +bool textistarts(PgfText *t, PgfText *prefix); + PGF_INTERNAL_DECL PgfText* string2text(const char *s);