| 1 | #include "seq.h" |
|---|
| 2 | #include "wrap.h" |
|---|
| 3 | #include "reader.h" |
|---|
| 4 | |
|---|
| 5 | int WrapMode::wrap_pos(const char *str, int wrapCol) const { |
|---|
| 6 | // returns the first position lower equal 'wrapCol' after which splitting |
|---|
| 7 | // is possible (according to separators of WrapMode) |
|---|
| 8 | // |
|---|
| 9 | // returns 'wrapCol' if no such position exists (fallback) |
|---|
| 10 | // |
|---|
| 11 | // throws if WrapMode is disabled |
|---|
| 12 | |
|---|
| 13 | if (!allowed_to_wrap()) throw_errorf(50, "Oversized content - no wrapping allowed here (content='%s')", str); |
|---|
| 14 | |
|---|
| 15 | ca_assert(wrapCol <= (int)strlen(str)); // to short to wrap |
|---|
| 16 | |
|---|
| 17 | const char *wrapAfter = get_seps(); |
|---|
| 18 | ca_assert(wrapAfter); |
|---|
| 19 | int i = wrapCol; |
|---|
| 20 | for (; i >= 0 && !occurs_in(str[i], wrapAfter); --i) {} |
|---|
| 21 | return i >= 0 ? i : wrapCol; |
|---|
| 22 | } |
|---|
| 23 | |
|---|
| 24 | const char *WrapMode::print_return_wrapped(Writer& write, const char * const content, const int len, const int rest_width) const { |
|---|
| 25 | ca_assert(content[len] == '\n'); |
|---|
| 26 | |
|---|
| 27 | if (len<(rest_width+1)) { |
|---|
| 28 | write.out(content); |
|---|
| 29 | return NULp; // no rest |
|---|
| 30 | } |
|---|
| 31 | |
|---|
| 32 | int split_after = wrap_pos(content, rest_width); |
|---|
| 33 | |
|---|
| 34 | ca_assert(split_after>0); |
|---|
| 35 | if (occurs_in(content[split_after], " \n")) split_after--; |
|---|
| 36 | ca_assert(split_after >= 0); |
|---|
| 37 | ca_assert(split_after <= len); |
|---|
| 38 | |
|---|
| 39 | int continue_at = split_after+1; |
|---|
| 40 | while (continue_at < len && occurs_in(content[continue_at], " \n")) continue_at++; |
|---|
| 41 | |
|---|
| 42 | ca_assert(content[split_after] != '\n'); |
|---|
| 43 | fputs_len(content, split_after+1, write); |
|---|
| 44 | write.out('\n'); |
|---|
| 45 | |
|---|
| 46 | ca_assert(content[len] == '\n'); |
|---|
| 47 | ca_assert(len >= continue_at); |
|---|
| 48 | |
|---|
| 49 | return content+continue_at; |
|---|
| 50 | } |
|---|
| 51 | |
|---|
| 52 | void WrapMode::print(Writer& write, const char *first_prefix, const char *other_prefix, const char *content, int max_width) const { |
|---|
| 53 | ca_assert(has_content(content)); |
|---|
| 54 | |
|---|
| 55 | int len = strlen(content)-1; |
|---|
| 56 | int prefix_len = strlen(first_prefix); |
|---|
| 57 | |
|---|
| 58 | write.out(first_prefix); |
|---|
| 59 | const char *rest = print_return_wrapped(write, content, len, max_width-prefix_len); |
|---|
| 60 | |
|---|
| 61 | if (rest) { |
|---|
| 62 | prefix_len = strlen(other_prefix); |
|---|
| 63 | |
|---|
| 64 | while (rest) { |
|---|
| 65 | len -= rest-content; |
|---|
| 66 | content = rest; |
|---|
| 67 | |
|---|
| 68 | write.out(other_prefix); |
|---|
| 69 | rest = print_return_wrapped(write, content, len, max_width-prefix_len); |
|---|
| 70 | } |
|---|
| 71 | } |
|---|
| 72 | } |
|---|
| 73 | |
|---|