dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / libast / common / stdio / vfwscanf.c
blob14a5c1ef2b7fa7c5239a3031b13733688a2c42a1
1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12 * *
13 * Information and Software Systems Research *
14 * AT&T Research *
15 * Florham Park NJ *
16 * *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
20 * *
21 ***********************************************************************/
22 #pragma prototyped
24 #include "stdhdr.h"
26 typedef struct
28 Sfdisc_t sfdisc; /* sfio discipline */
29 Sfio_t* f; /* original wide stream */
30 char fmt[1]; /* mb fmt */
31 } Wide_t;
34 * wide exception handler
35 * free on close
38 static int
39 wideexcept(Sfio_t* f, int op, void* val, Sfdisc_t* dp)
41 if (sffileno(f) >= 0)
42 return -1;
43 switch (op)
45 case SF_ATEXIT:
46 sfdisc(f, SF_POPDISC);
47 break;
48 case SF_CLOSING:
49 case SF_DPOP:
50 case SF_FINAL:
51 if (op != SF_CLOSING)
52 free(dp);
53 break;
55 return 0;
59 * sfio wide discipline read
60 * 1 wchar_t at a time
61 * go pure multibyte for best performance
64 static ssize_t
65 wideread(Sfio_t* f, Void_t* buf, size_t size, Sfdisc_t* dp)
67 register Wide_t* w = (Wide_t*)dp;
68 wchar_t wuf[2];
70 #if 0
71 if (sfread(w->f, wuf, sizeof(wuf[0])) != sizeof(wuf[0]))
72 return -1;
73 wuf[1] = 0;
74 return wcstombs(buf, wuf, size);
75 #else
76 ssize_t r;
78 r = sfread(w->f, wuf, sizeof(wuf[0]));
79 if (r != sizeof(wuf[0]))
80 return -1;
81 wuf[1] = 0;
82 r = wcstombs(buf, wuf, size);
83 return r;
84 #endif
87 int
88 vfwscanf(Sfio_t* f, const wchar_t* fmt, va_list args)
90 size_t n;
91 int v;
92 Sfio_t* t;
93 Wide_t* w;
94 char buf[1024];
96 STDIO_INT(f, "vfwscanf", int, (Sfio_t*, const wchar_t*, va_list), (f, fmt, args))
98 FWIDE(f, WEOF);
99 n = wcstombs(NiL, fmt, 0);
100 if (w = newof(0, Wide_t, 1, n))
102 if (t = sfnew(NiL, buf, sizeof(buf), OPEN_MAX+1, SF_READ))
104 w->sfdisc.exceptf = wideexcept;
105 w->sfdisc.readf = wideread;
106 w->f = f;
107 if (sfdisc(t, &w->sfdisc) == &w->sfdisc)
109 wcstombs(w->fmt, fmt, n + 1);
110 v = sfvscanf(t, w->fmt, args);
112 else
114 free(w);
115 v = -1;
117 sfsetfd(t, -1);
118 sfclose(t);
120 else
122 free(w);
123 v = -1;
126 else
127 v = -1;
128 return v;