Commit e4c393fd551654179c46b65e4a70ea20d831c783

Authored by Linus Torvalds

Merge branch 'printk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'printk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  printk: correct the behavior of printk_timed_ratelimit()
  vsprintf: unify the format decoding layer for its 3 users, cleanup
  fix regression from "vsprintf: unify the format decoding layer for its 3 users"
  vsprintf: fix bug in negative value printing
  vsprintf: unify the format decoding layer for its 3 users
  vsprintf: add binary printf
  printk: introduce printk_once()

Fix trivial conflicts (printk_once vs log_buf_kexec_setup() added near
each other) in include/linux/kernel.h.

Showing 5 changed files Side-by-side Diff

include/linux/kernel.h
... ... @@ -242,6 +242,19 @@
242 242 extern int printk_ratelimit(void);
243 243 extern bool printk_timed_ratelimit(unsigned long *caller_jiffies,
244 244 unsigned int interval_msec);
  245 +
  246 +/*
  247 + * Print a one-time message (analogous to WARN_ONCE() et al):
  248 + */
  249 +#define printk_once(x...) ({ \
  250 + static int __print_once = 1; \
  251 + \
  252 + if (__print_once) { \
  253 + __print_once = 0; \
  254 + printk(x); \
  255 + } \
  256 +})
  257 +
245 258 void log_buf_kexec_setup(void);
246 259 #else
247 260 static inline int vprintk(const char *s, va_list args)
... ... @@ -254,6 +267,10 @@
254 267 static inline bool printk_timed_ratelimit(unsigned long *caller_jiffies, \
255 268 unsigned int interval_msec) \
256 269 { return false; }
  270 +
  271 +/* No effect, but we still get type checking even in the !PRINTK case: */
  272 +#define printk_once(x...) printk(x)
  273 +
257 274 static inline void log_buf_kexec_setup(void)
258 275 {
259 276 }
include/linux/string.h
... ... @@ -10,6 +10,7 @@
10 10 #include <linux/compiler.h> /* for inline */
11 11 #include <linux/types.h> /* for size_t */
12 12 #include <linux/stddef.h> /* for NULL */
  13 +#include <stdarg.h>
13 14  
14 15 extern char *strndup_user(const char __user *, long);
15 16 extern void *memdup_user(const void __user *, size_t);
... ... @@ -111,6 +112,12 @@
111 112 extern void argv_free(char **argv);
112 113  
113 114 extern bool sysfs_streq(const char *s1, const char *s2);
  115 +
  116 +#ifdef CONFIG_BINARY_PRINTF
  117 +int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args);
  118 +int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf);
  119 +int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...) __printf(3, 4);
  120 +#endif
