* Emit a set of fields. This is really the core of libxo. */
| 6282 | * Emit a set of fields. This is really the core of libxo. |
| 6283 | */ |
| 6284 | static ssize_t |
| 6285 | xo_do_emit_fields (xo_handle_t *xop, xo_field_info_t *fields, |
| 6286 | unsigned max_fields, const char *fmt) |
| 6287 | { |
| 6288 | int gettext_inuse = 0; |
| 6289 | int gettext_changed = 0; |
| 6290 | int gettext_reordered = 0; |
| 6291 | unsigned ftype; |
| 6292 | xo_xff_flags_t flags; |
| 6293 | xo_field_info_t *new_fields = NULL; |
| 6294 | xo_field_info_t *xfip; |
| 6295 | unsigned field; |
| 6296 | ssize_t rc = 0; |
| 6297 | |
| 6298 | int flush = XOF_ISSET(xop, XOF_FLUSH); |
| 6299 | int flush_line = XOF_ISSET(xop, XOF_FLUSH_LINE); |
| 6300 | char *new_fmt = NULL; |
| 6301 | |
| 6302 | if (XOIF_ISSET(xop, XOIF_REORDER) || xo_style(xop) == XO_STYLE_ENCODER) |
| 6303 | flush_line = 0; |
| 6304 | |
| 6305 | /* |
| 6306 | * Some overhead for gettext; if the fields in the msgstr returned |
| 6307 | * by gettext are reordered, then we need to record start and end |
| 6308 | * for each field. We'll go ahead and render the fields in the |
| 6309 | * normal order, but later we can then reconstruct the reordered |
| 6310 | * fields using these fstart/fend values. |
| 6311 | */ |
| 6312 | unsigned flimit = max_fields * 2; /* Pessimistic limit */ |
| 6313 | unsigned min_fstart = flimit - 1; |
| 6314 | unsigned max_fend = 0; /* Highest recorded fend[] entry */ |
| 6315 | ssize_t fstart[flimit]; |
| 6316 | bzero(fstart, flimit * sizeof(fstart[0])); |
| 6317 | ssize_t fend[flimit]; |
| 6318 | bzero(fend, flimit * sizeof(fend[0])); |
| 6319 | |
| 6320 | for (xfip = fields, field = 0; field < max_fields && xfip->xfi_ftype; |
| 6321 | xfip++, field++) { |
| 6322 | ftype = xfip->xfi_ftype; |
| 6323 | flags = xfip->xfi_flags; |
| 6324 | |
| 6325 | /* Record field start offset */ |
| 6326 | if (gettext_reordered) { |
| 6327 | fstart[field] = xo_buf_offset(&xop->xo_data); |
| 6328 | if (min_fstart > field) |
| 6329 | min_fstart = field; |
| 6330 | } |
| 6331 | |
| 6332 | const char *content = xfip->xfi_content; |
| 6333 | ssize_t clen = xfip->xfi_clen; |
| 6334 | |
| 6335 | if (flags & XFF_ARGUMENT) { |
| 6336 | /* |
| 6337 | * Argument flag means the content isn't given in the descriptor, |
| 6338 | * but as a UTF-8 string ('const char *') argument in xo_vap. |
| 6339 | */ |
| 6340 | content = va_arg(xop->xo_vap, char *); |
| 6341 | clen = content ? strlen(content) : 0; |
no test coverage detected