This is the mail archive of the newlib@sources.redhat.com mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

%S %C vfprintf contribution


Hello.

Here is the patch that makes vfprintf (and hence, all other vfprintf-based Xprintf functions) understand ISO C 90 %S (same as %ls) and %C (same as %lc) format placeholders. Please, review it and give us know if something is wrong.

This is tested a little bit- it works and it seems should work with any locale if wcrtomb and wcsrtomb functions work.

--
Best regards,
Artem B. Bityuckiy
SoftMine Corporation, Software Engineer
Tel.: +7(812)329-67-44, +7(812)329-67-45
Mobile: +79112449030
E-mail: abitytsky@softminecorp.com
Web: www.softminecorp.com

164a165
> #include <limits.h>
240c241,246
< #define	BUF		(MAXEXP+MAXFRACT+1)	/* + decimal point */
---
> #if ((MAXEXP+MAXFRACT+1) > MB_LEN_MAX)
> #  define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */
> #else 
> #  define BUF MB_LEN_MAX
> #endif
> 
248c254,258
< #define	BUF		40
---
> #if (MB_LEN_MAX < 40)
> #  define BUF 40
> #else
> #  define BUF MB_LEN_MAX
> #endif
271a282
> #define WIDECHARSTR     0x200           /* Widechar string */
523c534,549
< 			*(cp = buf) = va_arg(ap, int);
---
>                 case 'C':
>                         cp = buf;
>                         if (*fmt == 'C' || (flags & LONGINT))
>                         {
>                             mbstate_t ps;
> 
>                             memset((void *)&ps, '\0', sizeof(mbstate_t));
>                             if ((size = (int)wcrtomb(cp, 
>                                      (wchar_t)va_arg(ap, int);, &ps)) == -1)
>                                 goto error; 
>                         }
>                         else
>                         {
>                             *cp = (char)va_arg(ap, int);
>                             size = 1;
>                         }
647,648c673,731
< 			if ((cp = va_arg(ap, char *)) == NULL)
< 				cp = "(null)";
---
>                 case 'S':
> 		        sign = '\0';
>                         cp = va_arg(ap, char *);
> 
>                         if (cp && (ch == 'S' || (flags & LONGINT))) {
>                             mbstate_t ps;
>                             _CONST wchar_t *wcp;
> 
>                             wcp = (_CONST wchar_t *)cp;
>                             size = m = 0;
>                             memset((void *)&ps, '\0', sizeof(mbstate_t));
> 
>                             /* 
>                              * Count number of bytes needed to store multibyte
>                              * string that will be produced from widechar
>                              * string.
>                              */
>                             if (prec >= 0) {
>                                 while (1) {
>                                     if (wcp[m] == L'\0')
>                                         break;
>                                     if ((n = wcrtomb(buf, wcp[m], &ps)) == -1)
>                                         goto error;
>                                     if (n + size > prec)
>                                         break;
>                                     m += 1;
>                                     size += n;
>                                     if (size == prec)
>                                         break;
>                                 }
>                             }
>                             else {
>                                 size = wcsrtombs(NULL, &wcp, 0, &ps);
>                                 if (size == -1)
>                                     goto error; 
>                                 wcp = (_CONST wchar_t *)cp;
>                             }
> 
>                             if (size == 0)
>                                 break;
> 
>                             if ((cp = (char *)malloc(size + 1)) == NULL)
>                                 goto error;
>                             
>                             flags |= WIDECHARSTR;
> 
>                             /*
>                              * Convert widechar string to multibyte string.
>                              */
>                             memset((void *)&ps, '\0', sizeof(mbstate_t));
>                             if (wcsrtombs(cp, &wcp, size, &ps) != size)
>                                 goto error;
>                             cp[size] = '\0';
>                             break;
>                         }
> 
> 			if (cp == NULL)
> 			    cp = "(null)";
> 
665d747
< 			sign = '\0';
848a931,933
> 
>                 if (flags & WIDECHARSTR)
>                     free(cp);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]