X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/halibut/blobdiff_plain/e4ea58f8cb4dccaa8e99306a3497de1e37600480..26c8c119efd44804c7b27f8637c69eda63f0c189:/misc.c diff --git a/misc.c b/misc.c index 304cb1f..3f2483c 100644 --- a/misc.c +++ b/misc.c @@ -18,7 +18,7 @@ struct stackTag { stack stk_new(void) { stack s; - s = mknew(struct stackTag); + s = snew(struct stackTag); s->sp = 0; s->size = 0; s->data = NULL; @@ -34,7 +34,7 @@ void stk_free(stack s) { void stk_push(stack s, void *item) { if (s->size <= s->sp) { s->size = s->sp + 32; - s->data = resize(s->data, s->size); + s->data = sresize(s->data, s->size, void *); } s->data[s->sp++] = item; } @@ -62,7 +62,7 @@ const rdstringc empty_rdstringc = {0, 0, NULL}; void rdadd(rdstring *rs, wchar_t c) { if (rs->pos >= rs->size-1) { rs->size = rs->pos + 128; - rs->text = resize(rs->text, rs->size); + rs->text = sresize(rs->text, rs->size, wchar_t); } rs->text[rs->pos++] = c; rs->text[rs->pos] = 0; @@ -71,35 +71,38 @@ void rdadds(rdstring *rs, wchar_t const *p) { int len = ustrlen(p); if (rs->pos >= rs->size - len) { rs->size = rs->pos + len + 128; - rs->text = resize(rs->text, rs->size); + rs->text = sresize(rs->text, rs->size, wchar_t); } ustrcpy(rs->text + rs->pos, p); rs->pos += len; } wchar_t *rdtrim(rdstring *rs) { - rs->text = resize(rs->text, rs->pos + 1); + rs->text = sresize(rs->text, rs->pos + 1, wchar_t); return rs->text; } void rdaddc(rdstringc *rs, char c) { if (rs->pos >= rs->size-1) { rs->size = rs->pos + 128; - rs->text = resize(rs->text, rs->size); + rs->text = sresize(rs->text, rs->size, char); } rs->text[rs->pos++] = 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 = resize(rs->text, rs->size); + 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 = resize(rs->text, rs->pos + 1); + rs->text = sresize(rs->text, rs->pos + 1, char); return rs->text; } @@ -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) @@ -194,10 +197,25 @@ int compare_wordlists(word *a, word *b) { } } +#ifdef HAS_WCSCOLL + { + wchar_t a[2], b[2]; + int ret; + + a[0] = pos[0].c; + b[0] = pos[1].c; + a[1] = b[1] = L'\0'; + + ret = wcscoll(a, b); + if (ret) + return ret; + } +#else if (pos[0].c < pos[1].c) return -1; else if (pos[0].c > pos[1].c) return +1; +#endif if (!pos[0].c) break; /* they're equal */ @@ -213,23 +231,37 @@ int compare_wordlists(word *a, word *b) { return compare_wordlists_literally(a, b); } -void mark_attr_ends(paragraph *sourceform) { - paragraph *p; +void mark_attr_ends(word *words) +{ word *w, *wp; - for (p = sourceform; p; p = p->next) { - wp = NULL; - for (w = p->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)); - } - wp = w; + + wp = NULL; + for (w = words; w; w = w->next) { + 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); } } @@ -448,7 +480,7 @@ wrappedline *wrap_para(word *text, int width, int subsequentwidth, */ i = 0; while (i < nwords) { - wrappedline *w = mknew(wrappedline); + wrappedline *w = snew(wrappedline); *ptr = w; ptr = &w->next; w->next = NULL; @@ -497,17 +529,17 @@ void cmdline_cfg_add(paragraph *cfg, char *string) while (cfg->origkeyword[len]) len += 1 + strlen(cfg->origkeyword+len); - ustring = ufroma_dup(string, CS_FIXME); + ustring = ufroma_locale_dup(string); upos = ulen; ulen += 2 + ustrlen(ustring); - cfg->keyword = resize(cfg->keyword, ulen); + cfg->keyword = sresize(cfg->keyword, ulen, wchar_t); ustrcpy(cfg->keyword+upos, ustring); cfg->keyword[ulen-1] = L'\0'; pos = len; len += 2 + strlen(string); - cfg->origkeyword = resize(cfg->origkeyword, len); + cfg->origkeyword = sresize(cfg->origkeyword, len, char); strcpy(cfg->origkeyword+pos, string); cfg->origkeyword[len-1] = '\0'; @@ -518,7 +550,7 @@ paragraph *cmdline_cfg_new(void) { paragraph *p; - p = mknew(paragraph); + p = snew(paragraph); memset(p, 0, sizeof(*p)); p->type = para_Config; p->next = NULL;