1290001Sglebius/* 2290001Sglebius * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC") 3290001Sglebius * Copyright (C) 1999-2001, 2003 Internet Software Consortium. 4290001Sglebius * 5290001Sglebius * Permission to use, copy, modify, and/or distribute this software for any 6290001Sglebius * purpose with or without fee is hereby granted, provided that the above 7290001Sglebius * copyright notice and this permission notice appear in all copies. 8290001Sglebius * 9290001Sglebius * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10290001Sglebius * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11290001Sglebius * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12290001Sglebius * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13290001Sglebius * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14290001Sglebius * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15290001Sglebius * PERFORMANCE OF THIS SOFTWARE. 16290001Sglebius */ 17290001Sglebius 18290001Sglebius/* $Id: print.c,v 1.37 2010/10/18 23:47:08 tbox Exp $ */ 19290001Sglebius 20290001Sglebius/*! \file */ 21290001Sglebius 22290001Sglebius#include <config.h> 23290001Sglebius 24290001Sglebius#include <ctype.h> 25290001Sglebius#include <stdio.h> /* for sprintf() */ 26290001Sglebius#include <string.h> /* for strlen() */ 27290001Sglebius 28290001Sglebius#define ISC__PRINT_SOURCE /* Used to get the isc_print_* prototypes. */ 29290001Sglebius 30290001Sglebius#include <isc/assertions.h> 31290001Sglebius#include <isc/int.h> 32290001Sglebius#include <isc/msgs.h> 33290001Sglebius#include <isc/print.h> 34290001Sglebius#include <isc/stdlib.h> 35290001Sglebius#include <isc/util.h> 36290001Sglebius 37290001Sglebiusint 38290001Sglebiusisc_print_sprintf(char *str, const char *format, ...) { 39290001Sglebius va_list ap; 40290001Sglebius 41290001Sglebius va_start(ap, format); 42290001Sglebius vsprintf(str, format, ap); 43290001Sglebius va_end(ap); 44290001Sglebius return (strlen(str)); 45290001Sglebius} 46290001Sglebius 47290001Sglebius/*! 48290001Sglebius * Return length of string that would have been written if not truncated. 49290001Sglebius */ 50290001Sglebius 51290001Sglebiusint 52290001Sglebiusisc_print_snprintf(char *str, size_t size, const char *format, ...) { 53290001Sglebius va_list ap; 54290001Sglebius int ret; 55290001Sglebius 56290001Sglebius va_start(ap, format); 57290001Sglebius ret = vsnprintf(str, size, format, ap); 58290001Sglebius va_end(ap); 59290001Sglebius return (ret); 60290001Sglebius 61290001Sglebius} 62290001Sglebius 63290001Sglebius/*! 64290001Sglebius * Return length of string that would have been written if not truncated. 65290001Sglebius */ 66290001Sglebius 67290001Sglebiusint 68290001Sglebiusisc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) { 69290001Sglebius int h; 70290001Sglebius int l; 71290001Sglebius int q; 72290001Sglebius int alt; 73290001Sglebius int zero; 74290001Sglebius int left; 75290001Sglebius int plus; 76290001Sglebius int space; 77290001Sglebius int neg; 78290001Sglebius isc_int64_t tmpi; 79290001Sglebius isc_uint64_t tmpui; 80290001Sglebius unsigned long width; 81290001Sglebius unsigned long precision; 82290001Sglebius unsigned int length; 83290001Sglebius char buf[1024]; 84290001Sglebius char c; 85290001Sglebius void *v; 86290001Sglebius char *save = str; 87290001Sglebius const char *cp; 88290001Sglebius const char *head; 89290001Sglebius int count = 0; 90290001Sglebius int pad; 91290001Sglebius int zeropad; 92290001Sglebius int dot; 93290001Sglebius double dbl; 94290001Sglebius#ifdef HAVE_LONG_DOUBLE 95290001Sglebius long double ldbl; 96290001Sglebius#endif 97290001Sglebius char fmt[32]; 98290001Sglebius 99290001Sglebius INSIST(str != NULL); 100290001Sglebius INSIST(format != NULL); 101290001Sglebius 102290001Sglebius while (*format != '\0') { 103290001Sglebius if (*format != '%') { 104290001Sglebius if (size > 1) { 105290001Sglebius *str++ = *format; 106290001Sglebius size--; 107290001Sglebius } 108290001Sglebius count++; 109290001Sglebius format++; 110290001Sglebius continue; 111290001Sglebius } 112290001Sglebius format++; 113290001Sglebius 114290001Sglebius /* 115290001Sglebius * Reset flags. 116290001Sglebius */ 117290001Sglebius dot = neg = space = plus = left = zero = alt = h = l = q = 0; 118290001Sglebius width = precision = 0; 119290001Sglebius head = ""; 120290001Sglebius length = pad = zeropad = 0; 121290001Sglebius 122290001Sglebius do { 123290001Sglebius if (*format == '#') { 124290001Sglebius alt = 1; 125290001Sglebius format++; 126290001Sglebius } else if (*format == '-') { 127290001Sglebius left = 1; 128290001Sglebius zero = 0; 129290001Sglebius format++; 130290001Sglebius } else if (*format == ' ') { 131290001Sglebius if (!plus) 132290001Sglebius space = 1; 133290001Sglebius format++; 134290001Sglebius } else if (*format == '+') { 135290001Sglebius plus = 1; 136290001Sglebius space = 0; 137290001Sglebius format++; 138290001Sglebius } else if (*format == '0') { 139290001Sglebius if (!left) 140290001Sglebius zero = 1; 141290001Sglebius format++; 142290001Sglebius } else 143290001Sglebius break; 144290001Sglebius } while (1); 145290001Sglebius 146290001Sglebius /* 147290001Sglebius * Width. 148290001Sglebius */ 149290001Sglebius if (*format == '*') { 150290001Sglebius width = va_arg(ap, int); 151290001Sglebius format++; 152290001Sglebius } else if (isdigit((unsigned char)*format)) { 153290001Sglebius char *e; 154290001Sglebius width = strtoul(format, &e, 10); 155290001Sglebius format = e; 156290001Sglebius } 157290001Sglebius 158290001Sglebius /* 159290001Sglebius * Precision. 160290001Sglebius */ 161290001Sglebius if (*format == '.') { 162290001Sglebius format++; 163290001Sglebius dot = 1; 164290001Sglebius if (*format == '*') { 165290001Sglebius precision = va_arg(ap, int); 166290001Sglebius format++; 167290001Sglebius } else if (isdigit((unsigned char)*format)) { 168290001Sglebius char *e; 169290001Sglebius precision = strtoul(format, &e, 10); 170290001Sglebius format = e; 171290001Sglebius } 172290001Sglebius } 173290001Sglebius 174290001Sglebius switch (*format) { 175290001Sglebius case '\0': 176290001Sglebius continue; 177290001Sglebius case '%': 178290001Sglebius if (size > 1) { 179290001Sglebius *str++ = *format; 180290001Sglebius size--; 181290001Sglebius } 182290001Sglebius count++; 183290001Sglebius break; 184290001Sglebius case 'q': 185290001Sglebius q = 1; 186290001Sglebius format++; 187290001Sglebius goto doint; 188290001Sglebius case 'h': 189290001Sglebius h = 1; 190290001Sglebius format++; 191290001Sglebius goto doint; 192290001Sglebius case 'l': 193290001Sglebius l = 1; 194290001Sglebius format++; 195290001Sglebius if (*format == 'l') { 196290001Sglebius q = 1; 197290001Sglebius format++; 198290001Sglebius } 199290001Sglebius goto doint; 200290001Sglebius case 'n': 201290001Sglebius case 'i': 202290001Sglebius case 'd': 203290001Sglebius case 'o': 204290001Sglebius case 'u': 205290001Sglebius case 'x': 206290001Sglebius case 'X': 207290001Sglebius doint: 208290001Sglebius if (precision != 0) 209290001Sglebius zero = 0; 210290001Sglebius switch (*format) { 211290001Sglebius case 'n': 212290001Sglebius if (h) { 213290001Sglebius short int *p; 214290001Sglebius p = va_arg(ap, short *); 215290001Sglebius REQUIRE(p != NULL); 216290001Sglebius *p = str - save; 217290001Sglebius } else if (l) { 218290001Sglebius long int *p; 219290001Sglebius p = va_arg(ap, long *); 220290001Sglebius REQUIRE(p != NULL); 221290001Sglebius *p = str - save; 222290001Sglebius } else { 223290001Sglebius int *p; 224290001Sglebius p = va_arg(ap, int *); 225290001Sglebius REQUIRE(p != NULL); 226290001Sglebius *p = str - save; 227290001Sglebius } 228290001Sglebius break; 229290001Sglebius case 'i': 230290001Sglebius case 'd': 231290001Sglebius if (q) 232290001Sglebius tmpi = va_arg(ap, isc_int64_t); 233290001Sglebius else if (l) 234290001Sglebius tmpi = va_arg(ap, long int); 235290001Sglebius else 236290001Sglebius tmpi = va_arg(ap, int); 237290001Sglebius if (tmpi < 0) { 238290001Sglebius head = "-"; 239290001Sglebius tmpui = -tmpi; 240290001Sglebius } else { 241290001Sglebius if (plus) 242290001Sglebius head = "+"; 243290001Sglebius else if (space) 244290001Sglebius head = " "; 245290001Sglebius else 246290001Sglebius head = ""; 247290001Sglebius tmpui = tmpi; 248290001Sglebius } 249290001Sglebius if (tmpui <= 0xffffffffU) 250290001Sglebius sprintf(buf, "%lu", 251290001Sglebius (unsigned long)tmpui); 252290001Sglebius else { 253290001Sglebius unsigned long mid; 254290001Sglebius unsigned long lo; 255290001Sglebius unsigned long hi; 256290001Sglebius lo = tmpui % 1000000000; 257290001Sglebius tmpui /= 1000000000; 258290001Sglebius mid = tmpui % 1000000000; 259290001Sglebius hi = tmpui / 1000000000; 260290001Sglebius if (hi != 0) 261290001Sglebius sprintf(buf, "%lu", hi); 262290001Sglebius else 263290001Sglebius buf[0] = '\n'; 264290001Sglebius sprintf(buf + strlen(buf), "%lu", mid); 265290001Sglebius sprintf(buf + strlen(buf), "%lu", lo); 266290001Sglebius } 267290001Sglebius goto printint; 268290001Sglebius case 'o': 269290001Sglebius if (q) 270290001Sglebius tmpui = va_arg(ap, isc_uint64_t); 271290001Sglebius else if (l) 272290001Sglebius tmpui = va_arg(ap, long int); 273290001Sglebius else 274290001Sglebius tmpui = va_arg(ap, int); 275290001Sglebius if (tmpui <= 0xffffffffU) 276290001Sglebius sprintf(buf, alt ? "%#lo" : "%lo", 277290001Sglebius (unsigned long)tmpui); 278290001Sglebius else { 279290001Sglebius unsigned long mid; 280290001Sglebius unsigned long lo; 281290001Sglebius unsigned long hi; 282290001Sglebius lo = tmpui % 010000000000; 283290001Sglebius tmpui /= 010000000000; 284290001Sglebius mid = tmpui % 010000000000; 285290001Sglebius hi = tmpui / 010000000000; 286290001Sglebius if (hi != 0) { 287290001Sglebius sprintf(buf, 288290001Sglebius alt ? "%#lo" : "%lo", 289290001Sglebius hi); 290290001Sglebius sprintf(buf + strlen(buf), 291290001Sglebius "%lo", mid); 292290001Sglebius } else 293290001Sglebius sprintf(buf, 294290001Sglebius alt ? "%#lo" : "%lo", 295290001Sglebius mid); 296290001Sglebius sprintf(buf + strlen(buf), "%lo", lo); 297290001Sglebius } 298290001Sglebius goto printint; 299290001Sglebius case 'u': 300290001Sglebius if (q) 301290001Sglebius tmpui = va_arg(ap, isc_uint64_t); 302290001Sglebius else if (l) 303290001Sglebius tmpui = va_arg(ap, unsigned long int); 304290001Sglebius else 305290001Sglebius tmpui = va_arg(ap, unsigned int); 306290001Sglebius if (tmpui <= 0xffffffffU) 307290001Sglebius sprintf(buf, "%lu", 308290001Sglebius (unsigned long)tmpui); 309290001Sglebius else { 310290001Sglebius unsigned long mid; 311290001Sglebius unsigned long lo; 312290001Sglebius unsigned long hi; 313290001Sglebius lo = tmpui % 1000000000; 314290001Sglebius tmpui /= 1000000000; 315290001Sglebius mid = tmpui % 1000000000; 316290001Sglebius hi = tmpui / 1000000000; 317290001Sglebius if (hi != 0) 318290001Sglebius sprintf(buf, "%lu", hi); 319290001Sglebius else 320290001Sglebius buf[0] = '\n'; 321290001Sglebius sprintf(buf + strlen(buf), "%lu", mid); 322290001Sglebius sprintf(buf + strlen(buf), "%lu", lo); 323290001Sglebius } 324290001Sglebius goto printint; 325290001Sglebius case 'x': 326290001Sglebius if (q) 327290001Sglebius tmpui = va_arg(ap, isc_uint64_t); 328290001Sglebius else if (l) 329290001Sglebius tmpui = va_arg(ap, unsigned long int); 330290001Sglebius else 331290001Sglebius tmpui = va_arg(ap, unsigned int); 332290001Sglebius if (alt) { 333290001Sglebius head = "0x"; 334290001Sglebius if (precision > 2) 335290001Sglebius precision -= 2; 336290001Sglebius } 337290001Sglebius if (tmpui <= 0xffffffffU) 338290001Sglebius sprintf(buf, "%lx", 339290001Sglebius (unsigned long)tmpui); 340290001Sglebius else { 341290001Sglebius unsigned long hi = tmpui>>32; 342290001Sglebius unsigned long lo = tmpui & 0xffffffff; 343290001Sglebius sprintf(buf, "%lx", hi); 344290001Sglebius sprintf(buf + strlen(buf), "%lx", lo); 345290001Sglebius } 346290001Sglebius goto printint; 347290001Sglebius case 'X': 348290001Sglebius if (q) 349290001Sglebius tmpui = va_arg(ap, isc_uint64_t); 350290001Sglebius else if (l) 351290001Sglebius tmpui = va_arg(ap, unsigned long int); 352290001Sglebius else 353290001Sglebius tmpui = va_arg(ap, unsigned int); 354290001Sglebius if (alt) { 355290001Sglebius head = "0X"; 356290001Sglebius if (precision > 2) 357290001Sglebius precision -= 2; 358290001Sglebius } 359290001Sglebius if (tmpui <= 0xffffffffU) 360290001Sglebius sprintf(buf, "%lX", 361290001Sglebius (unsigned long)tmpui); 362290001Sglebius else { 363290001Sglebius unsigned long hi = tmpui>>32; 364290001Sglebius unsigned long lo = tmpui & 0xffffffff; 365290001Sglebius sprintf(buf, "%lX", hi); 366290001Sglebius sprintf(buf + strlen(buf), "%lX", lo); 367290001Sglebius } 368290001Sglebius goto printint; 369290001Sglebius printint: 370290001Sglebius if (precision != 0 || width != 0) { 371290001Sglebius length = strlen(buf); 372290001Sglebius if (length < precision) 373290001Sglebius zeropad = precision - length; 374290001Sglebius else if (length < width && zero) 375290001Sglebius zeropad = width - length; 376290001Sglebius if (width != 0) { 377290001Sglebius pad = width - length - 378290001Sglebius zeropad - strlen(head); 379290001Sglebius if (pad < 0) 380290001Sglebius pad = 0; 381290001Sglebius } 382290001Sglebius } 383290001Sglebius count += strlen(head) + strlen(buf) + pad + 384290001Sglebius zeropad; 385290001Sglebius if (!left) { 386290001Sglebius while (pad > 0 && size > 1) { 387290001Sglebius *str++ = ' '; 388290001Sglebius size--; 389290001Sglebius pad--; 390290001Sglebius } 391290001Sglebius } 392290001Sglebius cp = head; 393290001Sglebius while (*cp != '\0' && size > 1) { 394290001Sglebius *str++ = *cp++; 395290001Sglebius size--; 396290001Sglebius } 397290001Sglebius while (zeropad > 0 && size > 1) { 398290001Sglebius *str++ = '0'; 399290001Sglebius size--; 400290001Sglebius zeropad--; 401290001Sglebius } 402290001Sglebius cp = buf; 403290001Sglebius while (*cp != '\0' && size > 1) { 404290001Sglebius *str++ = *cp++; 405290001Sglebius size--; 406290001Sglebius } 407290001Sglebius while (pad > 0 && size > 1) { 408290001Sglebius *str++ = ' '; 409290001Sglebius size--; 410290001Sglebius pad--; 411290001Sglebius } 412290001Sglebius break; 413290001Sglebius default: 414290001Sglebius break; 415290001Sglebius } 416290001Sglebius break; 417290001Sglebius case 's': 418290001Sglebius cp = va_arg(ap, char *); 419290001Sglebius REQUIRE(cp != NULL); 420290001Sglebius 421290001Sglebius if (precision != 0) { 422290001Sglebius /* 423290001Sglebius * cp need not be NULL terminated. 424290001Sglebius */ 425290001Sglebius const char *tp; 426290001Sglebius unsigned long n; 427290001Sglebius 428290001Sglebius n = precision; 429290001Sglebius tp = cp; 430290001Sglebius while (n != 0 && *tp != '\0') 431290001Sglebius n--, tp++; 432290001Sglebius length = precision - n; 433290001Sglebius } else { 434290001Sglebius length = strlen(cp); 435290001Sglebius } 436290001Sglebius if (width != 0) { 437290001Sglebius pad = width - length; 438290001Sglebius if (pad < 0) 439290001Sglebius pad = 0; 440290001Sglebius } 441290001Sglebius count += pad + length; 442290001Sglebius if (!left) 443290001Sglebius while (pad > 0 && size > 1) { 444290001Sglebius *str++ = ' '; 445290001Sglebius size--; 446290001Sglebius pad--; 447290001Sglebius } 448290001Sglebius if (precision != 0) 449290001Sglebius while (precision > 0 && *cp != '\0' && 450290001Sglebius size > 1) { 451290001Sglebius *str++ = *cp++; 452290001Sglebius size--; 453290001Sglebius precision--; 454290001Sglebius } 455290001Sglebius else 456290001Sglebius while (*cp != '\0' && size > 1) { 457290001Sglebius *str++ = *cp++; 458290001Sglebius size--; 459290001Sglebius } 460290001Sglebius while (pad > 0 && size > 1) { 461290001Sglebius *str++ = ' '; 462290001Sglebius size--; 463290001Sglebius pad--; 464290001Sglebius } 465290001Sglebius break; 466290001Sglebius case 'c': 467290001Sglebius c = va_arg(ap, int); 468290001Sglebius if (width > 0) { 469290001Sglebius count += width; 470290001Sglebius width--; 471290001Sglebius if (left && size > 1) { 472290001Sglebius *str++ = c; 473290001Sglebius size--; 474290001Sglebius } 475290001Sglebius while (width-- > 0 && size > 1) { 476290001Sglebius *str++ = ' '; 477290001Sglebius size--; 478290001Sglebius } 479290001Sglebius if (!left && size > 1) { 480290001Sglebius *str++ = c; 481290001Sglebius size--; 482290001Sglebius } 483290001Sglebius } else { 484290001Sglebius count++; 485290001Sglebius if (size > 1) { 486290001Sglebius *str++ = c; 487290001Sglebius size--; 488290001Sglebius } 489290001Sglebius } 490290001Sglebius break; 491290001Sglebius case 'p': 492290001Sglebius v = va_arg(ap, void *); 493290001Sglebius sprintf(buf, "%p", v); 494290001Sglebius length = strlen(buf); 495290001Sglebius if (precision > length) 496290001Sglebius zeropad = precision - length; 497290001Sglebius if (width > 0) { 498290001Sglebius pad = width - length - zeropad; 499290001Sglebius if (pad < 0) 500290001Sglebius pad = 0; 501290001Sglebius } 502290001Sglebius count += length + pad + zeropad; 503290001Sglebius if (!left) 504290001Sglebius while (pad > 0 && size > 1) { 505290001Sglebius *str++ = ' '; 506290001Sglebius size--; 507290001Sglebius pad--; 508290001Sglebius } 509290001Sglebius cp = buf; 510290001Sglebius if (zeropad > 0 && buf[0] == '0' && 511290001Sglebius (buf[1] == 'x' || buf[1] == 'X')) { 512290001Sglebius if (size > 1) { 513290001Sglebius *str++ = *cp++; 514290001Sglebius size--; 515290001Sglebius } 516290001Sglebius if (size > 1) { 517290001Sglebius *str++ = *cp++; 518290001Sglebius size--; 519290001Sglebius } 520290001Sglebius while (zeropad > 0 && size > 1) { 521290001Sglebius *str++ = '0'; 522290001Sglebius size--; 523290001Sglebius zeropad--; 524290001Sglebius } 525290001Sglebius } 526290001Sglebius while (*cp != '\0' && size > 1) { 527290001Sglebius *str++ = *cp++; 528290001Sglebius size--; 529290001Sglebius } 530290001Sglebius while (pad > 0 && size > 1) { 531290001Sglebius *str++ = ' '; 532290001Sglebius size--; 533290001Sglebius pad--; 534290001Sglebius } 535290001Sglebius break; 536290001Sglebius case 'D': /*deprecated*/ 537290001Sglebius INSIST("use %ld instead of %D" == NULL); 538290001Sglebius case 'O': /*deprecated*/ 539290001Sglebius INSIST("use %lo instead of %O" == NULL); 540290001Sglebius case 'U': /*deprecated*/ 541290001Sglebius INSIST("use %lu instead of %U" == NULL); 542290001Sglebius 543290001Sglebius case 'L': 544290001Sglebius#ifdef HAVE_LONG_DOUBLE 545290001Sglebius l = 1; 546290001Sglebius#else 547290001Sglebius INSIST("long doubles are not supported" == NULL); 548290001Sglebius#endif 549290001Sglebius /*FALLTHROUGH*/ 550290001Sglebius case 'e': 551290001Sglebius case 'E': 552290001Sglebius case 'f': 553290001Sglebius case 'g': 554290001Sglebius case 'G': 555290001Sglebius if (!dot) 556290001Sglebius precision = 6; 557290001Sglebius /* 558290001Sglebius * IEEE floating point. 559290001Sglebius * MIN 2.2250738585072014E-308 560290001Sglebius * MAX 1.7976931348623157E+308 561290001Sglebius * VAX floating point has a smaller range than IEEE. 562290001Sglebius * 563290001Sglebius * precisions > 324 don't make much sense. 564290001Sglebius * if we cap the precision at 512 we will not 565290001Sglebius * overflow buf. 566290001Sglebius */ 567290001Sglebius if (precision > 512) 568290001Sglebius precision = 512; 569290001Sglebius sprintf(fmt, "%%%s%s.%lu%s%c", alt ? "#" : "", 570290001Sglebius plus ? "+" : space ? " " : "", 571290001Sglebius precision, l ? "L" : "", *format); 572290001Sglebius switch (*format) { 573290001Sglebius case 'e': 574290001Sglebius case 'E': 575290001Sglebius case 'f': 576290001Sglebius case 'g': 577290001Sglebius case 'G': 578290001Sglebius#ifdef HAVE_LONG_DOUBLE 579290001Sglebius if (l) { 580290001Sglebius ldbl = va_arg(ap, long double); 581290001Sglebius sprintf(buf, fmt, ldbl); 582290001Sglebius } else 583290001Sglebius#endif 584290001Sglebius { 585290001Sglebius dbl = va_arg(ap, double); 586290001Sglebius sprintf(buf, fmt, dbl); 587290001Sglebius } 588290001Sglebius length = strlen(buf); 589290001Sglebius if (width > 0) { 590290001Sglebius pad = width - length; 591290001Sglebius if (pad < 0) 592290001Sglebius pad = 0; 593290001Sglebius } 594290001Sglebius count += length + pad; 595290001Sglebius if (!left) 596290001Sglebius while (pad > 0 && size > 1) { 597290001Sglebius *str++ = ' '; 598290001Sglebius size--; 599290001Sglebius pad--; 600290001Sglebius } 601290001Sglebius cp = buf; 602290001Sglebius while (*cp != ' ' && size > 1) { 603290001Sglebius *str++ = *cp++; 604290001Sglebius size--; 605290001Sglebius } 606290001Sglebius while (pad > 0 && size > 1) { 607290001Sglebius *str++ = ' '; 608290001Sglebius size--; 609290001Sglebius pad--; 610290001Sglebius } 611290001Sglebius break; 612290001Sglebius default: 613290001Sglebius continue; 614290001Sglebius } 615290001Sglebius break; 616290001Sglebius default: 617290001Sglebius continue; 618290001Sglebius } 619290001Sglebius format++; 620290001Sglebius } 621290001Sglebius if (size > 0) 622290001Sglebius *str = '\0'; 623290001Sglebius return (count); 624290001Sglebius} 625