* This is really _re_formatting, since the normal format code has * generated a beautiful string into xo_data, starting at * start_offset. We need to see if it's plural, which means * comma-separated options, or singular. Then we make the appropriate * call to d[n]gettext() to get the locale-based version. Note that * both input and output of gettext() this should be UTF-8. */
| 3151 | * both input and output of gettext() this should be UTF-8. |
| 3152 | */ |
| 3153 | static ssize_t |
| 3154 | xo_format_gettext (xo_handle_t *xop, xo_xff_flags_t flags, |
| 3155 | ssize_t start_offset, ssize_t cols, int need_enc) |
| 3156 | { |
| 3157 | xo_buffer_t *xbp = &xop->xo_data; |
| 3158 | |
| 3159 | if (!xo_buf_has_room(xbp, 1)) |
| 3160 | return cols; |
| 3161 | |
| 3162 | xbp->xb_curp[0] = '\0'; /* NUL-terminate the input string */ |
| 3163 | |
| 3164 | char *cp = xbp->xb_bufp + start_offset; |
| 3165 | ssize_t len = xbp->xb_curp - cp; |
| 3166 | const char *newstr = NULL; |
| 3167 | |
| 3168 | /* |
| 3169 | * The plural flag asks us to look backwards at the last numeric |
| 3170 | * value rendered and disect the string into two pieces. |
| 3171 | */ |
| 3172 | if (flags & XFF_GT_PLURAL) { |
| 3173 | int n = xo_buf_find_last_number(xbp, start_offset); |
| 3174 | char *two = memchr(cp, (int) ',', len); |
| 3175 | if (two == NULL) { |
| 3176 | xo_failure(xop, "no comma in plural gettext field: '%s'", cp); |
| 3177 | return cols; |
| 3178 | } |
| 3179 | |
| 3180 | if (two == cp) { |
| 3181 | xo_failure(xop, "nothing before comma in plural gettext " |
| 3182 | "field: '%s'", cp); |
| 3183 | return cols; |
| 3184 | } |
| 3185 | |
| 3186 | if (two == xbp->xb_curp) { |
| 3187 | xo_failure(xop, "nothing after comma in plural gettext " |
| 3188 | "field: '%s'", cp); |
| 3189 | return cols; |
| 3190 | } |
| 3191 | |
| 3192 | *two++ = '\0'; |
| 3193 | if (flags & XFF_GT_FIELD) { |
| 3194 | newstr = xo_dngettext(xop, cp, two, n); |
| 3195 | } else { |
| 3196 | /* Don't do a gettext() look up, just get the plural form */ |
| 3197 | newstr = (n == 1) ? cp : two; |
| 3198 | } |
| 3199 | |
| 3200 | /* |
| 3201 | * If we returned the first string, optimize a bit by |
| 3202 | * backing up over comma |
| 3203 | */ |
| 3204 | if (newstr == cp) { |
| 3205 | xbp->xb_curp = two - 1; /* One for comma */ |
| 3206 | /* |
| 3207 | * If the caller wanted UTF8, we're done; nothing changed, |
| 3208 | * but we need to count the columns used. |
| 3209 | */ |
| 3210 | if (need_enc == XF_ENC_UTF8) |
no test coverage detected