| 5247 | } |
| 5248 | |
| 5249 | static void |
| 5250 | xo_anchor_stop (xo_handle_t *xop, xo_field_info_t *xfip, |
| 5251 | const char *value, ssize_t vlen) |
| 5252 | { |
| 5253 | if (!XOIF_ISSET(xop, XOIF_ANCHOR)) { |
| 5254 | xo_failure(xop, "no start anchor"); |
| 5255 | return; |
| 5256 | } |
| 5257 | |
| 5258 | XOIF_CLEAR(xop, XOIF_UNITS_PENDING); |
| 5259 | |
| 5260 | ssize_t width = xo_find_width(xop, xfip, value, vlen); |
| 5261 | if (width == 0) |
| 5262 | width = xop->xo_anchor_min_width; |
| 5263 | |
| 5264 | if (width == 0) /* No width given; nothing to do */ |
| 5265 | goto done; |
| 5266 | |
| 5267 | xo_buffer_t *xbp = &xop->xo_data; |
| 5268 | ssize_t start = xop->xo_anchor_offset; |
| 5269 | ssize_t stop = xbp->xb_curp - xbp->xb_bufp; |
| 5270 | ssize_t abswidth = (width > 0) ? width : -width; |
| 5271 | ssize_t blen = abswidth - xop->xo_anchor_columns; |
| 5272 | |
| 5273 | if (blen <= 0) /* Already over width */ |
| 5274 | goto done; |
| 5275 | |
| 5276 | if (abswidth > XO_MAX_ANCHOR_WIDTH) { |
| 5277 | xo_failure(xop, "width over %u are not supported", |
| 5278 | XO_MAX_ANCHOR_WIDTH); |
| 5279 | goto done; |
| 5280 | } |
| 5281 | |
| 5282 | /* Make a suitable padding field and emit it */ |
| 5283 | char *buf = alloca(blen); |
| 5284 | memset(buf, ' ', blen); |
| 5285 | xo_format_content(xop, "padding", NULL, buf, blen, NULL, 0, 0); |
| 5286 | |
| 5287 | if (width < 0) /* Already left justified */ |
| 5288 | goto done; |
| 5289 | |
| 5290 | ssize_t now = xbp->xb_curp - xbp->xb_bufp; |
| 5291 | ssize_t delta = now - stop; |
| 5292 | if (delta <= 0) /* Strange; no output to move */ |
| 5293 | goto done; |
| 5294 | |
| 5295 | /* |
| 5296 | * Now we're in it alright. We've need to insert the padding data |
| 5297 | * we just created (which might be an HTML <div> or text) before |
| 5298 | * the formatted data. We make a local copy, move it and then |
| 5299 | * insert our copy. We know there's room in the buffer, since |
| 5300 | * we're just moving this around. |
| 5301 | */ |
| 5302 | if (delta > blen) |
| 5303 | buf = alloca(delta); /* Expand buffer if needed */ |
| 5304 | |
| 5305 | memcpy(buf, xbp->xb_bufp + stop, delta); |
| 5306 | memmove(xbp->xb_bufp + start + delta, xbp->xb_bufp + start, stop - start); |
no test coverage detected