]>
git.saurik.com Git - apple/libc.git/blob - stdio/FreeBSD/xprintf_str.c
   2  * Copyright (c) 2005 Poul-Henning Kamp 
   3  * Copyright (c) 1990, 1993 
   4  *      The Regents of the University of California.  All rights reserved. 
   6  * This code is derived from software contributed to Berkeley by 
   9  * Redistribution and use in source and binary forms, with or without 
  10  * modification, are permitted provided that the following conditions 
  12  * 1. Redistributions of source code must retain the above copyright 
  13  *    notice, this list of conditions and the following disclaimer. 
  14  * 2. Redistributions in binary form must reproduce the above copyright 
  15  *    notice, this list of conditions and the following disclaimer in the 
  16  *    documentation and/or other materials provided with the distribution. 
  17  * 3. Neither the name of the University nor the names of its contributors 
  18  *    may be used to endorse or promote products derived from this software 
  19  *    without specific prior written permission. 
  21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 
  22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
  24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 
  25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
  26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
  27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
  28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
  29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
  30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
  33  * $FreeBSD: src/lib/libc/stdio/xprintf_str.c,v 1.1 2005/12/16 18:56:38 phk Exp $ 
  36 #include <namespace.h> 
  45 #include "xprintf_private.h" 
  48  * Convert a wide character string argument for the %ls format to a multibyte 
  49  * string representation. If not -1, prec specifies the maximum number of 
  50  * bytes to output, and also means that we can't assume that the wide char. 
  51  * string ends is null-terminated. 
  54 __wcsconv(wchar_t *wcsarg
, int prec
, locale_t loc
) 
  56         static const mbstate_t initial
; 
  63         /* Allocate space for the maximum number of bytes we could output. */ 
  67                 nbytes 
= wcsrtombs_l(NULL
, (const wchar_t **)&p
, 0, &mbs
, loc
); 
  68                 if (nbytes 
== (size_t)-1) 
  72                  * Optimisation: if the output precision is small enough, 
  73                  * just allocate enough memory for the maximum instead of 
  74                  * scanning the string. 
  83                                 clen 
= wcrtomb_l(buf
, *p
++, &mbs
, loc
); 
  84                                 if (clen 
== 0 || clen 
== (size_t)-1 || 
  85                                     (int)(nbytes 
+ clen
) > prec
) 
  91         if ((convbuf 
= MALLOC(nbytes 
+ 1)) == NULL
) 
  94         /* Fill the output buffer. */ 
  97         if ((nbytes 
= wcsrtombs_l(convbuf
, (const wchar_t **)&p
, 
  98             nbytes
, &mbs
, loc
)) == (size_t)-1) { 
 102         convbuf
[nbytes
] = '\0'; 
 107 /* 's' ---------------------------------------------------------------*/ 
 109 __private_extern__ 
int 
 110 __printf_arginfo_str(const struct printf_info 
*pi
, size_t n
, int *argt
) 
 114         if (pi
->is_long 
|| pi
->spec 
== 'C') 
 115                 argt
[0] = PA_WSTRING
; 
 121 __private_extern__ 
int 
 122 __printf_render_str(struct __printf_io 
*io
, const struct printf_info 
*pi
, const void *const *arg
) 
 129         if (pi
->is_long 
|| pi
->spec 
== 'S') { 
 130                 wcp 
= *((wint_t **)arg
[0]); 
 132                         return (__printf_out(io
, pi
, "(null)", 6)); 
 133                 convbuf 
= __wcsconv(wcp
, pi
->prec
, pi
->loc
); 
 136                 l 
= __printf_out(io
, pi
, convbuf
, strlen(convbuf
)); 
 141         p 
= *((char **)arg
[0]); 
 143                 return (__printf_out(io
, pi
, "(null)", 6)); 
 145         if (pi
->prec 
>= 0 && pi
->prec 
< l
) 
 147         return (__printf_out(io
, pi
, p
, l
)); 
 150 /* 'c' ---------------------------------------------------------------*/ 
 152 __private_extern__ 
int 
 153 __printf_arginfo_chr(const struct printf_info 
*pi
, size_t n
, int *argt
) 
 162         if (pi
->is_long 
|| pi
->spec 
== 'C') 
 169 __private_extern__ 
int 
 170 __printf_render_chr(struct __printf_io 
*io
, const struct printf_info 
*pi
, const void *const *arg
) 
 175         static const mbstate_t initial
;         /* XXX: this is bogus! */ 
 178         char buf
[MB_CUR_MAX_L(pi
->loc
)]; 
 181         if (pi
->is_vec
) return __xprintf_vector(io
, pi
, arg
); 
 184         if (pi
->is_long 
|| pi
->spec 
== 'C') { 
 186                 ii 
= *((wint_t *)arg
[0]); 
 189                 mbseqlen 
= wcrtomb_l(buf
, (wchar_t)ii
, &mbs
, pi
->loc
); 
 190                 if (mbseqlen 
== (size_t) -1) 
 192                 ret 
= __printf_out(io
, pi
, buf
, mbseqlen
); 
 196         i 
= *((int *)arg
[0]); 
 198         i 
= __printf_out(io
, pi
, &c
, 1);