File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / dhcp / omapip / iscprint.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Oct 9 09:06:54 2012 UTC (12 years, 5 months ago) by misho
Branches: dhcp, MAIN
CVS tags: v4_1_R7p0, v4_1_R7, v4_1_R4, HEAD
dhcp 4.1 r7

    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.1.1.1 2012/10/09 09:06:54 misho 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.1.1.1 2012/10/09 09:06:54 misho 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>