* Format arguments into our buffer. If a custom formatter has been set, * we use that to do the work; otherwise we vsnprintf(). */
| 933 | * we use that to do the work; otherwise we vsnprintf(). |
| 934 | */ |
| 935 | static ssize_t |
| 936 | xo_vsnprintf (xo_handle_t *xop, xo_buffer_t *xbp, const char *fmt, va_list vap) |
| 937 | { |
| 938 | va_list va_local; |
| 939 | ssize_t rc; |
| 940 | ssize_t left = xbp->xb_size - (xbp->xb_curp - xbp->xb_bufp); |
| 941 | |
| 942 | va_copy(va_local, vap); |
| 943 | |
| 944 | if (xop->xo_formatter) |
| 945 | rc = xop->xo_formatter(xop, xbp->xb_curp, left, fmt, va_local); |
| 946 | else |
| 947 | rc = vsnprintf(xbp->xb_curp, left, fmt, va_local); |
| 948 | |
| 949 | if (rc >= left) { |
| 950 | if (!xo_buf_has_room(xbp, rc)) { |
| 951 | va_end(va_local); |
| 952 | return -1; |
| 953 | } |
| 954 | |
| 955 | /* |
| 956 | * After we call vsnprintf(), the stage of vap is not defined. |
| 957 | * We need to copy it before we pass. Then we have to do our |
| 958 | * own logic below to move it along. This is because the |
| 959 | * implementation can have va_list be a pointer (bsd) or a |
| 960 | * structure (macosx) or anything in between. |
| 961 | */ |
| 962 | |
| 963 | va_end(va_local); /* Reset vap to the start */ |
| 964 | va_copy(va_local, vap); |
| 965 | |
| 966 | left = xbp->xb_size - (xbp->xb_curp - xbp->xb_bufp); |
| 967 | if (xop->xo_formatter) |
| 968 | rc = xop->xo_formatter(xop, xbp->xb_curp, left, fmt, va_local); |
| 969 | else |
| 970 | rc = vsnprintf(xbp->xb_curp, left, fmt, va_local); |
| 971 | } |
| 972 | va_end(va_local); |
| 973 | |
| 974 | return rc; |
| 975 | } |
| 976 | |
| 977 | /* |
| 978 | * Print some data through the handle. |
no test coverage detected