| 327 | */ |
| 328 | |
| 329 | int decimal2string(const decimal_t *from, char *to, int *to_len, |
| 330 | int fixed_precision, int fixed_decimals, |
| 331 | char filler) |
| 332 | { |
| 333 | /* {intg_len, frac_len} output widths; {intg, frac} places in input */ |
| 334 | int len, intg, frac= from->frac, i, intg_len, frac_len, fill; |
| 335 | /* number digits before decimal point */ |
| 336 | int fixed_intg= (fixed_precision ? |
| 337 | (fixed_precision - fixed_decimals) : 0); |
| 338 | int error=E_DEC_OK; |
| 339 | char *s=to; |
| 340 | dec1 *buf, *buf0=from->buf, tmp; |
| 341 | |
| 342 | DBUG_ASSERT(*to_len >= 2+from->sign); |
| 343 | |
| 344 | /* removing leading zeroes */ |
| 345 | buf0= remove_leading_zeroes(from, &intg); |
| 346 | if (unlikely(intg+frac==0)) |
| 347 | { |
| 348 | intg=1; |
| 349 | tmp=0; |
| 350 | buf0=&tmp; |
| 351 | } |
| 352 | |
| 353 | if (!(intg_len= fixed_precision ? fixed_intg : intg)) |
| 354 | intg_len= 1; |
| 355 | frac_len= fixed_precision ? fixed_decimals : frac; |
| 356 | len= from->sign + intg_len + MY_TEST(frac) + frac_len; |
| 357 | if (fixed_precision) |
| 358 | { |
| 359 | if (frac > fixed_decimals) |
| 360 | { |
| 361 | error= E_DEC_TRUNCATED; |
| 362 | frac= fixed_decimals; |
| 363 | } |
| 364 | if (intg > fixed_intg) |
| 365 | { |
| 366 | error= E_DEC_OVERFLOW; |
| 367 | intg= fixed_intg; |
| 368 | } |
| 369 | } |
| 370 | else if (unlikely(len > --*to_len)) /* reserve one byte for \0 */ |
| 371 | { |
| 372 | int j= len - *to_len; /* excess printable chars */ |
| 373 | error= (frac && j <= frac + 1) ? E_DEC_TRUNCATED : E_DEC_OVERFLOW; |
| 374 | |
| 375 | /* |
| 376 | If we need to cut more places than frac is wide, we'll end up |
| 377 | dropping the decimal point as well. Account for this. |
| 378 | */ |
| 379 | if (frac && j >= frac + 1) |
| 380 | j--; |
| 381 | |
| 382 | if (j > frac) |
| 383 | { |
| 384 | intg_len= intg-= j-frac; |
| 385 | frac= 0; |
| 386 | } |
no test coverage detected