X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/halibut/blobdiff_plain/f15300499bce37cd28ea2ace0f2bd1c364fc835e..8f664e7e91c918cd13248f6b684580c4dd2cdb31:/misc.c diff --git a/misc.c b/misc.c index 0d488d4..3f2483c 100644 --- a/misc.c +++ b/misc.c @@ -90,13 +90,16 @@ void rdaddc(rdstringc *rs, char c) { rs->text[rs->pos] = 0; } void rdaddsc(rdstringc *rs, char const *p) { - int len = strlen(p); + rdaddsn(rs, p, strlen(p)); +} +void rdaddsn(rdstringc *rs, char const *p, int len) { if (rs->pos >= rs->size - len) { rs->size = rs->pos + len + 128; rs->text = sresize(rs->text, rs->size, char); } - strcpy(rs->text + rs->pos, p); + memcpy(rs->text + rs->pos, p, len); rs->pos += len; + rs->text[rs->pos] = 0; } char *rdtrimc(rdstringc *rs) { rs->text = sresize(rs->text, rs->pos + 1, char); @@ -126,7 +129,7 @@ static int compare_wordlists_literally(word *a, word *b) { } else { wchar_t *ap = a->text, *bp = b->text; while (*ap && *bp) { - wchar_t ac = utolower(*ap), bc = utolower(*bp); + wchar_t ac = *ap, bc = *bp; if (ac != bc) return (ac < bc ? -1 : +1); if (!*++ap && a->next && a->next->type == t && !a->next->alt) @@ -234,17 +237,32 @@ void mark_attr_ends(word *words) wp = NULL; for (w = words; w; w = w->next) { - if (isattr(w->type)) { - int before = (wp && isattr(wp->type) && - sameattr(wp->type, w->type)); - int after = (w->next && isattr(w->next->type) && - sameattr(w->next->type, w->type)); - w->aux |= (before ? - (after ? attr_Always : attr_Last) : - (after ? attr_First : attr_Only)); + int both; + if (!isvis(w->type)) + /* Invisible elements should not affect this calculation */ + continue; + both = (isattr(w->type) && + wp && isattr(wp->type) && + sameattr(wp->type, w->type)); + w->aux |= both ? attr_Always : attr_First; + if (wp && !both) { + /* If previous considered word turns out to have been + * the end of a run, tidy it up. */ + int wp_attr = attraux(wp->aux); + wp->aux = (wp->aux & ~attr_mask) | + ((wp_attr == attr_Always) ? attr_Last + /* attr_First */ : attr_Only); } wp = w; } + + /* Tidy up last word touched */ + if (wp) { + int wp_attr = attraux(wp->aux); + wp->aux = (wp->aux & ~attr_mask) | + ((wp_attr == attr_Always) ? attr_Last + /* attr_First */ : attr_Only); + } } /*