Clang knows about %b modifier and can do some semantic analysis on it.
Currently it type checks the first arg to be an int and the second to be
a char*.

Do you think it would be worth modifying the checks to include
this new functionality? Do you think you would like to take a stab
at it? 

Search for FreeBSDbArg in contrib/llvm/tools/clang/lib/Sema/SemaChecking.cpp
if you want to take a look.

Thanks, Roman

On Wed, Jul 12, 2017 at 07:30:14AM +0000, Ryan Libby wrote:
> Author: rlibby
> Date: Wed Jul 12 07:30:14 2017
> New Revision: 320908
> URL: https://svnweb.freebsd.org/changeset/base/320908
> 
> Log:
>   kvprintf %b enhancements
>   
>   Make the %b formatter accept number formatting flags. It will now accept
>   alternate form, precision, and length modifiers. It also now partially
>   supports field width (but forces left justification).
>   
>   Reviewed by:        markj
>   Approved by:        markj (mentor)
>   Sponsored by:       Dell EMC Isilon
>   Differential Revision:      https://reviews.freebsd.org/D11284
> 
> Modified:
>   head/sys/kern/subr_prf.c
> 
> Modified: head/sys/kern/subr_prf.c
> ==============================================================================
> --- head/sys/kern/subr_prf.c  Wed Jul 12 07:26:07 2017        (r320907)
> +++ head/sys/kern/subr_prf.c  Wed Jul 12 07:30:14 2017        (r320908)
> @@ -650,7 +650,7 @@ kvprintf(char const *fmt, void (*func)(int, void*), vo
>       uintmax_t num;
>       int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
>       int cflag, hflag, jflag, tflag, zflag;
> -     int dwidth, upper;
> +     int bconv, dwidth, upper;
>       char padc;
>       int stop = 0, retval = 0;
>  
> @@ -676,7 +676,7 @@ kvprintf(char const *fmt, void (*func)(int, void*), vo
>               }
>               percent = fmt - 1;
>               qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
> -             sign = 0; dot = 0; dwidth = 0; upper = 0;
> +             sign = 0; dot = 0; bconv = 0; dwidth = 0; upper = 0;
>               cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
>  reswitch:    switch (ch = (u_char)*fmt++) {
>               case '.':
> @@ -724,28 +724,9 @@ reswitch:        switch (ch = (u_char)*fmt++) {
>                               width = n;
>                       goto reswitch;
>               case 'b':
> -                     num = (u_int)va_arg(ap, int);
> -                     p = va_arg(ap, char *);
> -                     for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;)
> -                             PCHAR(*q--);
> -
> -                     if (num == 0)
> -                             break;
> -
> -                     for (tmp = 0; *p;) {
> -                             n = *p++;
> -                             if (num & (1 << (n - 1))) {
> -                                     PCHAR(tmp ? ',' : '<');
> -                                     for (; (n = *p) > ' '; ++p)
> -                                             PCHAR(n);
> -                                     tmp = 1;
> -                             } else
> -                                     for (; *p > ' '; ++p)
> -                                             continue;
> -                     }
> -                     if (tmp)
> -                             PCHAR('>');
> -                     break;
> +                     ladjust = 1;
> +                     bconv = 1;
> +                     goto handle_nosign;
>               case 'c':
>                       width -= 1;
>  
> @@ -883,6 +864,10 @@ handle_nosign:
>                               num = (u_char)va_arg(ap, int);
>                       else
>                               num = va_arg(ap, u_int);
> +                     if (bconv) {
> +                             q = va_arg(ap, char *);
> +                             base = *q++;
> +                     }
>                       goto number;
>  handle_sign:
>                       if (jflag)
> @@ -939,6 +924,26 @@ number:
>  
>                       while (*p)
>                               PCHAR(*p--);
> +
> +                     if (bconv && num != 0) {
> +                             /* %b conversion flag format. */
> +                             tmp = retval;
> +                             while (*q) {
> +                                     n = *q++;
> +                                     if (num & (1 << (n - 1))) {
> +                                             PCHAR(retval != tmp ?
> +                                                 ',' : '<');
> +                                             for (; (n = *q) > ' '; ++q)
> +                                                     PCHAR(n);
> +                                     } else
> +                                             for (; *q > ' '; ++q)
> +                                                     continue;
> +                             }
> +                             if (retval != tmp) {
> +                                     PCHAR('>');
> +                                     width -= retval - tmp;
> +                             }
> +                     }
>  
>                       if (ladjust)
>                               while (width-- > 0)
> _______________________________________________
> svn-src-head@freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/svn-src-head
> To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to