Annotation of embedaddon/dhcp/omapip/iscprint.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC")
                      3:  * Copyright (C) 1999-2001, 2003  Internet Software Consortium.
                      4:  *
                      5:  * Permission to use, copy, modify, and distribute this software for any
                      6:  * purpose with or without fee is hereby granted, provided that the above
                      7:  * copyright notice and this permission notice appear in all copies.
                      8:  *
                      9:  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
                     10:  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
                     11:  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
                     12:  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
                     13:  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
                     14:  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
                     15:  * PERFORMANCE OF THIS SOFTWARE.
                     16:  */
                     17: 
1.1.1.1 ! misho      18: /* $Id: iscprint.c,v 1.2 2005/03/17 20:30:41 dhankins Exp $ */
1.1       misho      19: 
                     20: #include "dhcpd.h"
                     21: 
                     22: #ifdef NO_SNPRINTF
                     23: 
                     24: #ifndef LINT
                     25: static char copyright[] =
1.1.1.1 ! misho      26: "$Id: iscprint.c,v 1.2 2005/03/17 20:30:41 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium, Inc.  All rights reserved.";
1.1       misho      27: #endif
                     28: 
                     29: #define INSIST(cond)   REQUIRE(cond)
                     30: #define REQUIRE(cond)  if (!(cond)) { return 0; }
                     31: 
                     32: /*
                     33:  * Return length of string that would have been written if not truncated.
                     34:  */
                     35: 
                     36: int
                     37: isc_print_snprintf(char *str, size_t size, const char *format, ...) {
                     38:        va_list ap;
                     39:        int ret;
                     40: 
                     41:        va_start(ap, format);
                     42:        ret = vsnprintf(str, size, format, ap);
                     43:        va_end(ap);
                     44:        return (ret);
                     45: }
                     46: 
                     47: /*
                     48:  * Return length of string that would have been written if not truncated.
                     49:  */
                     50: 
                     51: int
                     52: isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
                     53:        int h;
                     54:        int l;
                     55:        int q;
                     56:        int alt;
                     57:        int zero;
                     58:        int left;
                     59:        int plus;
                     60:        int space;
                     61:        int neg;
                     62:        isc_int64_t tmpi;
                     63:        isc_uint64_t tmpui;
                     64:        unsigned long width;
                     65:        unsigned long precision;
                     66:        unsigned int length;
                     67:        char buf[1024];
                     68:        char c;
                     69:        void *v;
                     70:        char *save = str;
                     71:        const char *cp;
                     72:        const char *head;
                     73:        int count = 0;
                     74:        int pad;
                     75:        int zeropad;
                     76:        int dot;
                     77:        double dbl;
                     78: #ifdef HAVE_LONG_DOUBLE
                     79:        long double ldbl;
                     80: #endif
                     81:        char fmt[32];
                     82: 
                     83:        INSIST(str != NULL);
                     84:        INSIST(format != NULL);
                     85: 
                     86:        while (*format != '\0') {
                     87:                if (*format != '%') {
                     88:                        if (size > 1) {
                     89:                                *str++ = *format;
                     90:                                size--;
                     91:                        }
                     92:                        count++;
                     93:                        format++;
                     94:                        continue;
                     95:                }
                     96:                format++;
                     97: 
                     98:                /*
                     99:                 * Reset flags.
                    100:                 */
                    101:                dot = neg = space = plus = left = zero = alt = h = l = q = 0;
                    102:                width = precision = 0;
                    103:                head = "";
                    104:                length = pad = zeropad = 0;
                    105: 
                    106:                do {
                    107:                        if (*format == '#') {
                    108:                                alt = 1;
                    109:                                format++;
                    110:                        } else if (*format == '-') {
                    111:                                left = 1;
                    112:                                zero = 0;
                    113:                                format++;
                    114:                        } else if (*format == ' ') {
                    115:                                if (!plus)
                    116:                                        space = 1;
                    117:                                format++;
                    118:                        } else if (*format == '+') {
                    119:                                plus = 1;
                    120:                                space = 0;
                    121:                                format++;
                    122:                        } else if (*format == '0') {
                    123:                                if (!left)
                    124:                                        zero = 1;
                    125:                                format++;
                    126:                        } else
                    127:                                break;
                    128:                } while (1);
                    129: 
                    130:                /*
                    131:                 * Width.
                    132:                 */
                    133:                if (*format == '*') {
                    134:                        width = va_arg(ap, int);
                    135:                        format++;
                    136:                } else if (isdigit((unsigned char)*format)) {
                    137:                        char *e;
                    138:                        width = strtoul(format, &e, 10);
                    139:                        format = e;
                    140:                }
                    141: 
                    142:                /*
                    143:                 * Precision.
                    144:                 */
                    145:                if (*format == '.') {
                    146:                        format++;
                    147:                        dot = 1;
                    148:                        if (*format == '*') {
                    149:                                precision = va_arg(ap, int);
                    150:                                format++;
                    151:                        } else if (isdigit((unsigned char)*format)) {
                    152:                                char *e;
                    153:                                precision = strtoul(format, &e, 10);
                    154:                                format = e;
                    155:                        }
                    156:                }
                    157: 
                    158:                switch (*format) {
                    159:                case '\0':
                    160:                        continue;
                    161:                case '%':
                    162:                        if (size > 1) {
                    163:                                *str++ = *format;
                    164:                                size--;
                    165:                        }
                    166:                        count++;
                    167:                        break;
                    168:                case 'q':
                    169:                        q = 1;
                    170:                        format++;
                    171:                        goto doint;
                    172:                case 'h':
                    173:                        h = 1;
                    174:                        format++;
                    175:                        goto doint;
                    176:                case 'l':
                    177:                        l = 1;
                    178:                        format++;
                    179:                        if (*format == 'l') {
                    180:                                q = 1;
                    181:                                format++;
                    182:                        }
                    183:                        goto doint;
                    184:                case 'n':
                    185:                case 'i':
                    186:                case 'd':
                    187:                case 'o':
                    188:                case 'u':
                    189:                case 'x':
                    190:                case 'X':
                    191:                doint:
                    192:                        if (precision != 0)
                    193:                                zero = 0;
                    194:                        switch (*format) {
                    195:                        case 'n':
                    196:                                if (h) {
                    197:                                        short int *p;
                    198:                                        p = va_arg(ap, short *);
                    199:                                        REQUIRE(p != NULL);
                    200:                                        *p = str - save;
                    201:                                } else if (l) {
                    202:                                        long int *p;
                    203:                                        p = va_arg(ap, long *);
                    204:                                        REQUIRE(p != NULL);
                    205:                                        *p = str - save;
                    206:                                } else {
                    207:                                        int *p;
                    208:                                        p = va_arg(ap, int *);
                    209:                                        REQUIRE(p != NULL);
                    210:                                        *p = str - save;
                    211:                                }
                    212:                                break;
                    213:                        case 'i':
                    214:                        case 'd':
                    215:                                if (q)
                    216:                                        tmpi = va_arg(ap, isc_int64_t);
                    217:                                else if (l)
                    218:                                        tmpi = va_arg(ap, long int);
                    219:                                else
                    220:                                        tmpi = va_arg(ap, int);
                    221:                                if (tmpi < 0) {
                    222:                                        head = "-";
                    223:                                        tmpui = -tmpi;
                    224:                                } else {
                    225:                                        if (plus)
                    226:                                                head = "+";
                    227:                                        else if (space)
                    228:                                                head = " ";
                    229:                                        else
                    230:                                                head = "";
                    231:                                        tmpui = tmpi;
                    232:                                }
                    233:                                sprintf(buf, "%u", tmpui);
                    234:                                goto printint;
                    235:                        case 'o':
                    236:                                if (q)
                    237:                                        tmpui = va_arg(ap, isc_uint64_t);
                    238:                                else if (l)
                    239:                                        tmpui = va_arg(ap, long int);
                    240:                                else
                    241:                                        tmpui = va_arg(ap, int);
                    242:                                sprintf(buf, alt ? "%#o"
                    243:                                                 : "%o", tmpui);
                    244:                                goto printint;
                    245:                        case 'u':
                    246:                                if (q)
                    247:                                        tmpui = va_arg(ap, isc_uint64_t);
                    248:                                else if (l)
                    249:                                        tmpui = va_arg(ap, unsigned long int);
                    250:                                else
                    251:                                        tmpui = va_arg(ap, unsigned int);
                    252:                                sprintf(buf, "%u", tmpui);
                    253:                                goto printint;
                    254:                        case 'x':
                    255:                                if (q)
                    256:                                        tmpui = va_arg(ap, isc_uint64_t);
                    257:                                else if (l)
                    258:                                        tmpui = va_arg(ap, unsigned long int);
                    259:                                else
                    260:                                        tmpui = va_arg(ap, unsigned int);
                    261:                                if (alt) {
                    262:                                        head = "0x";
                    263:                                        if (precision > 2)
                    264:                                                precision -= 2;
                    265:                                }
                    266:                                sprintf(buf, "%x", tmpui);
                    267:                                goto printint;
                    268:                        case 'X':
                    269:                                if (q)
                    270:                                        tmpui = va_arg(ap, isc_uint64_t);
                    271:                                else if (l)
                    272:                                        tmpui = va_arg(ap, unsigned long int);
                    273:                                else
                    274:                                        tmpui = va_arg(ap, unsigned int);
                    275:                                if (alt) {
                    276:                                        head = "0X";
                    277:                                        if (precision > 2)
                    278:                                                precision -= 2;
                    279:                                }
                    280:                                sprintf(buf, "%X", tmpui);
                    281:                                goto printint;
                    282:                        printint:
                    283:                                if (precision != 0 || width != 0) {
                    284:                                        length = strlen(buf);
                    285:                                        if (length < precision)
                    286:                                                zeropad = precision - length;
                    287:                                        else if (length < width && zero)
                    288:                                                zeropad = width - length;
                    289:                                        if (width != 0) {
                    290:                                                pad = width - length -
                    291:                                                      zeropad - strlen(head);
                    292:                                                if (pad < 0)
                    293:                                                        pad = 0;
                    294:                                        }
                    295:                                }
                    296:                                count += strlen(head) + strlen(buf) + pad +
                    297:                                         zeropad;
                    298:                                if (!left) {
                    299:                                        while (pad > 0 && size > 1) {
                    300:                                                *str++ = ' ';
                    301:                                                size--;
                    302:                                                pad--;
                    303:                                        }
                    304:                                }
                    305:                                cp = head;
                    306:                                while (*cp != '\0' && size > 1) {
                    307:                                        *str++ = *cp++;
                    308:                                        size--;
                    309:                                }
                    310:                                while (zeropad > 0 && size > 1) {
                    311:                                        *str++ = '0';
                    312:                                        size--;
                    313:                                        zeropad--;
                    314:                                }
                    315:                                cp = buf;
                    316:                                while (*cp != '\0' && size > 1) {
                    317:                                        *str++ = *cp++;
                    318:                                        size--;
                    319:                                }
                    320:                                while (pad > 0 && size > 1) {
                    321:                                        *str++ = ' ';
                    322:                                        size--;
                    323:                                        pad--;
                    324:                                }
                    325:                                break;
                    326:                        default:
                    327:                                break;
                    328:                        }
                    329:                        break;
                    330:                case 's':
                    331:                        cp = va_arg(ap, char *);
                    332:                        REQUIRE(cp != NULL);
                    333: 
                    334:                        if (precision != 0) {
                    335:                                /*
                    336:                                 * cp need not be NULL terminated.
                    337:                                 */
                    338:                                const char *tp;
                    339:                                unsigned long n;
                    340: 
                    341:                                n = precision;
                    342:                                tp = cp;
                    343:                                while (n != 0 && *tp != '\0')
                    344:                                        n--, tp++;
                    345:                                length = precision - n;
                    346:                        } else {
                    347:                                length = strlen(cp);
                    348:                        }
                    349:                        if (width != 0) {
                    350:                                pad = width - length;
                    351:                                if (pad < 0)
                    352:                                        pad = 0;
                    353:                        }
                    354:                        count += pad + length;
                    355:                        if (!left)
                    356:                                while (pad > 0 && size > 1) {
                    357:                                        *str++ = ' ';
                    358:                                        size--;
                    359:                                        pad--;
                    360:                                }
                    361:                        if (precision != 0)
                    362:                                while (precision > 0 && *cp != '\0' &&
                    363:                                       size > 1) {
                    364:                                        *str++ = *cp++;
                    365:                                        size--;
                    366:                                        precision--;
                    367:                                }
                    368:                        else
                    369:                                while (*cp != '\0' && size > 1) {
                    370:                                        *str++ = *cp++;
                    371:                                        size--;
                    372:                                }
                    373:                        while (pad > 0 && size > 1) {
                    374:                                *str++ = ' ';
                    375:                                size--;
                    376:                                pad--;
                    377:                        }
                    378:                        break;
                    379:                case 'c':
                    380:                        c = va_arg(ap, int);
                    381:                        if (width > 0) {
                    382:                                count += width;
                    383:                                width--;
                    384:                                if (left) {
                    385:                                        *str++ = c;
                    386:                                        size--;
                    387:                                }
                    388:                                while (width-- > 0 && size > 1) {
                    389:                                        *str++ = ' ';
                    390:                                        size--;
                    391:                                }
                    392:                                if (!left && size > 1) {
                    393:                                        *str++ = c;
                    394:                                        size--;
                    395:                                }
                    396:                        } else {
                    397:                                count++;
                    398:                                if (size > 1) {
                    399:                                        *str++ = c;
                    400:                                        size--;
                    401:                                }
                    402:                        }
                    403:                        break;
                    404:                case 'p':
                    405:                        v = va_arg(ap, void *);
                    406:                        sprintf(buf, "%p", v);
                    407:                        length = strlen(buf);
                    408:                        if (precision > length)
                    409:                                zeropad = precision - length;
                    410:                        if (width > 0) {
                    411:                                pad = width - length - zeropad;
                    412:                                if (pad < 0)
                    413:                                        pad = 0;
                    414:                        }
                    415:                        count += length + pad + zeropad;
                    416:                        if (!left)
                    417:                                while (pad > 0 && size > 1) {
                    418:                                        *str++ = ' ';
                    419:                                        size--;
                    420:                                        pad--;
                    421:                                }
                    422:                        cp = buf;
                    423:                        if (zeropad > 0 && buf[0] == '0' &&
                    424:                            (buf[1] == 'x' || buf[1] == 'X')) {
                    425:                                if (size > 1) {
                    426:                                        *str++ = *cp++;
                    427:                                        size--;
                    428:                                }
                    429:                                if (size > 1) {
                    430:                                        *str++ = *cp++;
                    431:                                        size--;
                    432:                                }
                    433:                                while (zeropad > 0 && size > 1) {
                    434:                                        *str++ = '0';
                    435:                                        size--;
                    436:                                        zeropad--;
                    437:                                }
                    438:                        }
                    439:                        while (*cp != '\0' && size > 1) {
                    440:                                *str++ = *cp++;
                    441:                                size--;
                    442:                        }
                    443:                        while (pad > 0 && size > 1) {
                    444:                                *str++ = ' ';
                    445:                                size--;
                    446:                                pad--;
                    447:                        }
                    448:                        break;
                    449:                case 'D':       /*deprecated*/
                    450:                        INSIST("use %ld instead of %D" == NULL);
                    451:                case 'O':       /*deprecated*/
                    452:                        INSIST("use %lo instead of %O" == NULL);
                    453:                case 'U':       /*deprecated*/
                    454:                        INSIST("use %lu instead of %U" == NULL);
                    455: 
                    456:                case 'L':
                    457: #ifdef HAVE_LONG_DOUBLE
                    458:                        l = 1;
                    459: #else
                    460:                        INSIST("long doubles are not supported" == NULL);
                    461: #endif
                    462:                        /*FALLTHROUGH*/
                    463:                case 'e':
                    464:                case 'E':
                    465:                case 'f':
                    466:                case 'g':
                    467:                case 'G':
                    468:                        if (!dot)
                    469:                                precision = 6;
                    470:                        /*
                    471:                         * IEEE floating point.
                    472:                         * MIN 2.2250738585072014E-308
                    473:                         * MAX 1.7976931348623157E+308
                    474:                         * VAX floating point has a smaller range than IEEE.
                    475:                         *
                    476:                         * precisions > 324 don't make much sense.
                    477:                         * if we cap the precision at 512 we will not
                    478:                         * overflow buf.
                    479:                         */
                    480:                        if (precision > 512)
                    481:                                precision = 512;
                    482:                        sprintf(fmt, "%%%s%s.%lu%s%c", alt ? "#" : "",
                    483:                                plus ? "+" : space ? " " : "",
                    484:                                precision, l ? "L" : "", *format);
                    485:                        switch (*format) {
                    486:                        case 'e':
                    487:                        case 'E':
                    488:                        case 'f':
                    489:                        case 'g':
                    490:                        case 'G':
                    491: #ifdef HAVE_LONG_DOUBLE
                    492:                                if (l) {
                    493:                                        ldbl = va_arg(ap, long double);
                    494:                                        sprintf(buf, fmt, ldbl);
                    495:                                } else
                    496: #endif
                    497:                                {
                    498:                                        dbl = va_arg(ap, double);
                    499:                                        sprintf(buf, fmt, dbl);
                    500:                                }
                    501:                                length = strlen(buf);
                    502:                                if (width > 0) {
                    503:                                        pad = width - length;
                    504:                                        if (pad < 0)
                    505:                                                pad = 0;
                    506:                                }
                    507:                                count += length + pad;
                    508:                                if (!left)
                    509:                                        while (pad > 0 && size > 1) {
                    510:                                                *str++ = ' ';
                    511:                                                size--;
                    512:                                                pad--;
                    513:                                        }
                    514:                                cp = buf;
                    515:                                while (*cp != ' ' && size > 1) {
                    516:                                        *str++ = *cp++;
                    517:                                        size--;
                    518:                                }
                    519:                                while (pad > 0 && size > 1) {
                    520:                                        *str++ = ' ';
                    521:                                        size--;
                    522:                                        pad--;
                    523:                                }
                    524:                                break;
                    525:                        default:
                    526:                                continue;
                    527:                        }
                    528:                        break;
                    529:                default:
                    530:                        continue;
                    531:                }
                    532:                format++;
                    533:        }
                    534:        if (size > 0)
                    535:                *str = '\0';
                    536:        return (count);
                    537: }
                    538: 
                    539: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>