// ospad -- ostream padding members
#include <string.h>
#include <ostream>
static _Bool do_rep(streambuf *sb, char c, int n)
{ //put repeated char
while (0 <= --n)
if (sb->sputc(c) == EOF)
return (0);
return (1);
}
inline_Bool rep(streambuf *sb, char c, int n)
{ // put repeated char, if any
return (0 < n ? do_rep(sb, c, n) : 1);
}
inline _Bool send(streambuf *sb, const char *s, int n)
{ // put char sequence, if any
return (n <= 0 || sb->sputn(s, n) == n ? 1 : 0);
}
void ostream::_Pad(const char *code, char *s, int n)
{ // pad with fill char as needed
_Bool ok = 1;
int ni, np, nz;
const char *sf;
const void *sv;
if (code[1] != '.' || (nz = precision() - _Pr()) <= 0)
nz = 0, sf = s + n;
else if ((sv = memchr((const void *)s, 'e', n)) != 0
|| (sv = memchr((const void *)s, 'E', n)) != 0)
sf = (const char *)sv;
else
sf = s + n;
ni = sf - s;
if (width() == 0 || (np = width() - n - nz) < 0)
np=0;
if ((flags() & adjustfield) == right)
{ // put leading fill
if (!rep(rdbuf(), fill(), np)
|| !send(rdbuf(), s, ni)
|| !rep(rdbuf(), '0', nz)
|| !send(rdbuf(), sf, n - ni))
ok = 0;
}
else if ((flags() & adjustfield) != internal)
{ // put trailing fill
if (!send(rdbuf(), s, ni)
||!rep(rdbuf(), '0', nz)
|| !send(rdbuf(), sf, n - ni)
|| !rep(rdbuf(), fill(), np))
ok = 0;
}
else if (code[0] == 'B' && code[3] == 'x' && 2 <= n
&& (s[1] == 'x' || s[1] == 'X'))
{ // put internal fill after 0x or 0X
if (!send(rdbuf(), s, 2)
|| !rep(rdbuf(), fill(), np)
|| !send(rdbuf(), s + 2, ni - 2))
ok = 0;
}
else if (0 < n && s[0] == '-' || s[0] == '+'))
{ // put internal fill after + or -
if (!send(rdbuf(), s, 1)
|| !rep(rdbuf(), fill(), np)
|| !send(rdbuf(), s + 1, ni - 1)
|| !rep(rdbuf(), '0', nz)
|| !send(rdbuf(), sf, n - ni - 1))
ok = 0;
}
else
{ // put internal fill as leading fill
if (!rep(rdbuf(), fill(), np)
|| !send(rdbuf(), s, ni)
|| !rep(rdbuf(), '0', nz)
|| !send(rdbuf(), sf, n - ni))
ok = 0;
}
width(0);
if (!ok)
setstate(badbit);
}
int ostream::_Pr()
{ // get bounded precision
return (precision() <= 0 && !(flags() & fixed) ? 6
:_MAX_SIG_DIG < precision() ? _MAX_SIG_DIG
: precision());
}