diff options
| author | Simon Tatham <anakin@pobox.com> | 1999-10-20 20:17:18 +0000 |
|---|---|---|
| committer | Simon Tatham <anakin@pobox.com> | 1999-10-20 20:17:18 +0000 |
| commit | 8511f4ae900f48999617bc8384e9c327673e2196 (patch) | |
| tree | d24d0a7d8cc217bf6d864157c3b08e05ed59868f /misc.c | |
| parent | e44f985bd4f796d4c4b11eb3555436dbaa2d163b (diff) | |
| download | halibut-8511f4ae900f48999617bc8384e9c327673e2196.zip halibut-8511f4ae900f48999617bc8384e9c327673e2196.tar.gz halibut-8511f4ae900f48999617bc8384e9c327673e2196.tar.bz2 halibut-8511f4ae900f48999617bc8384e9c327673e2196.tar.xz | |
First backend! Text output now pretty much works.
[originally from svn r240]
Diffstat (limited to 'misc.c')
| -rw-r--r-- | misc.c | 114 |
1 files changed, 114 insertions, 0 deletions
@@ -41,6 +41,53 @@ void *stk_pop(stack s) { return NULL; } +/* + * Small routines to amalgamate a string from an input source. + */ +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[rs->pos++] = c; + rs->text[rs->pos] = 0; +} +void rdadds(rdstring *rs, wchar_t *p) { + int len = ustrlen(p); + if (rs->pos >= rs->size - len) { + rs->size = rs->pos + len + 128; + rs->text = resize(rs->text, rs->size); + } + ustrcpy(rs->text + rs->pos, p); + rs->pos += len; +} +wchar_t *rdtrim(rdstring *rs) { + rs->text = resize(rs->text, rs->pos + 1); + 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[rs->pos++] = c; + rs->text[rs->pos] = 0; +} +void rdaddsc(rdstringc *rs, char *p) { + int len = strlen(p); + if (rs->pos >= rs->size - len) { + rs->size = rs->pos + len + 128; + rs->text = resize(rs->text, rs->size); + } + strcpy(rs->text + rs->pos, p); + rs->pos += len; +} +char *rdtrimc(rdstringc *rs) { + rs->text = resize(rs->text, rs->pos + 1); + return rs->text; +} + int compare_wordlists(word *a, word *b) { int t; while (a && b) { @@ -84,3 +131,70 @@ int compare_wordlists(word *a, word *b) { else return 0; } + +wrappedline *wrap_para(word *text, int width, int subsequentwidth, + int (*widthfn)(word *)) { + wrappedline *head = NULL, **ptr = &head; + word *spc; + int nspc; + int thiswidth, lastgood; + + while (text) { + wrappedline *w = mknew(wrappedline); + *ptr = w; + ptr = &w->next; + w->next = NULL; + + w->begin = text; + spc = NULL; + nspc = 0; + thiswidth = lastgood = 0; + while (text) { + thiswidth += widthfn(text); + if (text->next && text->next->type == word_WhiteSpace) { + if (thiswidth > width) + break; + spc = text->next; + lastgood = thiswidth; + nspc++; + } + text = text->next; + } + /* + * We've exited this loop on one of three conditions. spc + * might be non-NULL and we've overflowed: we have broken + * the paragraph there. spc might be NULL and text might be + * NULL too: we've reached the end of the paragraph and + * should output the last line. Or text might be non-NULL + * and spc might be NULL: we've got an anomalously long + * line with no spaces we could have broken at. Output it + * anyway as the best we can do. + */ + if (spc && thiswidth > width) { + w->end = spc; + text = spc->next; + w->nspaces = nspc-1; + w->shortfall = width - lastgood; + } else if (!text) { + w->end = NULL; /* no end marker needed */ + w->nspaces = nspc; + w->shortfall = width - thiswidth; + } else { + w->end = text; + text = text->next; + w->nspaces = 0; + w->shortfall = width - thiswidth; + } + width = subsequentwidth; + } + + return head; +} + +void wrap_free(wrappedline *w) { + while (w) { + wrappedline *t = w->next; + sfree(w); + w = t; + } +} |