Home | History | Annotate | Download | only in Stdio
      1 /*
      2  * Copyright (c) 1997 Todd C. Miller <Todd.Miller (at) courtesan.com>
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  * 3. The name of the author may not be used to endorse or promote products
     14  *    derived from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
     17  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
     18  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
     19  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26 
     27   FreeBSD: src/lib/libc/stdio/vswprintf.c,v 1.6 2005/02/21 19:41:44 fjoe Exp
     28   NetBSD: vswprintf.c,v 1.1 2005/05/14 23:51:02 christos Exp
     29  */
     30 #include  <LibConfig.h>
     31 #include  <sys/EfiCdefs.h>
     32 
     33 #include  <errno.h>
     34 #include  <stdio.h>
     35 #include  <stdlib.h>
     36 #include  <wchar.h>
     37 #include  <stdarg.h>
     38 #include  "reentrant.h"
     39 #include  "local.h"
     40 
     41 int
     42 vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt,
     43     va_list ap)
     44 {
     45   static const mbstate_t initial = { 0 };
     46   mbstate_t mbs;
     47   FILE f;
     48   char *mbp;
     49   int ret, sverrno;
     50   size_t nwc;
     51   struct __sfileext fext;
     52 
     53   if (n == 0) {
     54     errno = EINVAL;
     55     return (-1);
     56   }
     57 
     58   _FILEEXT_SETUP(&f, &fext);
     59   f._file = -1;
     60   f._flags = __SWR | __SSTR | __SALC;
     61   f._bf._base = f._p = (unsigned char *)malloc(128);
     62   if (f._bf._base == NULL) {
     63     errno = ENOMEM;
     64     return (-1);
     65   }
     66   f._bf._size = f._w = 127;   /* Leave room for the NUL */
     67   ret = __vfwprintf_unlocked(&f, fmt, ap);
     68   if (ret < 0) {
     69     sverrno = errno;
     70     free(f._bf._base);
     71     errno = sverrno;
     72     return (-1);
     73   }
     74   *f._p = '\0';
     75   mbp = (char *)f._bf._base;
     76   /*
     77    * XXX Undo the conversion from wide characters to multibyte that
     78    * fputwc() did in __vfwprintf().
     79    */
     80   mbs = initial;
     81   nwc = mbsrtowcs(s, (const char **)&mbp, n, &mbs);
     82   free(f._bf._base);
     83   if (nwc == (size_t)-1) {
     84     errno = EILSEQ;
     85     return (-1);
     86   }
     87   if (nwc == n) {
     88     s[n - 1] = L'\0';
     89     errno = EOVERFLOW;
     90     return (-1);
     91   }
     92 
     93   return (ret);
     94 }
     95