* Format a "humanized" value for a numeric, meaning something nice * like "44M" instead of "44470272". We autoscale, choosing the * most appropriate value for K/M/G/T/P/E based on the value given. */
| 3745 | * most appropriate value for K/M/G/T/P/E based on the value given. |
| 3746 | */ |
| 3747 | static void |
| 3748 | xo_format_humanize (xo_handle_t *xop, xo_buffer_t *xbp, |
| 3749 | xo_humanize_save_t *savep, xo_xff_flags_t flags) |
| 3750 | { |
| 3751 | if (XOF_ISSET(xop, XOF_NO_HUMANIZE)) |
| 3752 | return; |
| 3753 | |
| 3754 | ssize_t end_offset = xbp->xb_curp - xbp->xb_bufp; |
| 3755 | if (end_offset == savep->xhs_offset) /* Huh? Nothing to render */ |
| 3756 | return; |
| 3757 | |
| 3758 | /* |
| 3759 | * We have a string that's allegedly a number. We want to |
| 3760 | * humanize it, which means turning it back into a number |
| 3761 | * and calling xo_humanize_number on it. |
| 3762 | */ |
| 3763 | uint64_t value; |
| 3764 | char *ep; |
| 3765 | |
| 3766 | xo_buf_append(xbp, "", 1); /* NUL-terminate it */ |
| 3767 | |
| 3768 | value = strtoull(xbp->xb_bufp + savep->xhs_offset, &ep, 0); |
| 3769 | if (!(value == ULLONG_MAX && errno == ERANGE) |
| 3770 | && (ep != xbp->xb_bufp + savep->xhs_offset)) { |
| 3771 | /* |
| 3772 | * There are few values where humanize_number needs |
| 3773 | * more bytes than the original value. I've used |
| 3774 | * 10 as a rectal number to cover those scenarios. |
| 3775 | */ |
| 3776 | if (xo_buf_has_room(xbp, 10)) { |
| 3777 | xbp->xb_curp = xbp->xb_bufp + savep->xhs_offset; |
| 3778 | |
| 3779 | ssize_t rc; |
| 3780 | ssize_t left = (xbp->xb_bufp + xbp->xb_size) - xbp->xb_curp; |
| 3781 | int hn_flags = HN_NOSPACE; /* On by default */ |
| 3782 | |
| 3783 | if (flags & XFF_HN_SPACE) |
| 3784 | hn_flags &= ~HN_NOSPACE; |
| 3785 | |
| 3786 | if (flags & XFF_HN_DECIMAL) |
| 3787 | hn_flags |= HN_DECIMAL; |
| 3788 | |
| 3789 | if (flags & XFF_HN_1000) |
| 3790 | hn_flags |= HN_DIVISOR_1000; |
| 3791 | |
| 3792 | rc = xo_humanize(xbp->xb_curp, left, value, hn_flags); |
| 3793 | if (rc > 0) { |
| 3794 | xbp->xb_curp += rc; |
| 3795 | xop->xo_columns = savep->xhs_columns + rc; |
| 3796 | xop->xo_anchor_columns = savep->xhs_anchor_columns + rc; |
| 3797 | } |
| 3798 | } |
| 3799 | } |
| 3800 | } |
| 3801 | |
| 3802 | /* |
| 3803 | * Convenience function that either append a fixed value (if one is |
no test coverage detected