114 121  
115 122 extern ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos,
116 123 const void *from, size_t available);
... ... @@ -1311,8 +1311,11 @@
1311 1311 bool printk_timed_ratelimit(unsigned long *caller_jiffies,
1312 1312 unsigned int interval_msecs)
1313 1313 {
1314   - if (*caller_jiffies == 0 || time_after(jiffies, *caller_jiffies)) {
1315   - *caller_jiffies = jiffies + msecs_to_jiffies(interval_msecs);
  1314 + if (*caller_jiffies == 0
  1315 + || !time_in_range(jiffies, *caller_jiffies,
  1316 + *caller_jiffies
  1317 + + msecs_to_jiffies(interval_msecs))) {
  1318 + *caller_jiffies = jiffies;
1316 1319 return true;
1317 1320 }
1318 1321 return false;
... ... @@ -2,6 +2,9 @@
2 2 # Library configuration
3 3 #
4 4  
  5 +config BINARY_PRINTF
  6 + def_bool n
  7 +
5 8 menu "Library routines"
6 9  
7 10 config BITREVERSE
Changes suppressed. Click to show
... ... @@ -396,7 +396,38 @@
396 396 #define SMALL 32 /* Must be 32 == 0x20 */
397 397 #define SPECIAL 64 /* 0x */
398 398  
399   -static char *number(char *buf, char *end, unsigned long long num, int base, int size, int precision, int type)
  399 +enum format_type {
  400 + FORMAT_TYPE_NONE, /* Just a string part */
  401 + FORMAT_TYPE_WIDTH,
  402 + FORMAT_TYPE_PRECISION,
  403 + FORMAT_TYPE_CHAR,
  404 + FORMAT_TYPE_STR,
  405 + FORMAT_TYPE_PTR,
  406 + FORMAT_TYPE_PERCENT_CHAR,
  407 + FORMAT_TYPE_INVALID,
  408 + FORMAT_TYPE_LONG_LONG,
  409 + FORMAT_TYPE_ULONG,
  410 + FORMAT_TYPE_LONG,
  411 + FORMAT_TYPE_USHORT,
  412 + FORMAT_TYPE_SHORT,
  413 + FORMAT_TYPE_UINT,
  414 + FORMAT_TYPE_INT,
  415 + FORMAT_TYPE_NRCHARS,
  416 + FORMAT_TYPE_SIZE_T,
  417 + FORMAT_TYPE_PTRDIFF
  418 +};
  419 +
  420 +struct printf_spec {
  421 + enum format_type type;
  422 + int flags; /* flags to number() */
  423 + int field_width; /* width of output field */
  424 + int base;
  425 + int precision; /* # of digits/chars */
  426 + int qualifier;
  427 +};
  428 +
  429 +static char *number(char *buf, char *end, unsigned long long num,
  430 + struct printf_spec spec)
400 431 {
401 432 /* we are called with base 8, 10 or 16, only, thus don't need "G..." */
402 433 static const char digits[16] = "0123456789ABCDEF"; /* "GHIJKLMNOPQRSTUVWXYZ"; */
403 434  
404 435  
405 436  
406 437  
407 438  
408 439  
... ... @@ -404,32 +435,32 @@
404 435 char tmp[66];
405 436 char sign;
406 437 char locase;
407   - int need_pfx = ((type & SPECIAL) && base != 10);
  438 + int need_pfx = ((spec.flags & SPECIAL) && spec.base != 10);
408 439 int i;
409 440  
410 441 /* locase = 0 or 0x20. ORing digits or letters with 'locase'
411 442 * produces same digits or (maybe lowercased) letters */
412   - locase = (type & SMALL);
413   - if (type & LEFT)
414   - type &= ~ZEROPAD;
  443 + locase = (spec.flags & SMALL);
  444 + if (spec.flags & LEFT)
  445 + spec.flags &= ~ZEROPAD;
415 446 sign = 0;
416   - if (type & SIGN) {
  447 + if (spec.flags & SIGN) {
417 448 if ((signed long long) num < 0) {
418 449 sign = '-';
419 450 num = - (signed long long) num;
420   - size--;
421   - } else if (type & PLUS) {
  451 + spec.field_width--;
  452 + } else if (spec.flags & PLUS) {
422 453 sign = '+';
423   - size--;
424   - } else if (type & SPACE) {
  454 + spec.field_width--;
  455 + } else if (spec.flags & SPACE) {
425 456 sign = ' ';
426   - size--;
  457 + spec.field_width--;
427 458 }
428 459 }
429 460 if (need_pfx) {
430   - size--;
431   - if (base == 16)
432   - size--;
  461 + spec.field_width--;
  462 + if (spec.base == 16)
  463 + spec.field_width--;
433 464 }
434 465  
435 466 /* generate full string in tmp[], in reverse order */
436 467  
... ... @@ -441,10 +472,10 @@
441 472 tmp[i++] = (digits[do_div(num,base)] | locase);
442 473 } while (num != 0);
443 474 */
444   - else if (base != 10) { /* 8 or 16 */
445   - int mask = base - 1;
  475 + else if (spec.base != 10) { /* 8 or 16 */
  476 + int mask = spec.base - 1;
446 477 int shift = 3;
447   - if (base == 16) shift = 4;
  478 + if (spec.base == 16) shift = 4;
448 479 do {
449 480 tmp[i++] = (digits[((unsigned char)num) & mask] | locase);
450 481 num >>= shift;
451 482  
... ... @@ -454,12 +485,12 @@
454 485 }
455 486  
456 487 /* printing 100 using %2d gives "100", not "00" */
457   - if (i > precision)
458   - precision = i;
  488 + if (i > spec.precision)
  489 + spec.precision = i;
459 490 /* leading space padding */
460   - size -= precision;
461   - if (!(type & (ZEROPAD+LEFT))) {
462   - while(--size >= 0) {
  491 + spec.field_width -= spec.precision;
  492 + if (!(spec.flags & (ZEROPAD+LEFT))) {
  493 + while(--spec.field_width >= 0) {
463 494 if (buf < end)
464 495 *buf = ' ';
465 496 ++buf;
466 497  
467 498  
... ... @@ -476,23 +507,23 @@
476 507 if (buf < end)
477 508 *buf = '0';
478 509 ++buf;
479   - if (base == 16) {
  510 + if (spec.base == 16) {
480 511 if (buf < end)
481 512 *buf = ('X' | locase);
482 513 ++buf;
483 514 }
484 515 }
485 516 /* zero or space padding */
486   - if (!(type & LEFT)) {
487   - char c = (type & ZEROPAD) ? '0' : ' ';
488   - while (--size >= 0) {
  517 + if (!(spec.flags & LEFT)) {
  518 + char c = (spec.flags & ZEROPAD) ? '0' : ' ';
  519 + while (--spec.field_width >= 0) {
489 520 if (buf < end)
490 521 *buf = c;
491 522 ++buf;
492 523 }
493 524 }
494 525 /* hmm even more zero padding? */
495   - while (i <= --precision) {
  526 + while (i <= --spec.precision) {
496 527 if (buf < end)
497 528 *buf = '0';
498 529 ++buf;
... ... @@ -504,7 +535,7 @@
504 535 ++buf;
505 536 }
506 537 /* trailing space padding */
507   - while (--size >= 0) {
  538 + while (--spec.field_width >= 0) {
508 539 if (buf < end)
509 540 *buf = ' ';
510 541 ++buf;
511 542  
512 543  
... ... @@ -512,17 +543,17 @@
512 543 return buf;
513 544 }
514 545  
515   -static char *string(char *buf, char *end, char *s, int field_width, int precision, int flags)
  546 +static char *string(char *buf, char *end, char *s, struct printf_spec spec)
516 547 {
517 548 int len, i;
518 549  
519 550 if ((unsigned long)s < PAGE_SIZE)
520 551 s = "<NULL>";
521 552  
522   - len = strnlen(s, precision);
  553 + len = strnlen(s, spec.precision);
523 554  
524   - if (!(flags & LEFT)) {
525   - while (len < field_width--) {
  555 + if (!(spec.flags & LEFT)) {
  556 + while (len < spec.field_width--) {
526 557 if (buf < end)
527 558 *buf = ' ';
528 559 ++buf;
... ... @@ -533,7 +564,7 @@
533 564 *buf = *s;
534 565 ++buf; ++s;
535 566 }
536   - while (len < field_width--) {
  567 + while (len < spec.field_width--) {
537 568 if (buf < end)
538 569 *buf = ' ';
539 570 ++buf;
540 571  
541 572  
542 573  
... ... @@ -541,21 +572,24 @@
541 572 return buf;
542 573 }
543 574  
544   -static char *symbol_string(char *buf, char *end, void *ptr, int field_width, int precision, int flags)
  575 +static char *symbol_string(char *buf, char *end, void *ptr,
  576 + struct printf_spec spec)
545 577 {
546 578 unsigned long value = (unsigned long) ptr;
547 579 #ifdef CONFIG_KALLSYMS
548 580 char sym[KSYM_SYMBOL_LEN];
549 581 sprint_symbol(sym, value);
550   - return string(buf, end, sym, field_width, precision, flags);
  582 + return string(buf, end, sym, spec);
551 583 #else
552   - field_width = 2*sizeof(void *);
553   - flags |= SPECIAL | SMALL | ZEROPAD;
554   - return number(buf, end, value, 16, field_width, precision, flags);
  584 + spec.field_width = 2*sizeof(void *);
  585 + spec.flags |= SPECIAL | SMALL | ZEROPAD;
  586 + spec.base = 16;
  587 + return number(buf, end, value, spec);
555 588 #endif
556 589 }
557 590  
558   -static char *resource_string(char *buf, char *end, struct resource *res, int field_width, int precision, int flags)
  591 +static char *resource_string(char *buf, char *end, struct resource *res,
  592 + struct printf_spec spec)
559 593 {
560 594 #ifndef IO_RSRC_PRINTK_SIZE
561 595 #define IO_RSRC_PRINTK_SIZE 4
... ... @@ -564,7 +598,11 @@
564 598 #ifndef MEM_RSRC_PRINTK_SIZE
565 599 #define MEM_RSRC_PRINTK_SIZE 8
566 600 #endif
567   -
  601 + struct printf_spec num_spec = {
  602 + .base = 16,
  603 + .precision = -1,
  604 + .flags = SPECIAL | SMALL | ZEROPAD,
  605 + };
568 606 /* room for the actual numbers, the two "0x", -, [, ] and the final zero */
569 607 char sym[4*sizeof(resource_size_t) + 8];
570 608 char *p = sym, *pend = sym + sizeof(sym);
571 609  
572 610  
573 611  
... ... @@ -576,17 +614,18 @@
576 614 size = MEM_RSRC_PRINTK_SIZE;
577 615  
578 616 *p++ = '[';
579   - p = number(p, pend, res->start, 16, size, -1, SPECIAL | SMALL | ZEROPAD);
  617 + num_spec.field_width = size;
  618 + p = number(p, pend, res->start, num_spec);
580 619 *p++ = '-';
581   - p = number(p, pend, res->end, 16, size, -1, SPECIAL | SMALL | ZEROPAD);
  620 + p = number(p, pend, res->end, num_spec);
582 621 *p++ = ']';
583 622 *p = 0;
584 623  
585   - return string(buf, end, sym, field_width, precision, flags);
  624 + return string(buf, end, sym, spec);
586 625 }
587 626  
588   -static char *mac_address_string(char *buf, char *end, u8 *addr, int field_width,
589   - int precision, int flags)
  627 +static char *mac_address_string(char *buf, char *end, u8 *addr,
  628 + struct printf_spec spec)
590 629 {
591 630 char mac_addr[6 * 3]; /* (6 * 2 hex digits), 5 colons and trailing zero */
592 631 char *p = mac_addr;
593 632  
594 633  
595 634  
... ... @@ -594,16 +633,17 @@
594 633  
595 634 for (i = 0; i < 6; i++) {
596 635 p = pack_hex_byte(p, addr[i]);
597   - if (!(flags & SPECIAL) && i != 5)
  636 + if (!(spec.flags & SPECIAL) && i != 5)
598 637 *p++ = ':';
599 638 }
600 639 *p = '\0';
  640 + spec.flags &= ~SPECIAL;
601 641  
602   - return string(buf, end, mac_addr, field_width, precision, flags & ~SPECIAL);
  642 + return string(buf, end, mac_addr, spec);
603 643 }
604 644  
605   -static char *ip6_addr_string(char *buf, char *end, u8 *addr, int field_width,
606   - int precision, int flags)
  645 +static char *ip6_addr_string(char *buf, char *end, u8 *addr,
  646 + struct printf_spec spec)
607 647 {
608 648 char ip6_addr[8 * 5]; /* (8 * 4 hex digits), 7 colons and trailing zero */
609 649 char *p = ip6_addr;
610 650  
611 651  
612 652  
... ... @@ -612,16 +652,17 @@
612 652 for (i = 0; i < 8; i++) {
613 653 p = pack_hex_byte(p, addr[2 * i]);
614 654 p = pack_hex_byte(p, addr[2 * i + 1]);
615   - if (!(flags & SPECIAL) && i != 7)
  655 + if (!(spec.flags & SPECIAL) && i != 7)
616 656 *p++ = ':';
617 657 }
618 658 *p = '\0';
  659 + spec.flags &= ~SPECIAL;
619 660  
620   - return string(buf, end, ip6_addr, field_width, precision, flags & ~SPECIAL);
  661 + return string(buf, end, ip6_addr, spec);
621 662 }
622 663  
623   -static char *ip4_addr_string(char *buf, char *end, u8 *addr, int field_width,
624   - int precision, int flags)
  664 +static char *ip4_addr_string(char *buf, char *end, u8 *addr,
  665 + struct printf_spec spec)
625 666 {
626 667 char ip4_addr[4 * 4]; /* (4 * 3 decimal digits), 3 dots and trailing zero */
627 668 char temp[3]; /* hold each IP quad in reverse order */
628 669  
... ... @@ -637,8 +678,9 @@
637 678 *p++ = '.';
638 679 }
639 680 *p = '\0';
  681 + spec.flags &= ~SPECIAL;
640 682  
641   - return string(buf, end, ip4_addr, field_width, precision, flags & ~SPECIAL);
  683 + return string(buf, end, ip4_addr, spec);
642 684 }
643 685  
644 686 /*
645 687  
646 688  
647 689  
648 690  
649 691  
650 692  
651 693  
652 694  
653 695  
654 696  
655 697  
... ... @@ -663,43 +705,235 @@
663 705 * function pointers are really function descriptors, which contain a
664 706 * pointer to the real address.
665 707 */
666   -static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field_width, int precision, int flags)
  708 +static char *pointer(const char *fmt, char *buf, char *end, void *ptr,
  709 + struct printf_spec spec)
667 710 {
668 711 if (!ptr)
669   - return string(buf, end, "(null)", field_width, precision, flags);
  712 + return string(buf, end, "(null)", spec);
670 713  
671 714 switch (*fmt) {
672 715 case 'F':
673 716 ptr = dereference_function_descriptor(ptr);
674 717 /* Fallthrough */
675 718 case 'S':
676   - return symbol_string(buf, end, ptr, field_width, precision, flags);
  719 + return symbol_string(buf, end, ptr, spec);
677 720 case 'R':
678   - return resource_string(buf, end, ptr, field_width, precision, flags);
  721 + return resource_string(buf, end, ptr, spec);
679 722 case 'm':
680   - flags |= SPECIAL;
  723 + spec.flags |= SPECIAL;
681 724 /* Fallthrough */
682 725 case 'M':
683   - return mac_address_string(buf, end, ptr, field_width, precision, flags);
  726 + return mac_address_string(buf, end, ptr, spec);
684 727 case 'i':
685   - flags |= SPECIAL;
  728 + spec.flags |= SPECIAL;
686 729 /* Fallthrough */
687 730 case 'I':
688 731 if (fmt[1] == '6')
689   - return ip6_addr_string(buf, end, ptr, field_width, precision, flags);
  732 + return ip6_addr_string(buf, end, ptr, spec);
690 733 if (fmt[1] == '4')
691   - return ip4_addr_string(buf, end, ptr, field_width, precision, flags);
692   - flags &= ~SPECIAL;
  734 + return ip4_addr_string(buf, end, ptr, spec);
  735 + spec.flags &= ~SPECIAL;
693 736 break;
694 737 }
695   - flags |= SMALL;
696   - if (field_width == -1) {
697   - field_width = 2*sizeof(void *);
698   - flags |= ZEROPAD;
  738 + spec.flags |= SMALL;
  739 + if (spec.field_width == -1) {
  740 + spec.field_width = 2*sizeof(void *);
  741 + spec.flags |= ZEROPAD;
699 742 }
700   - return number(buf, end, (unsigned long) ptr, 16, field_width, precision, flags);
  743 + spec.base = 16;
  744 +
  745 + return number(buf, end, (unsigned long) ptr, spec);
701 746 }
702 747  
  748 +/*
  749 + * Helper function to decode printf style format.
  750 + * Each call decode a token from the format and return the
  751 + * number of characters read (or likely the delta where it wants
  752 + * to go on the next call).
  753 + * The decoded token is returned through the parameters
  754 + *
  755 + * 'h', 'l', or 'L' for integer fields
  756 + * 'z' support added 23/7/1999 S.H.
  757 + * 'z' changed to 'Z' --davidm 1/25/99
  758 + * 't' added for ptrdiff_t
  759 + *
  760 + * @fmt: the format string
  761 + * @type of the token returned
  762 + * @flags: various flags such as +, -, # tokens..
  763 + * @field_width: overwritten width
  764 + * @base: base of the number (octal, hex, ...)
  765 + * @precision: precision of a number
  766 + * @qualifier: qualifier of a number (long, size_t, ...)
  767 + */
  768 +static int format_decode(const char *fmt, struct printf_spec *spec)
  769 +{
  770 + const char *start = fmt;
  771 +
  772 + /* we finished early by reading the field width */
  773 + if (spec->type == FORMAT_TYPE_WIDTH) {
  774 + if (spec->field_width < 0) {
  775 + spec->field_width = -spec->field_width;
  776 + spec->flags |= LEFT;
  777 + }
  778 + spec->type = FORMAT_TYPE_NONE;
  779 + goto precision;
  780 + }
  781 +
  782 + /* we finished early by reading the precision */
  783 + if (spec->type == FORMAT_TYPE_PRECISION) {
  784 + if (spec->precision < 0)
  785 + spec->precision = 0;
  786 +
  787 + spec->type = FORMAT_TYPE_NONE;
  788 + goto qualifier;
  789 + }
  790 +
  791 + /* By default */
  792 + spec->type = FORMAT_TYPE_NONE;
  793 +
  794 + for (; *fmt ; ++fmt) {
  795 + if (*fmt == '%')
  796 + break;
  797 + }
  798 +
  799 + /* Return the current non-format string */
  800 + if (fmt != start || !*fmt)
  801 + return fmt - start;
  802 +
  803 + /* Process flags */
  804 + spec->flags = 0;
  805 +
  806 + while (1) { /* this also skips first '%' */
  807 + bool found = true;
  808 +
  809 + ++fmt;
  810 +
  811 + switch (*fmt) {
  812 + case '-': spec->flags |= LEFT; break;
  813 + case '+': spec->flags |= PLUS; break;
  814 + case ' ': spec->flags |= SPACE; break;
  815 + case '#': spec->flags |= SPECIAL; break;
  816 + case '0': spec->flags |= ZEROPAD; break;
  817 + default: found = false;
  818 + }
  819 +
  820 + if (!found)
  821 + break;
  822 + }
  823 +
  824 + /* get field width */
  825 + spec->field_width = -1;
  826 +
  827 + if (isdigit(*fmt))
  828 + spec->field_width = skip_atoi(&fmt);
  829 + else if (*fmt == '*') {
  830 + /* it's the next argument */
  831 + spec->type = FORMAT_TYPE_WIDTH;
  832 + return ++fmt - start;
  833 + }
  834 +
  835 +precision:
  836 + /* get the precision */
  837 + spec->precision = -1;
  838 + if (*fmt == '.') {
  839 + ++fmt;
  840 + if (isdigit(*fmt)) {
  841 + spec->precision = skip_atoi(&fmt);
  842 + if (spec->precision < 0)
  843 + spec->precision = 0;
  844 + } else if (*fmt == '*') {
  845 + /* it's the next argument */
  846 + spec->type = FORMAT_TYPE_PRECISION;
  847 + return ++fmt - start;
  848 + }
  849 + }
  850 +
  851 +qualifier:
  852 + /* get the conversion qualifier */
  853 + spec->qualifier = -1;
  854 + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
  855 + *fmt == 'Z' || *fmt == 'z' || *fmt == 't') {
  856 + spec->qualifier = *fmt;
  857 + ++fmt;
  858 + if (spec->qualifier == 'l' && *fmt == 'l') {
  859 + spec->qualifier = 'L';
  860 + ++fmt;
  861 + }
  862 + }
  863 +
  864 + /* default base */
  865 + spec->base = 10;
  866 + switch (*fmt) {
  867 + case 'c':
  868 + spec->type = FORMAT_TYPE_CHAR;
  869 + return ++fmt - start;
  870 +
  871 + case 's':
  872 + spec->type = FORMAT_TYPE_STR;
  873 + return ++fmt - start;
  874 +
  875 + case 'p':
  876 + spec->type = FORMAT_TYPE_PTR;
  877 + return fmt - start;
  878 + /* skip alnum */
  879 +
  880 + case 'n':
  881 + spec->type = FORMAT_TYPE_NRCHARS;
  882 + return ++fmt - start;
  883 +
  884 + case '%':
  885 + spec->type = FORMAT_TYPE_PERCENT_CHAR;
  886 + return ++fmt - start;
  887 +
  888 + /* integer number formats - set up the flags and "break" */
  889 + case 'o':
  890 + spec->base = 8;
  891 + break;
  892 +
  893 + case 'x':
  894 + spec->flags |= SMALL;
  895 +
  896 + case 'X':
  897 + spec->base = 16;
  898 + break;
  899 +
  900 + case 'd':
  901 + case 'i':
  902 + spec->flags |= SIGN;
  903 + case 'u':
  904 + break;
  905 +
  906 + default:
  907 + spec->type = FORMAT_TYPE_INVALID;
  908 + return fmt - start;
  909 + }
  910 +
  911 + if (spec->qualifier == 'L')
  912 + spec->type = FORMAT_TYPE_LONG_LONG;
  913 + else if (spec->qualifier == 'l') {
  914 + if (spec->flags & SIGN)
  915 + spec->type = FORMAT_TYPE_LONG;
  916 + else
  917 + spec->type = FORMAT_TYPE_ULONG;
  918 + } else if (spec->qualifier == 'Z' || spec->qualifier == 'z') {
  919 + spec->type = FORMAT_TYPE_SIZE_T;
  920 + } else if (spec->qualifier == 't') {
  921 + spec->type = FORMAT_TYPE_PTRDIFF;
  922 + } else if (spec->qualifier == 'h') {
  923 + if (spec->flags & SIGN)
  924 + spec->type = FORMAT_TYPE_SHORT;
  925 + else
  926 + spec->type = FORMAT_TYPE_USHORT;
  927 + } else {
  928 + if (spec->flags & SIGN)
  929 + spec->type = FORMAT_TYPE_INT;
  930 + else
  931 + spec->type = FORMAT_TYPE_UINT;
  932 + }
  933 +
  934 + return ++fmt - start;
  935 +}
  936 +
703 937 /**
704 938 * vsnprintf - Format a string and place it in a buffer
705 939 * @buf: The buffer to place the result into
706 940  
707 941  
... ... @@ -726,19 +960,10 @@
726 960 int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
727 961 {
728 962 unsigned long long num;
729   - int base;
730 963 char *str, *end, c;
  964 + int read;
  965 + struct printf_spec spec = {0};
731 966  
732   - int flags; /* flags to number() */
733   -
734   - int field_width; /* width of output field */
735   - int precision; /* min. # of digits for integers; max
736   - number of chars for from string */
737   - int qualifier; /* 'h', 'l', or 'L' for integer fields */
738   - /* 'z' support added 23/7/1999 S.H. */
739   - /* 'z' changed to 'Z' --davidm 1/25/99 */
740   - /* 't' added for ptrdiff_t */
741   -
742 967 /* Reject out-of-range values early. Large positive sizes are
743 968 used for unknown buffer sizes. */
744 969 if (unlikely((int) size < 0)) {
745 970  
746 971  
747 972  
748 973  
749 974  
750 975  
751 976  
752 977  
753 978  
754 979  
755 980  
756 981  
757 982  
758 983  
759 984  
760 985  
761 986  
762 987  
763 988  
764 989  
765 990  
766 991  
767 992  
768 993  
... ... @@ -758,184 +983,144 @@
758 983 size = end - buf;
759 984 }
760 985  
761   - for (; *fmt ; ++fmt) {
762   - if (*fmt != '%') {
763   - if (str < end)
764   - *str = *fmt;
765   - ++str;
766   - continue;
767   - }
  986 + while (*fmt) {
  987 + const char *old_fmt = fmt;
768 988  
769   - /* process flags */
770   - flags = 0;
771   - repeat:
772   - ++fmt; /* this also skips first '%' */
773   - switch (*fmt) {
774   - case '-': flags |= LEFT; goto repeat;
775   - case '+': flags |= PLUS; goto repeat;
776   - case ' ': flags |= SPACE; goto repeat;
777   - case '#': flags |= SPECIAL; goto repeat;
778   - case '0': flags |= ZEROPAD; goto repeat;
779   - }
  989 + read = format_decode(fmt, &spec);
780 990  
781   - /* get field width */
782   - field_width = -1;
783   - if (isdigit(*fmt))
784   - field_width = skip_atoi(&fmt);
785   - else if (*fmt == '*') {
786   - ++fmt;
787   - /* it's the next argument */
788   - field_width = va_arg(args, int);
789   - if (field_width < 0) {
790   - field_width = -field_width;
791   - flags |= LEFT;
792   - }
793   - }
  991 + fmt += read;
794 992  
795   - /* get the precision */
796   - precision = -1;
797   - if (*fmt == '.') {
798   - ++fmt;
799   - if (isdigit(*fmt))
800   - precision = skip_atoi(&fmt);
801   - else if (*fmt == '*') {
802   - ++fmt;
803   - /* it's the next argument */
804   - precision = va_arg(args, int);
  993 + switch (spec.type) {
  994 + case FORMAT_TYPE_NONE: {
  995 + int copy = read;
  996 + if (str < end) {
  997 + if (copy > end - str)
  998 + copy = end - str;
  999 + memcpy(str, old_fmt, copy);
805 1000 }
806   - if (precision < 0)
807   - precision = 0;
  1001 + str += read;
  1002 + break;
808 1003 }
809 1004  
810   - /* get the conversion qualifier */
811   - qualifier = -1;
812   - if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
813   - *fmt =='Z' || *fmt == 'z' || *fmt == 't') {
814   - qualifier = *fmt;
815   - ++fmt;
816   - if (qualifier == 'l' && *fmt == 'l') {
817   - qualifier = 'L';
818   - ++fmt;
819   - }
820   - }
  1005 + case FORMAT_TYPE_WIDTH:
  1006 + spec.field_width = va_arg(args, int);
  1007 + break;
821 1008  
822   - /* default base */
823   - base = 10;
  1009 + case FORMAT_TYPE_PRECISION:
  1010 + spec.precision = va_arg(args, int);
  1011 + break;
824 1012  
825   - switch (*fmt) {
826   - case 'c':
827   - if (!(flags & LEFT)) {
828   - while (--field_width > 0) {
829   - if (str < end)
830   - *str = ' ';
831   - ++str;
832   - }
833   - }
834   - c = (unsigned char) va_arg(args, int);
835   - if (str < end)
836   - *str = c;
837   - ++str;
838   - while (--field_width > 0) {
  1013 + case FORMAT_TYPE_CHAR:
  1014 + if (!(spec.flags & LEFT)) {
  1015 + while (--spec.field_width > 0) {
839 1016 if (str < end)
840 1017 *str = ' ';
841 1018 ++str;
  1019 +
842 1020 }
843   - continue;
  1021 + }
  1022 + c = (unsigned char) va_arg(args, int);
  1023 + if (str < end)
  1024 + *str = c;
  1025 + ++str;
  1026 + while (--spec.field_width > 0) {
  1027 + if (str < end)
  1028 + *str = ' ';
  1029 + ++str;
  1030 + }
  1031 + break;
844 1032  
845   - case 's':
846   - str = string(str, end, va_arg(args, char *), field_width, precision, flags);
847   - continue;
  1033 + case FORMAT_TYPE_STR:
  1034 + str = string(str, end, va_arg(args, char *), spec);
  1035 + break;
848 1036  
849   - case 'p':
850   - str = pointer(fmt+1, str, end,
851   - va_arg(args, void *),
852   - field_width, precision, flags);
853   - /* Skip all alphanumeric pointer suffixes */
854   - while (isalnum(fmt[1]))
855   - fmt++;
856   - continue;
  1037 + case FORMAT_TYPE_PTR:
  1038 + str = pointer(fmt+1, str, end, va_arg(args, void *),
  1039 + spec);
  1040 + while (isalnum(*fmt))
  1041 + fmt++;
  1042 + break;
857 1043  
858   - case 'n':
859   - /* FIXME:
860   - * What does C99 say about the overflow case here? */
861   - if (qualifier == 'l') {
862   - long * ip = va_arg(args, long *);
863   - *ip = (str - buf);
864   - } else if (qualifier == 'Z' || qualifier == 'z') {
865   - size_t * ip = va_arg(args, size_t *);
866   - *ip = (str - buf);
867   - } else {
868   - int * ip = va_arg(args, int *);
869   - *ip = (str - buf);
870   - }
871   - continue;
  1044 + case FORMAT_TYPE_PERCENT_CHAR:
  1045 + if (str < end)
  1046 + *str = '%';
  1047 + ++str;
  1048 + break;
872 1049  
873   - case '%':
  1050 + case FORMAT_TYPE_INVALID:
  1051 + if (str < end)
  1052 + *str = '%';
  1053 + ++str;
  1054 + if (*fmt) {
874 1055 if (str < end)
875   - *str = '%';
  1056 + *str = *fmt;
876 1057 ++str;
877   - continue;
  1058 + } else {
  1059 + --fmt;
  1060 + }
  1061 + break;
878 1062  
879   - /* integer number formats - set up the flags and "break" */
880   - case 'o':
881   - base = 8;
882   - break;
  1063 + case FORMAT_TYPE_NRCHARS: {
  1064 + int qualifier = spec.qualifier;
883 1065  
884   - case 'x':
885   - flags |= SMALL;
886   - case 'X':
887   - base = 16;
888   - break;
  1066 + if (qualifier == 'l') {
  1067 + long *ip = va_arg(args, long *);
  1068 + *ip = (str - buf);
  1069 + } else if (qualifier == 'Z' ||
  1070 + qualifier == 'z') {
  1071 + size_t *ip = va_arg(args, size_t *);
  1072 + *ip = (str - buf);
  1073 + } else {
  1074 + int *ip = va_arg(args, int *);
  1075 + *ip = (str - buf);
  1076 + }
  1077 + break;
  1078 + }
889 1079  
890   - case 'd':
891   - case 'i':
892   - flags |= SIGN;
893   - case 'u':
  1080 + default:
  1081 + switch (spec.type) {
  1082 + case FORMAT_TYPE_LONG_LONG:
  1083 + num = va_arg(args, long long);
894 1084 break;
895   -
  1085 + case FORMAT_TYPE_ULONG:
  1086 + num = va_arg(args, unsigned long);
  1087 + break;
  1088 + case FORMAT_TYPE_LONG:
  1089 + num = va_arg(args, long);
  1090 + break;
  1091 + case FORMAT_TYPE_SIZE_T:
  1092 + num = va_arg(args, size_t);
  1093 + break;
  1094 + case FORMAT_TYPE_PTRDIFF:
  1095 + num = va_arg(args, ptrdiff_t);
  1096 + break;
  1097 + case FORMAT_TYPE_USHORT:
  1098 + num = (unsigned short) va_arg(args, int);
  1099 + break;
  1100 + case FORMAT_TYPE_SHORT:
  1101 + num = (short) va_arg(args, int);
  1102 + break;
  1103 + case FORMAT_TYPE_INT:
  1104 + num = (int) va_arg(args, int);
  1105 + break;
896 1106 default:
897   - if (str < end)
898   - *str = '%';
899   - ++str;
900   - if (*fmt) {
901   - if (str < end)
902   - *str = *fmt;
903   - ++str;
904   - } else {
905   - --fmt;
906   - }
907   - continue;
  1107 + num = va_arg(args, unsigned int);
  1108 + }
  1109 +
  1110 + str = number(str, end, num, spec);
908 1111 }
909   - if (qualifier == 'L')
910   - num = va_arg(args, long long);
911   - else if (qualifier == 'l') {
912   - num = va_arg(args, unsigned long);
913   - if (flags & SIGN)
914   - num = (signed long) num;
915   - } else if (qualifier == 'Z' || qualifier == 'z') {
916   - num = va_arg(args, size_t);
917   - } else if (qualifier == 't') {
918   - num = va_arg(args, ptrdiff_t);
919   - } else if (qualifier == 'h') {
920   - num = (unsigned short) va_arg(args, int);
921   - if (flags & SIGN)
922   - num = (signed short) num;
923   - } else {
924   - num = va_arg(args, unsigned int);
925   - if (flags & SIGN)
926   - num = (signed int) num;
927   - }
928   - str = number(str, end, num, base,
929   - field_width, precision, flags);
930 1112 }
  1113 +
931 1114 if (size > 0) {
932 1115 if (str < end)
933 1116 *str = '\0';
934 1117 else
935 1118 end[-1] = '\0';
936 1119 }
  1120 +
937 1121 /* the trailing null byte doesn't count towards the total */
938 1122 return str-buf;
  1123 +
939 1124 }
940 1125 EXPORT_SYMBOL(vsnprintf);
941 1126  
... ... @@ -1057,6 +1242,372 @@
1057 1242 return i;
1058 1243 }
1059 1244 EXPORT_SYMBOL(sprintf);
  1245 +
  1246 +#ifdef CONFIG_BINARY_PRINTF
  1247 +/*
  1248 + * bprintf service:
  1249 + * vbin_printf() - VA arguments to binary data
  1250 + * bstr_printf() - Binary data to text string
  1251 + */
  1252 +
  1253 +/**
  1254 + * vbin_printf - Parse a format string and place args' binary value in a buffer
  1255 + * @bin_buf: The buffer to place args' binary value
  1256 + * @size: The size of the buffer(by words(32bits), not characters)
  1257 + * @fmt: The format string to use
  1258 + * @args: Arguments for the format string
  1259 + *
  1260 + * The format follows C99 vsnprintf, except %n is ignored, and its argument
  1261 + * is skiped.
  1262 + *
  1263 + * The return value is the number of words(32bits) which would be generated for
  1264 + * the given input.
  1265 + *
  1266 + * NOTE:
  1267 + * If the return value is greater than @size, the resulting bin_buf is NOT
  1268 + * valid for bstr_printf().
  1269 + */
  1270 +int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args)
  1271 +{
  1272 + struct printf_spec spec = {0};
  1273 + char *str, *end;
  1274 + int read;
  1275 +
  1276 + str = (char *)bin_buf;
  1277 + end = (char *)(bin_buf + size);
  1278 +
  1279 +#define save_arg(type) \
  1280 +do { \
  1281 + if (sizeof(type) == 8) { \
  1282 + unsigned long long value; \
  1283 + str = PTR_ALIGN(str, sizeof(u32)); \
  1284 + value = va_arg(args, unsigned long long); \
  1285 + if (str + sizeof(type) <= end) { \
  1286 + *(u32 *)str = *(u32 *)&value; \
  1287 + *(u32 *)(str + 4) = *((u32 *)&value + 1); \
  1288 + } \
  1289 + } else { \
  1290 + unsigned long value; \
  1291 + str = PTR_ALIGN(str, sizeof(type)); \
  1292 + value = va_arg(args, int); \
  1293 + if (str + sizeof(type) <= end) \
  1294 + *(typeof(type) *)str = (type)value; \
  1295 + } \
  1296 + str += sizeof(type); \
  1297 +} while (0)
  1298 +
  1299 +
  1300 + while (*fmt) {
  1301 + read = format_decode(fmt, &spec);
  1302 +
  1303 + fmt += read;
  1304 +
  1305 + switch (spec.type) {
  1306 + case FORMAT_TYPE_NONE:
  1307 + break;
  1308 +
  1309 + case FORMAT_TYPE_WIDTH:
  1310 + case FORMAT_TYPE_PRECISION:
  1311 + save_arg(int);
  1312 + break;
  1313 +
  1314 + case FORMAT_TYPE_CHAR:
  1315 + save_arg(char);
  1316 + break;
  1317 +
  1318 + case FORMAT_TYPE_STR: {
  1319 + const char *save_str = va_arg(args, char *);
  1320 + size_t len;
  1321 + if ((unsigned long)save_str > (unsigned long)-PAGE_SIZE
  1322 + || (unsigned long)save_str < PAGE_SIZE)
  1323 + save_str = "<NULL>";
  1324 + len = strlen(save_str);
  1325 + if (str + len + 1 < end)
  1326 + memcpy(str, save_str, len + 1);
  1327 + str += len + 1;
  1328 + break;
  1329 + }
  1330 +
  1331 + case FORMAT_TYPE_PTR:
  1332 + save_arg(void *);
  1333 + /* skip all alphanumeric pointer suffixes */
  1334 + while (isalnum(*fmt))
  1335 + fmt++;
  1336 + break;
  1337 +
  1338 + case FORMAT_TYPE_PERCENT_CHAR:
  1339 + break;
  1340 +
  1341 + case FORMAT_TYPE_INVALID:
  1342 + if (!*fmt)
  1343 + --fmt;
  1344 + break;
  1345 +
  1346 + case FORMAT_TYPE_NRCHARS: {
  1347 + /* skip %n 's argument */
  1348 + int qualifier = spec.qualifier;
  1349 + void *skip_arg;
  1350 + if (qualifier == 'l')
  1351 + skip_arg = va_arg(args, long *);
  1352 + else if (qualifier == 'Z' || qualifier == 'z')
  1353 + skip_arg = va_arg(args, size_t *);
  1354 + else
  1355 + skip_arg = va_arg(args, int *);
  1356 + break;
  1357 + }
  1358 +
  1359 + default:
  1360 + switch (spec.type) {
  1361 +
  1362 + case FORMAT_TYPE_LONG_LONG:
  1363 + save_arg(long long);
  1364 + break;
  1365 + case FORMAT_TYPE_ULONG:
  1366 + case FORMAT_TYPE_LONG:
  1367 + save_arg(unsigned long);
  1368 + break;
  1369 + case FORMAT_TYPE_SIZE_T:
  1370 + save_arg(size_t);
  1371 + break;
  1372 + case FORMAT_TYPE_PTRDIFF:
  1373 + save_arg(ptrdiff_t);
  1374 + break;
  1375 + case FORMAT_TYPE_USHORT:
  1376 + case FORMAT_TYPE_SHORT:
  1377 + save_arg(short);
  1378 + break;
  1379 + default:
  1380 + save_arg(int);
  1381 + }
  1382 + }
  1383 + }
  1384 + return (u32 *)(PTR_ALIGN(str, sizeof(u32))) - bin_buf;
  1385 +
  1386 +#undef save_arg
  1387 +}
  1388 +EXPORT_SYMBOL_GPL(vbin_printf);
  1389 +
  1390 +/**
  1391 + * bstr_printf - Format a string from binary arguments and place it in a buffer
  1392 + * @buf: The buffer to place the result into
  1393 + * @size: The size of the buffer, including the trailing null space
  1394 + * @fmt: The format string to use
  1395 + * @bin_buf: Binary arguments for the format string
  1396 + *
  1397 + * This function like C99 vsnprintf, but the difference is that vsnprintf gets
  1398 + * arguments from stack, and bstr_printf gets arguments from @bin_buf which is
  1399 + * a binary buffer that generated by vbin_printf.
  1400 + *
  1401 + * The format follows C99 vsnprintf, but has some extensions:
  1402 + * %pS output the name of a text symbol
  1403 + * %pF output the name of a function pointer
  1404 + * %pR output the address range in a struct resource
  1405 + * %n is ignored
  1406 + *
  1407 + * The return value is the number of characters which would
  1408 + * be generated for the given input, excluding the trailing
  1409 + * '\0', as per ISO C99. If you want to have the exact
  1410 + * number of characters written into @buf as return value
  1411 + * (not including the trailing '\0'), use vscnprintf(). If the
  1412 + * return is greater than or equal to @size, the resulting
  1413 + * string is truncated.
  1414 + */
  1415 +int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
  1416 +{
  1417 + unsigned long long num;
  1418 + char *str, *end, c;
  1419 + const char *args = (const char *)bin_buf;
  1420 +
  1421 + struct printf_spec spec = {0};
  1422 +
  1423 + if (unlikely((int) size < 0)) {
  1424 + /* There can be only one.. */
  1425 + static char warn = 1;
  1426 + WARN_ON(warn);
  1427 + warn = 0;
  1428 + return 0;
  1429 + }
  1430 +
  1431 + str = buf;
  1432 + end = buf + size;
  1433 +
  1434 +#define get_arg(type) \
  1435 +({ \
  1436 + typeof(type) value; \
  1437 + if (sizeof(type) == 8) { \
  1438 + args = PTR_ALIGN(args, sizeof(u32)); \
  1439 + *(u32 *)&value = *(u32 *)args; \
  1440 + *((u32 *)&value + 1) = *(u32 *)(args + 4); \
  1441 + } else { \
  1442 + args = PTR_ALIGN(args, sizeof(type)); \
  1443 + value = *(typeof(type) *)args; \
  1444 + } \
  1445 + args += sizeof(type); \
  1446 + value; \
  1447 +})
  1448 +
  1449 + /* Make sure end is always >= buf */
  1450 + if (end < buf) {
  1451 + end = ((void *)-1);
  1452 + size = end - buf;
  1453 + }
  1454 +
  1455 + while (*fmt) {
  1456 + int read;
  1457 + const char *old_fmt = fmt;
  1458 +
  1459 + read = format_decode(fmt, &spec);
  1460 +
  1461 + fmt += read;
  1462 +
  1463 + switch (spec.type) {
  1464 + case FORMAT_TYPE_NONE: {
  1465 + int copy = read;
  1466 + if (str < end) {
  1467 + if (copy > end - str)
  1468 + copy = end - str;
  1469 + memcpy(str, old_fmt, copy);
  1470 + }
  1471 + str += read;
  1472 + break;
  1473 + }
  1474 +
  1475 + case FORMAT_TYPE_WIDTH:
  1476 + spec.field_width = get_arg(int);
  1477 + break;
  1478 +
  1479 + case FORMAT_TYPE_PRECISION:
  1480 + spec.precision = get_arg(int);
  1481 + break;
  1482 +
  1483 + case FORMAT_TYPE_CHAR:
  1484 + if (!(spec.flags & LEFT)) {
  1485 + while (--spec.field_width > 0) {
  1486 + if (str < end)
  1487 + *str = ' ';
  1488 + ++str;
  1489 + }
  1490 + }
  1491 + c = (unsigned char) get_arg(char);
  1492 + if (str < end)
  1493 + *str = c;
  1494 + ++str;
  1495 + while (--spec.field_width > 0) {
  1496 + if (str < end)
  1497 + *str = ' ';
  1498 + ++str;
  1499 + }
  1500 + break;
  1501 +
  1502 + case FORMAT_TYPE_STR: {
  1503 + const char *str_arg = args;
  1504 + size_t len = strlen(str_arg);
  1505 + args += len + 1;
  1506 + str = string(str, end, (char *)str_arg, spec);
  1507 + break;
  1508 + }
  1509 +
  1510 + case FORMAT_TYPE_PTR:
  1511 + str = pointer(fmt+1, str, end, get_arg(void *), spec);
  1512 + while (isalnum(*fmt))
  1513 + fmt++;
  1514 + break;
  1515 +
  1516 + case FORMAT_TYPE_PERCENT_CHAR:
  1517 + if (str < end)
  1518 + *str = '%';
  1519 + ++str;
  1520 + break;
  1521 +
  1522 + case FORMAT_TYPE_INVALID:
  1523 + if (str < end)
  1524 + *str = '%';
  1525 + ++str;
  1526 + if (*fmt) {
  1527 + if (str < end)
  1528 + *str = *fmt;
  1529 + ++str;
  1530 + } else {
  1531 + --fmt;
  1532 + }
  1533 + break;
  1534 +
  1535 + case FORMAT_TYPE_NRCHARS:
  1536 + /* skip */
  1537 + break;
  1538 +
  1539 + default:
  1540 + switch (spec.type) {
  1541 +
  1542 + case FORMAT_TYPE_LONG_LONG:
  1543 + num = get_arg(long long);
  1544 + break;
  1545 + case FORMAT_TYPE_ULONG:
  1546 + num = get_arg(unsigned long);
  1547 + break;
  1548 + case FORMAT_TYPE_LONG:
  1549 + num = get_arg(unsigned long);
  1550 + break;
  1551 + case FORMAT_TYPE_SIZE_T:
  1552 + num = get_arg(size_t);
  1553 + break;
  1554 + case FORMAT_TYPE_PTRDIFF:
  1555 + num = get_arg(ptrdiff_t);
  1556 + break;
  1557 + case FORMAT_TYPE_USHORT:
  1558 + num = get_arg(unsigned short);
  1559 + break;
  1560 + case FORMAT_TYPE_SHORT:
  1561 + num = get_arg(short);
  1562 + break;
  1563 + case FORMAT_TYPE_UINT:
  1564 + num = get_arg(unsigned int);
  1565 + break;
  1566 + default:
  1567 + num = get_arg(int);
  1568 + }
  1569 +
  1570 + str = number(str, end, num, spec);
  1571 + }
  1572 + }
  1573 +
  1574 + if (size > 0) {
  1575 + if (str < end)
  1576 + *str = '\0';
  1577 + else
  1578 + end[-1] = '\0';
  1579 + }
  1580 +
  1581 +#undef get_arg
  1582 +
  1583 + /* the trailing null byte doesn't count towards the total */
  1584 + return str - buf;
  1585 +}
  1586 +EXPORT_SYMBOL_GPL(bstr_printf);
  1587 +
  1588 +/**
  1589 + * bprintf - Parse a format string and place args' binary value in a buffer
  1590 + * @bin_buf: The buffer to place args' binary value
  1591 + * @size: The size of the buffer(by words(32bits), not characters)
  1592 + * @fmt: The format string to use
  1593 + * @...: Arguments for the format string
  1594 + *
  1595 + * The function returns the number of words(u32) written
  1596 + * into @bin_buf.
  1597 + */
  1598 +int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...)
  1599 +{
  1600 + va_list args;
  1601 + int ret;
  1602 +
  1603 + va_start(args, fmt);
  1604 + ret = vbin_printf(bin_buf, size, fmt, args);
  1605 + va_end(args);
  1606 + return ret;
  1607 +}
  1608 +EXPORT_SYMBOL_GPL(bprintf);
  1609 +
  1610 +#endif /* CONFIG_BINARY_PRINTF */
1060 1611  
1061 1612 /**
1062 1613 * vsscanf - Unformat a buffer into a list of arguments