The provided string is consumed!
| 171 | |
| 172 | // The provided string is consumed! |
| 173 | string wordwrap_line(string &s, int width, bool tags, bool indent, int force_indent) |
| 174 | { |
| 175 | ASSERT(width > 0); |
| 176 | |
| 177 | const char *cp0 = s.c_str(); |
| 178 | const char *cp = cp0, *space = 0; |
| 179 | char32_t c; |
| 180 | bool seen_nonspace = false; |
| 181 | |
| 182 | while (int clen = utf8towc(&c, cp)) |
| 183 | { |
| 184 | int cw = wcwidth(c); |
| 185 | if (c == ' ') |
| 186 | { |
| 187 | if (seen_nonspace) |
| 188 | space = cp; |
| 189 | } |
| 190 | else if (c == '\n') |
| 191 | { |
| 192 | space = cp; |
| 193 | break; |
| 194 | } |
| 195 | else |
| 196 | seen_nonspace = true; |
| 197 | |
| 198 | if (c == '<' && tags) |
| 199 | { |
| 200 | ASSERT(cw == 1); |
| 201 | if (cp[1] == '<') // "<<" escape |
| 202 | { |
| 203 | // Note: this must be after a possible wrap, otherwise we could |
| 204 | // split the escape between lines. |
| 205 | cp++; |
| 206 | } |
| 207 | else |
| 208 | { |
| 209 | cw = 0; |
| 210 | // Skip the whole tag. |
| 211 | while (*cp != '>') |
| 212 | { |
| 213 | if (!*cp) |
| 214 | { |
| 215 | // Everything so far fitted, report error. |
| 216 | string ret = s + ">"; |
| 217 | s = "<lightred>ERROR: string above had unterminated tag</lightred>"; |
| 218 | return ret; |
| 219 | } |
| 220 | cp++; |
| 221 | } |
| 222 | } |
| 223 | } |
| 224 | |
| 225 | if (cw > width) |
| 226 | break; |
| 227 | |
| 228 | if (cw >= 0) |
| 229 | width -= cw; |
| 230 | cp += clen; |
no test coverage detected