Annotation of embedaddon/dhcp/omapip/iscprint.c, revision 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:
! 18: /* $Id: iscprint.c,v 1.2 2005-03-17 20:30:41 dhankins Exp $ */
! 19:
! 20: #include "dhcpd.h"
! 21:
! 22: #ifdef NO_SNPRINTF
! 23:
! 24: #ifndef LINT
! 25: static char copyright[] =
! 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.";
! 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>