Listing 5 The file ospad.c

// 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());
   }