Annotation of researchv10no/cmd/cfront/ooptcfront/doprint.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1988 Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms are permitted
        !             6:  * provided that the above copyright notice and this paragraph are
        !             7:  * duplicated in all such forms and that any documentation,
        !             8:  * advertising materials, and other materials related to such
        !             9:  * distribution and use acknowledge that the software was developed
        !            10:  * by the University of California, Berkeley.  The name of the
        !            11:  * University may not be used to endorse or promote products derived
        !            12:  * from this software without specific prior written permission.
        !            13:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
        !            14:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
        !            15:  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            16:  */
        !            17: 
        !            18: /*
        !            19:     $Header: /usr2/odi/lib.src/RCS/doprint.C,v 1.3 89/09/19 12:00:34 benson Exp $
        !            20: 
        !            21:     Copyright (c) 1989 by Object Design, Inc., Burlington, Mass.
        !            22:     All rights reserved.
        !            23: 
        !            24: */
        !            25: 
        !            26: #if defined(LIBC_SCCS) && !defined(lint)
        !            27: static char sccsid[] = "@(#)doprnt.c   5.35 (Berkeley) 6/27/88";
        !            28: #endif /* LIBC_SCCS and not lint */
        !            29: 
        !            30: #include <sys/types.h>
        !            31: #include <stdarg.h>
        !            32: #include <ctype.h>
        !            33: #include <iostream.h>
        !            34: #include <strstream.h>
        !            35: #include <memory.h>
        !            36: #include <math.h>
        !            37: #include <string.h>
        !            38: #include <print_self.H>
        !            39: 
        !            40: /* 11-bit exponent (VAX G floating point) is 308 decimal digits */
        !            41: #define        MAXEXP          308
        !            42: /* 128 bit fraction takes up 39 decimal digits; max reasonable precision */
        !            43: #define        MAXFRACT        39
        !            44: 
        !            45: #define        DEFPREC         6
        !            46: 
        !            47: #define        BUF             (MAXEXP+MAXFRACT+1)     /* + decimal point */
        !            48: 
        !            49: #define        PUTC(ch)        (void) fp.put(ch)
        !            50: 
        !            51: #define        ARG() \
        !            52:        _ulong = flags&LONGINT ? va_arg(argp, long) : \
        !            53:            flags&SHORTINT ? va_arg(argp, short) : va_arg(argp, int);
        !            54: 
        !            55: #define        todigit(c)      ((c) - '0')
        !            56: #define        tochar(n)       ((n) + '0')
        !            57: 
        !            58: #define        LONGINT         0x01            /* long integer */
        !            59: #define        LONGDBL         0x02            /* long double; unimplemented */
        !            60: #define        SHORTINT        0x04            /* short integer */
        !            61: #define        ALT             0x08            /* alternate form */
        !            62: #define        LADJUST         0x10            /* left adjustment */
        !            63: #define        ZEROPAD         0x20            /* zero (as opposed to blank) pad */
        !            64: #define        HEXPREFIX       0x40            /* add 0x or 0X prefix */
        !            65: 
        !            66: 
        !            67: static char * exponent(char * p, int exp, u_char fmtch);
        !            68: static char * round(double fract,
        !            69:                    int * exp,
        !            70:                    char * start,
        !            71:                    char * end,
        !            72:                    char ch,
        !            73:                    char * signp);
        !            74: 
        !            75: 
        !            76: 
        !            77: static
        !            78: cvt(double number,
        !            79:     register int prec,
        !            80:     int flags,
        !            81:     char * signp,
        !            82:     u_char fmtch,
        !            83:     char * startp,
        !            84:     char * endp)
        !            85: {
        !            86:     register char *p, *t;
        !            87:     register double fract;
        !            88:     int dotrim, expcnt, gformat;
        !            89:     double integer, tmp;
        !            90: 
        !            91:     dotrim = expcnt = gformat = 0;
        !            92:     fract = modf(number, &integer);
        !            93: 
        !            94:     /* get an extra slot for rounding. */
        !            95:     t = ++startp;
        !            96: 
        !            97:     /*
        !            98:        * get integer portion of number; put into the end of the buffer; the
        !            99:            * .01 is added for modf(356.0 / 10, &integer) returning .59999999...
        !           100:                */
        !           101:     for (p = endp - 1; integer; ++expcnt) {
        !           102:        tmp = modf(integer / 10, &integer);
        !           103:        *p-- = tochar((int)((tmp + .01) * 10));
        !           104:     }
        !           105:     switch(fmtch) {
        !           106:     case 'f':
        !           107:        /* reverse integer into beginning of buffer */
        !           108:        if (expcnt)
        !           109:            for (; ++p < endp; *t++ = *p);
        !           110:        else
        !           111:            *t++ = '0';
        !           112:        /*
        !           113:            * if precision required or alternate flag set, add in a
        !           114:                * decimal point.
        !           115:                    */
        !           116:        if (prec || flags&ALT)
        !           117:            *t++ = '.';
        !           118:        /* if requires more precision and some fraction left */
        !           119:        if (fract) {
        !           120:            if (prec)
        !           121:                do {
        !           122:                    fract = modf(fract * 10, &tmp);
        !           123:                    *t++ = tochar((int)tmp);
        !           124:                } while (--prec && fract);
        !           125:            if (fract)
        !           126:                startp = round(fract, (int *)NULL, startp,
        !           127:                               t - 1, (char)0, signp);
        !           128:        }
        !           129:        for (; prec--; *t++ = '0');
        !           130:        break;
        !           131:     case 'e':
        !           132:     case 'E':
        !           133:       eformat: if (expcnt) {
        !           134:          *t++ = *++p;
        !           135:          if (prec || flags&ALT)
        !           136:              *t++ = '.';
        !           137:          /* if requires more precision and some integer left */
        !           138:          for (; prec && ++p < endp; --prec)
        !           139:              *t++ = *p;
        !           140:          /*
        !           141:              * if done precision and more of the integer component,
        !           142:          * round using it; adjust fract so we don't re-round
        !           143:              * later.
        !           144:                  */
        !           145:          if (!prec && ++p < endp) {
        !           146:              fract = 0;
        !           147:              startp = round((double)0, &expcnt, startp,
        !           148:                             t - 1, *p, signp);
        !           149:          }
        !           150:          /* adjust expcnt for digit in front of decimal */
        !           151:          --expcnt;
        !           152:       }
        !           153:        /* until first fractional digit, decrement exponent */
        !           154:       else if (fract) {
        !           155:          /* adjust expcnt for digit in front of decimal */
        !           156:          for (expcnt = -1;; --expcnt) {
        !           157:              fract = modf(fract * 10, &tmp);
        !           158:              if (tmp)
        !           159:                  break;
        !           160:          }
        !           161:          *t++ = tochar((int)tmp);
        !           162:          if (prec || flags&ALT)
        !           163:              *t++ = '.';
        !           164:       }
        !           165:       else {
        !           166:          *t++ = '0';
        !           167:          if (prec || flags&ALT)
        !           168:              *t++ = '.';
        !           169:       }
        !           170:        /* if requires more precision and some fraction left */
        !           171:        if (fract) {
        !           172:            if (prec)
        !           173:                do {
        !           174:                    fract = modf(fract * 10, &tmp);
        !           175:                    *t++ = tochar((int)tmp);
        !           176:                } while (--prec && fract);
        !           177:            if (fract)
        !           178:                startp = round(fract, &expcnt, startp,
        !           179:                               t - 1, (char)0, signp);
        !           180:        }
        !           181:        /* if requires more precision */
        !           182:        for (; prec--; *t++ = '0');
        !           183: 
        !           184:        /* unless alternate flag, trim any g/G format trailing 0's */
        !           185:        if (gformat && !(flags&ALT)) {
        !           186:            while (t > startp && *--t == '0');
        !           187:            if (*t == '.')
        !           188:                --t;
        !           189:            ++t;
        !           190:        }
        !           191:        t = exponent(t, expcnt, fmtch);
        !           192:        break;
        !           193:     case 'g':
        !           194:     case 'G':
        !           195:        /* a precision of 0 is treated as a precision of 1. */
        !           196:        if (!prec)
        !           197:            ++prec;
        !           198:        /*
        !           199:            * ``The style used depends on the value converted; style e
        !           200:                * will be used only if the exponent resulting from the
        !           201:                    * conversion is less than -4 or greater than the precision.''
        !           202:                        *       -- ANSI X3J11
        !           203:                            */
        !           204:        if (expcnt > prec || !expcnt && fract && fract < .0001) {
        !           205:            /*
        !           206:                * g/G format counts "significant digits, not digits of
        !           207:                         * precision; for the e/E format, this just causes an
        !           208:                         * off-by-one problem, i.e. g/G considers the digit
        !           209:                         * before the decimal point significant and e/E doesn't
        !           210:                         * count it as precision."
        !           211:                             */
        !           212:            --prec;
        !           213:            fmtch -= 2;         /* G->E, g->e */
        !           214:            gformat = 1;
        !           215:            goto eformat;
        !           216:        }
        !           217:        /*
        !           218:            * reverse integer into beginning of buffer,
        !           219:        * note, decrement precision
        !           220:            */
        !           221:        if (expcnt)
        !           222:            for (; ++p < endp; *t++ = *p, --prec);
        !           223:        else
        !           224:            *t++ = '0';
        !           225:        /*
        !           226:            * if precision required or alternate flag set, add in a
        !           227:                * decimal point.  If no digits yet, add in leading 0.
        !           228:                    */
        !           229:        if (prec || flags&ALT) {
        !           230:            dotrim = 1;
        !           231:            *t++ = '.';
        !           232:        }
        !           233:        else
        !           234:            dotrim = 0;
        !           235:        /* if requires more precision and some fraction left */
        !           236:        if (fract) {
        !           237:            if (prec) {
        !           238:                do {
        !           239:                    fract = modf(fract * 10, &tmp);
        !           240:                    *t++ = tochar((int)tmp);
        !           241:                } while(!tmp);
        !           242:                while (--prec && fract) {
        !           243:                    fract = modf(fract * 10, &tmp);
        !           244:                    *t++ = tochar((int)tmp);
        !           245:                }
        !           246:            }
        !           247:            if (fract)
        !           248:                startp = round(fract, (int *)NULL, startp,
        !           249:                               t - 1, (char)0, signp);
        !           250:        }
        !           251:        /* alternate format, adds 0's for precision, else trim 0's */
        !           252:        if (flags&ALT)
        !           253:            for (; prec--; *t++ = '0');
        !           254:        else if (dotrim) {
        !           255:            while (t > startp && *--t == '0');
        !           256:            if (*t != '.')
        !           257:                ++t;
        !           258:        }
        !           259:     }
        !           260:     return(t - startp);
        !           261: }
        !           262: 
        !           263: static char * round(double fract,
        !           264:                    int * exp,
        !           265:                    char * start,
        !           266:                    char * end,
        !           267:                    char ch,
        !           268:                    char * signp)
        !           269: {
        !           270:     double tmp;
        !           271: 
        !           272:     if (fract)
        !           273:        (void)modf(fract * 10, &tmp);
        !           274:     else
        !           275:        tmp = todigit(ch);
        !           276:     if (tmp > 4)
        !           277:        for (;; --end) {
        !           278:            if (*end == '.')
        !           279:                --end;
        !           280:            if (++*end <= '9')
        !           281:                break;
        !           282:            *end = '0';
        !           283:            if (end == start) {
        !           284:                if (exp) {      /* e/E; increment exponent */
        !           285:                    *end = '1';
        !           286:                    ++*exp;
        !           287:                }
        !           288:                else {          /* f; add extra digit */
        !           289:                    *--end = '1';
        !           290:                    --start;
        !           291:                }
        !           292:                break;
        !           293:            }
        !           294:        }
        !           295:     /* ``"%.3f", (double)-0.0004'' gives you a negative 0. */
        !           296:     else if (*signp == '-')
        !           297:        for (;; --end) {
        !           298:            if (*end == '.')
        !           299:                --end;
        !           300:            if (*end != '0')
        !           301:                break;
        !           302:            if (end == start)
        !           303:                *signp = 0;
        !           304:        }
        !           305:     return(start);
        !           306: }
        !           307: 
        !           308: static char * exponent(char * p, int exp, u_char fmtch)
        !           309: {
        !           310:     register char *t;
        !           311:     char expbuf[MAXEXP];
        !           312: 
        !           313:     *p++ = fmtch;
        !           314:     if (exp < 0) {
        !           315:        exp = -exp;
        !           316:        *p++ = '-';
        !           317:     }
        !           318:     else
        !           319:        *p++ = '+';
        !           320:     t = expbuf + MAXEXP;
        !           321:     if (exp > 9) {
        !           322:        do {
        !           323:            *--t = tochar(exp % 10);
        !           324:        } while ((exp /= 10) > 9);
        !           325:        *--t = tochar(exp);
        !           326:        for (; t < expbuf + MAXEXP; *p++ = *t++);
        !           327:     }
        !           328:     else {
        !           329:        *p++ = '0';
        !           330:        *p++ = tochar(exp);
        !           331:     }
        !           332:     return(p);
        !           333: }
        !           334: 
        !           335: int vostream_printf(const char *fmt0, va_list argp, ostream& fp)
        !           336: {
        !           337:     register const u_char *fmt;        /* format string */
        !           338:     register int ch;           /* character from fmt */
        !           339:     register int cnt;          /* return value accumulator */
        !           340:     register int n;            /* random handy integer */
        !           341:     register char *t;          /* buffer pointer */
        !           342:     double _double;            /* double precision arguments %[eEfgG] */
        !           343:     u_long _ulong;             /* integer arguments %[diouxX] */
        !           344:     int base;                  /* base for [diouxX] conversion */
        !           345:     int dprec;                 /* decimal precision in [diouxX] */
        !           346:     int fieldsz;               /* field size expanded by sign, etc */
        !           347:     int flags;                 /* flags as above */
        !           348:     int fpprec;                        /* `extra' floating precision in [eEfgG] */
        !           349:     int prec;                  /* precision from format (%.3d), or -1 */
        !           350:     int realsz;                        /* field size expanded by decimal precision */
        !           351:     int size;                  /* size of converted field or string */
        !           352:     int width;                 /* width from format (%8d), or 0 */
        !           353:     char sign;                 /* sign prefix (' ', '+', '-', or \0) */
        !           354:     char softsign;             /* temporary negative sign for floats */
        !           355:     char *digs;                        /* digits for [diouxX] conversion */
        !           356:     char buf[BUF];             /* space for %c, %[diouxX], %[eEfgG] */
        !           357: 
        !           358:     fmt = (const u_char *)fmt0;
        !           359:     digs = "0123456789abcdef";
        !           360:     for (cnt = 0;; ++fmt) {
        !           361:        for (;(ch = *fmt) && ch != '%'; ++cnt, ++fmt)
        !           362:            PUTC(ch);
        !           363:        if (!ch)return (cnt);
        !           364: 
        !           365:        flags = 0; dprec = 0; fpprec = 0; width = 0;
        !           366:        prec = -1;
        !           367:        sign = '\0';
        !           368: 
        !           369:       rflag:           switch (*++fmt) {
        !           370:        case ' ':
        !           371:          /*
        !           372:           * ``If the space and + flags both appear, the space
        !           373:           * flag will be ignored.''
        !           374:           *    -- ANSI X3J11
        !           375:           */
        !           376:          if (!sign)
        !           377:              sign = ' ';
        !           378:          goto rflag;
        !           379:        case '#':
        !           380:          flags |= ALT;
        !           381:          goto rflag;
        !           382:        case '*':
        !           383:          /*
        !           384:           * ``A negative field width argument is taken as a
        !           385:           * - flag followed by a  positive field width.''
        !           386:           *    -- ANSI X3J11
        !           387:           * They don't exclude field widths read from args.
        !           388:           */
        !           389:          if ((width = va_arg(argp, int)) >= 0)
        !           390:              goto rflag;
        !           391:          width = -width;
        !           392:          /* FALLTHROUGH */
        !           393:        case '-':
        !           394:          flags |= LADJUST;
        !           395:          goto rflag;
        !           396:        case '+':
        !           397:          sign = '+';
        !           398:          goto rflag;
        !           399:        case '.':
        !           400:          if (*++fmt == '*')
        !           401:              n = va_arg(argp, int);
        !           402:          else {
        !           403:              n = 0;
        !           404:              while (isascii(*fmt) && isdigit(*fmt))
        !           405:                  n = 10 * n + todigit(*fmt++);
        !           406:              --fmt;
        !           407:          }
        !           408:          prec = n < 0 ? -1 : n;
        !           409:          goto rflag;
        !           410:        case '0':
        !           411:          /*
        !           412:           * ``Note that 0 is taken as a flag, not as the
        !           413:           * beginning of a field width.''
        !           414:           *    -- ANSI X3J11
        !           415:           */
        !           416:          flags |= ZEROPAD;
        !           417:          goto rflag;
        !           418:        case '1': case '2': case '3': case '4':
        !           419:        case '5': case '6': case '7': case '8': case '9':
        !           420:          n = 0;
        !           421:          do {
        !           422:              n = 10 * n + todigit(*fmt);
        !           423:          } while (isascii(*++fmt) && isdigit(*fmt));
        !           424:          width = n;
        !           425:          --fmt;
        !           426:          goto rflag;
        !           427:        case 'L':
        !           428:          flags |= LONGDBL;
        !           429:          goto rflag;
        !           430:        case 'h':
        !           431:          flags |= SHORTINT;
        !           432:          goto rflag;
        !           433:        case 'l':
        !           434:          flags |= LONGINT;
        !           435:          goto rflag;
        !           436:        case 'c':
        !           437:          *(t = buf) = va_arg(argp, int);
        !           438:          size = 1;
        !           439:          sign = '\0';
        !           440:          goto pforw;
        !           441:        case 'D':
        !           442:          flags |= LONGINT;
        !           443:          /*FALLTHROUGH*/
        !           444:        case 'd':
        !           445:        case 'i':
        !           446:          ARG();
        !           447:          if ((long)_ulong < 0) {
        !           448:              _ulong = -_ulong;
        !           449:              sign = '-';
        !           450:          }
        !           451:          base = 10;
        !           452:          goto number;
        !           453:        case 'e':
        !           454:        case 'E':
        !           455:        case 'f':
        !           456:        case 'g':
        !           457:        case 'G':
        !           458:          _double = va_arg(argp, double);
        !           459:          /*
        !           460:           * don't do unrealistic precision; just pad it with
        !           461:           * zeroes later, so buffer size stays rational.
        !           462:           */
        !           463:          if (prec > MAXFRACT) {
        !           464:              if (*fmt != 'g' && *fmt != 'G' || (flags&ALT))
        !           465:                  fpprec = prec - MAXFRACT;
        !           466:              prec = MAXFRACT;
        !           467:          }
        !           468:          else if (prec == -1)
        !           469:              prec = DEFPREC;
        !           470:          /*
        !           471:           * softsign avoids negative 0 if _double is < 0 and
        !           472:           * no significant digits will be shown
        !           473:           */
        !           474:          if (_double < 0) {
        !           475:              softsign = '-';
        !           476:              _double = -_double;
        !           477:          }
        !           478:          else
        !           479:              softsign = 0;
        !           480:          /*
        !           481:           * cvt may have to round up past the "start" of the
        !           482:           * buffer, i.e. ``intf("%.2f", (double)9.999);'';
        !           483:           * if the first char isn't NULL, it did.
        !           484:           */
        !           485:          *buf = NULL;
        !           486:          size = cvt(_double, prec, flags, &softsign, *fmt, buf,
        !           487:                     buf + sizeof(buf));
        !           488:          if (softsign)
        !           489:              sign = '-';
        !           490:          t = *buf ? buf : buf + 1;
        !           491:          goto pforw;
        !           492:        case 'n':
        !           493:          if (flags & LONGINT)
        !           494:              *va_arg(argp, long *) = cnt;
        !           495:          else if (flags & SHORTINT)
        !           496:              *va_arg(argp, short *) = cnt;
        !           497:          else
        !           498:              *va_arg(argp, int *) = cnt;
        !           499:          break;
        !           500:        case 'O':
        !           501:          flags |= LONGINT;
        !           502:          /*FALLTHROUGH*/
        !           503:        case 'o':
        !           504:          ARG();
        !           505:          base = 8;
        !           506:          goto nosign;
        !           507:        case 'T':               // Type
        !           508:          {
        !           509:              streampos cur_pos;
        !           510:              streampos new_pos;
        !           511: 
        !           512:              cur_pos = fp.tellp();
        !           513: 
        !           514:              _Print_self * obj = va_arg (argp, _Print_self *);
        !           515:              obj->print_self (fp);
        !           516: 
        !           517:              new_pos = fp.tellp();
        !           518: 
        !           519:              cnt += new_pos - cur_pos;
        !           520:          }
        !           521:          break;
        !           522: 
        !           523:        case 'p':
        !           524:          /*
        !           525:           * ``The argument shall be a pointer to void.  The
        !           526:           * value of the pointer is converted to a sequence
        !           527:           * of printable characters, in an implementation-
        !           528:           * defined manner.''
        !           529:           *    -- ANSI X3J11
        !           530:           */
        !           531:          /* NOSTRICT */
        !           532:          _ulong = (u_long)va_arg(argp, void *);
        !           533:          base = 16;
        !           534:          goto nosign;
        !           535:        case 's':
        !           536:          if (!(t = va_arg(argp, char *)))
        !           537:              t = "(null)";
        !           538:          if (prec >= 0) {
        !           539:              /*
        !           540:               * can't use strlen; can only look for the
        !           541:               * NUL in the first `prec' characters, and
        !           542:               * strlen() will go further.
        !           543:               */
        !           544:              char *p;
        !           545: 
        !           546:              if (p = (char *) memchr(t, 0, prec)) {
        !           547:                  size = p - t;
        !           548:                  if (size > prec)
        !           549:                      size = prec;
        !           550:              } else
        !           551:                  size = prec;
        !           552:          } else
        !           553:              size = strlen(t);
        !           554:          sign = '\0';
        !           555:          goto pforw;
        !           556:        case 'U':
        !           557:          flags |= LONGINT;
        !           558:          /*FALLTHROUGH*/
        !           559:        case 'u':
        !           560:          ARG();
        !           561:          base = 10;
        !           562:          goto nosign;
        !           563:        case 'X':
        !           564:          digs = "0123456789ABCDEF";
        !           565:          /* FALLTHROUGH */
        !           566:        case 'x':
        !           567:          ARG();
        !           568:          base = 16;
        !           569:          /* leading 0x/X only if non-zero */
        !           570:          if (flags & ALT && _ulong != 0)
        !           571:              flags |= HEXPREFIX;
        !           572: 
        !           573:          /* unsigned conversions */
        !           574:        nosign:                 sign = '\0';
        !           575:          /*
        !           576:           * ``... diouXx conversions ... if a precision is
        !           577:           * specified, the 0 flag will be ignored.''
        !           578:           *    -- ANSI X3J11
        !           579:           */
        !           580:        number:                 if ((dprec = prec) >= 0)
        !           581:            flags &= ~ZEROPAD;
        !           582: 
        !           583:          /*
        !           584:           * ``The result of converting a zero value with an
        !           585:           * explicit precision of zero is no characters.''
        !           586:           *    -- ANSI X3J11
        !           587:           */
        !           588:          t = buf + BUF;
        !           589:          if (_ulong != 0 || prec != 0) {
        !           590:              do {
        !           591:                  *--t = digs[_ulong % base];
        !           592:                  _ulong /= base;
        !           593:              } while (_ulong);
        !           594:              digs = "0123456789abcdef";
        !           595:              if (flags & ALT && base == 8 && *t != '0')
        !           596:                  *--t = '0';   /* octal leading 0 */
        !           597:          }
        !           598:          size = buf + BUF - t;
        !           599: 
        !           600:        pforw:
        !           601:          /*
        !           602:           * All reasonable formats wind up here.  At this point,
        !           603:           * `t' points to a string which (if not flags&LADJUST)
        !           604:           * should be padded out to `width' places.  If
        !           605:           * flags&ZEROPAD, it should first be prefixed by any
        !           606:           * sign or other prefix; otherwise, it should be blank
        !           607:           * padded before the prefix is emitted.  After any
        !           608:           * left-hand padding and prefixing, emit zeroes
        !           609:           * required by a decimal [diouxX] precision, then print
        !           610:           * the string proper, then emit zeroes required by any
        !           611:           * leftover floating precision; finally, if LADJUST,
        !           612:           * pad with blanks.
        !           613:           */
        !           614: 
        !           615:          /*
        !           616:           * compute actual size, so we know how much to pad
        !           617:           * fieldsz excludes decimal prec; realsz includes it
        !           618:           */
        !           619:          fieldsz = size + fpprec;
        !           620:          if (sign)
        !           621:              fieldsz++;
        !           622:          if (flags & HEXPREFIX)
        !           623:              fieldsz += 2;
        !           624:          realsz = dprec > fieldsz ? dprec : fieldsz;
        !           625: 
        !           626:          /* right-adjusting blank padding */
        !           627:          if ((flags & (LADJUST|ZEROPAD)) == 0 && width)
        !           628:              for (n = realsz; n < width; n++)
        !           629:                  PUTC(' ');
        !           630:          /* prefix */
        !           631:          if (sign)
        !           632:              PUTC(sign);
        !           633:          if (flags & HEXPREFIX) {
        !           634:              PUTC('0');
        !           635:              PUTC((char)*fmt);
        !           636:          }
        !           637:          /* right-adjusting zero padding */
        !           638:          if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
        !           639:              for (n = realsz; n < width; n++)
        !           640:                  PUTC('0');
        !           641:          /* leading zeroes from decimal precision */
        !           642:          for (n = fieldsz; n < dprec; n++)
        !           643:              PUTC('0');
        !           644: 
        !           645:          /* the string or number proper */
        !           646: 
        !           647:          fp.write(t, size);
        !           648: 
        !           649:          /* trailing f.p. zeroes */
        !           650:          while (--fpprec >= 0)
        !           651:              PUTC('0');
        !           652:          /* left-adjusting padding (always blank) */
        !           653:          if (flags & LADJUST)
        !           654:              for (n = realsz; n < width; n++)
        !           655:                  PUTC(' ');
        !           656:          /* finally, adjust cnt */
        !           657:          cnt += width > realsz ? width : realsz;
        !           658:          break;
        !           659:        case '\0':              /* "%?" prints ?, unless ? is NULL */
        !           660:          return (cnt);
        !           661:        default:
        !           662:          PUTC(*fmt);
        !           663:          cnt++;
        !           664:       }
        !           665:     }
        !           666:     /* NOTREACHED */
        !           667: }
        !           668: 
        !           669: int ostream_printf(ostream& stream, const char * format ...)
        !           670: {
        !           671:     int ret;
        !           672: 
        !           673:     va_list args;
        !           674:     va_start(args, format);
        !           675:     ret = vostream_printf(format, args, stream);
        !           676:     va_end(args);
        !           677:     return ret;
        !           678: }
        !           679: 
        !           680: // There are intended to be more convienient that stirring up
        !           681: // an strstream by hand.
        !           682: 
        !           683: int printf_to_string (char * string, int length, const char * format ...)
        !           684: {
        !           685:     ostrstream& stream = ostrstream (string, length, (open_mode)ios::app);
        !           686: 
        !           687:     va_list args;
        !           688:     va_start(args, format);
        !           689: 
        !           690:     vostream_printf (format, args, stream);
        !           691: 
        !           692:     va_end(args);
        !           693:     stream.str();
        !           694:     return stream.pcount();
        !           695: }
        !           696: 
        !           697: // caller of this must free() the string that comes back. 
        !           698: 
        !           699: char * printf_to_alloc_string (const char * format ...)
        !           700: {
        !           701:     ostrstream& stream = ostrstream ();
        !           702: 
        !           703:     va_list args;
        !           704:     va_start(args, format);
        !           705: 
        !           706:     vostream_printf (format, args, stream);
        !           707: 
        !           708:     va_end(args);
        !           709:     return stream.str();
        !           710: }
        !           711: 
        !           712: 
        !           713: 
        !           714: 
        !           715: static char rcssrc[] = "$Source: /usr2/odi/lib.src/RCS/doprint.C,v $";
        !           716: static char rcsrev[] = "$Revision: 1.3 $";
        !           717: static char rcsdate[] = "$Date: 89/09/19 12:00:34 $";
        !           718: static char copyright[]="Copyright (c) 1989 by Object Design, Inc., Burlington, Mass.";
        !           719: 
        !           720: 
        !           721: /*
        !           722:    $Log:       doprint.C,v $
        !           723: Revision 1.3  89/09/19  12:00:34  benson
        !           724: Fix a bug in printing numbers that sometimes added garbage.
        !           725: 
        !           726: Revision 1.2  89/05/19  10:46:07  benson
        !           727: fix include path for print_self.
        !           728: 
        !           729: Revision 1.1  89/05/19  10:40:19  benson
        !           730: Initial revision
        !           731: 
        !           732: 
        !           733:    end_log
        !           734: */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.