msvcrt: Change strtod_l implementation.
[wine] / dlls / msvcrt / scanf.c
1 /*
2  * general implementation of scanf used by scanf, sscanf, fscanf,
3  * _cscanf, wscanf, swscanf and fwscanf
4  *
5  * Copyright 1996,1998 Marcus Meissner
6  * Copyright 1996 Jukka Iivonen
7  * Copyright 1997,2000 Uwe Bonnes
8  * Copyright 2000 Jon Griffiths
9  * Copyright 2002 Daniel Gudbjartsson
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25
26 #include <stdarg.h>
27 #include <limits.h>
28
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winternl.h"
32 #include "msvcrt.h"
33 #include "wine/debug.h"
34
35 WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
36
37 extern MSVCRT_FILE MSVCRT__iob[];
38
39 /* helper function for *scanf.  Returns the value of character c in the
40  * given base, or -1 if the given character is not a digit of the base.
41  */
42 static int char2digit(char c, int base) {
43     if ((c>='0') && (c<='9') && (c<='0'+base-1)) return (c-'0');
44     if (base<=10) return -1;
45     if ((c>='A') && (c<='Z') && (c<='A'+base-11)) return (c-'A'+10);
46     if ((c>='a') && (c<='z') && (c<='a'+base-11)) return (c-'a'+10);
47     return -1;
48 }
49
50 /* helper function for *wscanf.  Returns the value of character c in the
51  * given base, or -1 if the given character is not a digit of the base.
52  */
53 static int wchar2digit(MSVCRT_wchar_t c, int base) {
54     if ((c>='0') && (c<='9') && (c<='0'+base-1)) return (c-'0');
55     if (base<=10) return -1;
56     if ((c>='A') && (c<='Z') && (c<='A'+base-11)) return (c-'A'+10);
57     if ((c>='a') && (c<='z') && (c<='a'+base-11)) return (c-'a'+10);
58     return -1;
59 }
60
61 /* vfscanf_l */
62 #undef WIDE_SCANF
63 #undef CONSOLE
64 #undef STRING
65 #undef SECURE
66 #include "scanf.h"
67
68 /* vfscanf_l */
69 #define SECURE 1
70 #include "scanf.h"
71
72 /* vfwscanf_l */
73 #define WIDE_SCANF 1
74 #undef CONSOLE
75 #undef STRING
76 #undef SECURE
77 #include "scanf.h"
78
79 /* vfwscanf_s_l */
80 #define SECURE 1
81 #include "scanf.h"
82
83 /* vsscanf_l */
84 #undef WIDE_SCANF
85 #undef CONSOLE
86 #define STRING 1
87 #undef SECURE
88 #include "scanf.h"
89
90 /* vsscanf_s_l */
91 #define SECURE 1
92 #include "scanf.h"
93
94 /* vswscanf_l */
95 #define WIDE_SCANF 1
96 #undef CONSOLE
97 #define STRING 1
98 #undef SECURE
99 #include "scanf.h"
100
101 /* vswscanf_s_l */
102 #define SECURE 1
103 #include "scanf.h"
104
105 /* vcscanf_l */
106 #undef WIDE_SCANF
107 #define CONSOLE 1
108 #undef STRING
109 #undef SECURE
110 #include "scanf.h"
111
112 /* vcscanf_s_l */
113 #define SECURE 1
114 #include "scanf.h"
115
116 /* vcwscanf_l */
117 #define WIDE_SCANF 1
118 #define CONSOLE 1
119 #undef STRING
120 #undef SECURE
121 #include "scanf.h"
122
123 /* vcwscanf_s_l */
124 #define SECURE 1
125 #include "scanf.h"
126
127
128 /*********************************************************************
129  *              fscanf (MSVCRT.@)
130  */
131 int CDECL MSVCRT_fscanf(MSVCRT_FILE *file, const char *format, ...)
132 {
133     __ms_va_list valist;
134     int res;
135
136     __ms_va_start(valist, format);
137     res = MSVCRT_vfscanf_l(file, format, NULL, valist);
138     __ms_va_end(valist);
139     return res;
140 }
141
142 /*********************************************************************
143  *              _fscanf_l (MSVCRT.@)
144  */
145 int CDECL MSVCRT__fscanf_l(MSVCRT_FILE *file, const char *format,
146         MSVCRT__locale_t locale, ...)
147 {
148     __ms_va_list valist;
149     int res;
150
151     __ms_va_start(valist, locale);
152     res = MSVCRT_vfscanf_l(file, format, locale, valist);
153     __ms_va_end(valist);
154     return res;
155 }
156
157 /*********************************************************************
158  *              fscanf_s (MSVCRT.@)
159  */
160 int CDECL MSVCRT_fscanf_s(MSVCRT_FILE *file, const char *format, ...)
161 {
162     __ms_va_list valist;
163     int res;
164
165     __ms_va_start(valist, format);
166     res = MSVCRT_vfscanf_s_l(file, format, NULL, valist);
167     __ms_va_end(valist);
168     return res;
169 }
170
171 /*********************************************************************
172  *              _fscanf_s_l (MSVCRT.@)
173  */
174 int CDECL MSVCRT__fscanf_s_l(MSVCRT_FILE *file, const char *format,
175         MSVCRT__locale_t locale, ...)
176 {
177     __ms_va_list valist;
178     int res;
179
180     __ms_va_start(valist, locale);
181     res = MSVCRT_vfscanf_s_l(file, format, locale, valist);
182     __ms_va_end(valist);
183     return res;
184 }
185
186 /*********************************************************************
187  *              scanf (MSVCRT.@)
188  */
189 int CDECL MSVCRT_scanf(const char *format, ...)
190 {
191     __ms_va_list valist;
192     int res;
193
194     __ms_va_start(valist, format);
195     res = MSVCRT_vfscanf_l(MSVCRT_stdin, format, NULL, valist);
196     __ms_va_end(valist);
197     return res;
198 }
199
200 /*********************************************************************
201  *              _scanf_l (MSVCRT.@)
202  */
203 int CDECL MSVCRT__scanf_l(const char *format, MSVCRT__locale_t locale, ...)
204 {
205     __ms_va_list valist;
206     int res;
207
208     __ms_va_start(valist, locale);
209     res = MSVCRT_vfscanf_l(MSVCRT_stdin, format, locale, valist);
210     __ms_va_end(valist);
211     return res;
212 }
213
214 /*********************************************************************
215  *              scanf_s (MSVCRT.@)
216  */
217 int CDECL MSVCRT_scanf_s(const char *format, ...)
218 {
219     __ms_va_list valist;
220     int res;
221
222     __ms_va_start(valist, format);
223     res = MSVCRT_vfscanf_s_l(MSVCRT_stdin, format, NULL, valist);
224     __ms_va_end(valist);
225     return res;
226 }
227
228 /*********************************************************************
229  *              _scanf_s_l (MSVCRT.@)
230  */
231 int CDECL MSVCRT__scanf_s_l(const char *format, MSVCRT__locale_t locale, ...)
232 {
233     __ms_va_list valist;
234     int res;
235
236     __ms_va_start(valist, locale);
237     res = MSVCRT_vfscanf_s_l(MSVCRT_stdin, format, locale, valist);
238     __ms_va_end(valist);
239     return res;
240 }
241
242 /*********************************************************************
243  *              fwscanf (MSVCRT.@)
244  */
245 int CDECL MSVCRT_fwscanf(MSVCRT_FILE *file, const MSVCRT_wchar_t *format, ...)
246 {
247     __ms_va_list valist;
248     int res;
249
250     __ms_va_start(valist, format);
251     res = MSVCRT_vfwscanf_l(file, format, NULL, valist);
252     __ms_va_end(valist);
253     return res;
254 }
255
256 /*********************************************************************
257  *              _fwscanf_l (MSVCRT.@)
258  */
259 int CDECL MSVCRT__fwscanf_l(MSVCRT_FILE *file, const MSVCRT_wchar_t *format,
260         MSVCRT__locale_t locale, ...)
261 {
262     __ms_va_list valist;
263     int res;
264
265     __ms_va_start(valist, locale);
266     res = MSVCRT_vfwscanf_l(file, format, locale, valist);
267     __ms_va_end(valist);
268     return res;
269 }
270
271 /*********************************************************************
272  *              fwscanf_s (MSVCRT.@)
273  */
274 int CDECL MSVCRT_fwscanf_s(MSVCRT_FILE *file, const MSVCRT_wchar_t *format, ...)
275 {
276     __ms_va_list valist;
277     int res;
278
279     __ms_va_start(valist, format);
280     res = MSVCRT_vfwscanf_s_l(file, format, NULL, valist);
281     __ms_va_end(valist);
282     return res;
283 }
284
285 /*********************************************************************
286  *              _fwscanf_s_l (MSVCRT.@)
287  */
288 int CDECL MSVCRT__fwscanf_s_l(MSVCRT_FILE *file, const MSVCRT_wchar_t *format,
289         MSVCRT__locale_t locale, ...)
290 {
291     __ms_va_list valist;
292     int res;
293
294     __ms_va_start(valist, locale);
295     res = MSVCRT_vfwscanf_s_l(file, format, locale, valist);
296     __ms_va_end(valist);
297     return res;
298 }
299
300 /*********************************************************************
301  *              wscanf (MSVCRT.@)
302  */
303 int CDECL MSVCRT_wscanf(const MSVCRT_wchar_t *format, ...)
304 {
305     __ms_va_list valist;
306     int res;
307
308     __ms_va_start(valist, format);
309     res = MSVCRT_vfwscanf_l(MSVCRT_stdin, format, NULL, valist);
310     __ms_va_end(valist);
311     return res;
312 }
313
314 /*********************************************************************
315  *              _wscanf_l (MSVCRT.@)
316  */
317 int CDECL MSVCRT__wscanf_l(const MSVCRT_wchar_t *format,
318         MSVCRT__locale_t locale, ...)
319 {
320     __ms_va_list valist;
321     int res;
322
323     __ms_va_start(valist, locale);
324     res = MSVCRT_vfwscanf_l(MSVCRT_stdin, format, locale, valist);
325     __ms_va_end(valist);
326     return res;
327 }
328
329 /*********************************************************************
330  *              wscanf_s (MSVCRT.@)
331  */
332 int CDECL MSVCRT_wscanf_s(const MSVCRT_wchar_t *format, ...)
333 {
334     __ms_va_list valist;
335     int res;
336
337     __ms_va_start(valist, format);
338     res = MSVCRT_vfwscanf_s_l(MSVCRT_stdin, format, NULL, valist);
339     __ms_va_end(valist);
340     return res;
341 }
342
343 /*********************************************************************
344  *              _wscanf_s_l (MSVCRT.@)
345  */
346 int CDECL MSVCRT__wscanf_s_l(const MSVCRT_wchar_t *format,
347         MSVCRT__locale_t locale, ...)
348 {
349     __ms_va_list valist;
350     int res;
351
352     __ms_va_start(valist, locale);
353     res = MSVCRT_vfwscanf_s_l(MSVCRT_stdin, format, locale, valist);
354     __ms_va_end(valist);
355     return res;
356 }
357
358 /*********************************************************************
359  *              sscanf (MSVCRT.@)
360  */
361 int CDECL MSVCRT_sscanf(const char *str, const char *format, ...)
362 {
363     __ms_va_list valist;
364     int res;
365
366     __ms_va_start(valist, format);
367     res = MSVCRT_vsscanf_l(str, format, NULL, valist);
368     __ms_va_end(valist);
369     return res;
370 }
371
372 /*********************************************************************
373  *              _sscanf_l (MSVCRT.@)
374  */
375 int CDECL MSVCRT__sscanf_l(const char *str, const char *format,
376         MSVCRT__locale_t locale, ...)
377 {
378     __ms_va_list valist;
379     int res;
380
381     __ms_va_start(valist, locale);
382     res = MSVCRT_vsscanf_l(str, format, locale, valist);
383     __ms_va_end(valist);
384     return res;
385 }
386
387 /*********************************************************************
388  *              sscanf_s (MSVCRT.@)
389  */
390 int CDECL MSVCRT_sscanf_s(const char *str, const char *format, ...)
391 {
392     __ms_va_list valist;
393     int res;
394
395     __ms_va_start(valist, format);
396     res = MSVCRT_vsscanf_s_l(str, format, NULL, valist);
397     __ms_va_end(valist);
398     return res;
399 }
400
401 /*********************************************************************
402  *              _sscanf_s_l (MSVCRT.@)
403  */
404 int CDECL MSVCRT__sscanf_s_l(const char *str, const char *format,
405         MSVCRT__locale_t locale, ...)
406 {
407     __ms_va_list valist;
408     int res;
409
410     __ms_va_start(valist, locale);
411     res = MSVCRT_vsscanf_s_l(str, format, locale, valist);
412     __ms_va_end(valist);
413     return res;
414 }
415
416 /*********************************************************************
417  *              swscanf (MSVCRT.@)
418  */
419 int CDECL MSVCRT_swscanf(const MSVCRT_wchar_t *str, const MSVCRT_wchar_t *format, ...)
420 {
421     __ms_va_list valist;
422     int res;
423
424     __ms_va_start(valist, format);
425     res = MSVCRT_vswscanf_l(str, format, NULL, valist);
426     __ms_va_end(valist);
427     return res;
428 }
429
430 /*********************************************************************
431  *              _swscanf_l (MSVCRT.@)
432  */
433 int CDECL MSVCRT__swscanf_l(const MSVCRT_wchar_t *str, const MSVCRT_wchar_t *format,
434         MSVCRT__locale_t locale, ...)
435 {
436     __ms_va_list valist;
437     int res;
438
439     __ms_va_start(valist, locale);
440     res = MSVCRT_vswscanf_l(str, format, locale, valist);
441     __ms_va_end(valist);
442     return res;
443 }
444
445 /*********************************************************************
446  *              swscanf_s (MSVCRT.@)
447  */
448 int CDECL MSVCRT_swscanf_s(const MSVCRT_wchar_t *str, const MSVCRT_wchar_t *format, ...)
449 {
450     __ms_va_list valist;
451     int res;
452
453     __ms_va_start(valist, format);
454     res = MSVCRT_vswscanf_s_l(str, format, NULL, valist);
455     __ms_va_end(valist);
456     return res;
457 }
458
459 /*********************************************************************
460  *              _swscanf_s_l (MSVCRT.@)
461  */
462 int CDECL MSVCRT__swscanf_s_l(const MSVCRT_wchar_t *str, const MSVCRT_wchar_t *format,
463         MSVCRT__locale_t locale, ...)
464 {
465     __ms_va_list valist;
466     int res;
467
468     __ms_va_start(valist, locale);
469     res = MSVCRT_vswscanf_s_l(str, format, locale, valist);
470     __ms_va_end(valist);
471     return res;
472 }
473
474 /*********************************************************************
475  *              _cscanf (MSVCRT.@)
476  */
477 int CDECL _cscanf(const char *format, ...)
478 {
479     __ms_va_list valist;
480     int res;
481
482     __ms_va_start(valist, format);
483     res = MSVCRT_vcscanf_l(format, NULL, valist);
484     __ms_va_end(valist);
485     return res;
486 }
487
488 /*********************************************************************
489  *              _cscanf_l (MSVCRT.@)
490  */
491 int CDECL _cscanf_l(const char *format, MSVCRT__locale_t locale, ...)
492 {
493     __ms_va_list valist;
494     int res;
495
496     __ms_va_start(valist, locale);
497     res = MSVCRT_vcscanf_l(format, locale, valist);
498     __ms_va_end(valist);
499     return res;
500 }
501
502 /*********************************************************************
503  *              _cscanf_s (MSVCRT.@)
504  */
505 int CDECL _cscanf_s(const char *format, ...)
506 {
507     __ms_va_list valist;
508     int res;
509
510     __ms_va_start(valist, format);
511     res = MSVCRT_vcscanf_s_l(format, NULL, valist);
512     __ms_va_end(valist);
513     return res;
514 }
515
516 /*********************************************************************
517  *              _cscanf_s_l (MSVCRT.@)
518  */
519 int CDECL _cscanf_s_l(const char *format, MSVCRT__locale_t locale, ...)
520 {
521     __ms_va_list valist;
522     int res;
523
524     __ms_va_start(valist, locale);
525     res = MSVCRT_vcscanf_s_l(format, locale, valist);
526     __ms_va_end(valist);
527     return res;
528 }
529
530 /*********************************************************************
531  *              _cwscanf (MSVCRT.@)
532  */
533 int CDECL _cwscanf(const char *format, ...)
534 {
535     __ms_va_list valist;
536     int res;
537
538     __ms_va_start(valist, format);
539     res = MSVCRT_vcwscanf_l(format, NULL, valist);
540     __ms_va_end(valist);
541     return res;
542 }
543
544 /*********************************************************************
545  *              _cwscanf_l (MSVCRT.@)
546  */
547 int CDECL _cwscanf_l(const char *format, MSVCRT__locale_t locale, ...)
548 {
549     __ms_va_list valist;
550     int res;
551
552     __ms_va_start(valist, locale);
553     res = MSVCRT_vcwscanf_l(format, locale, valist);
554     __ms_va_end(valist);
555     return res;
556 }
557
558 /*********************************************************************
559  *              _cwscanf_s (MSVCRT.@)
560  */
561 int CDECL _cwscanf_s(const char *format, ...)
562 {
563     __ms_va_list valist;
564     int res;
565
566     __ms_va_start(valist, format);
567     res = MSVCRT_vcwscanf_s_l(format, NULL, valist);
568     __ms_va_end(valist);
569     return res;
570 }
571
572 /*********************************************************************
573  *              _cwscanf_s_l (MSVCRT.@)
574  */
575 int CDECL _cwscanf_s_l(const char *format, MSVCRT__locale_t locale, ...)
576 {
577     __ms_va_list valist;
578     int res;
579
580     __ms_va_start(valist, locale);
581     res = MSVCRT_vcwscanf_s_l(format, locale, valist);
582     __ms_va_end(valist);
583     return res;
584 }