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