| /* |
| * Copyright (c) 1990 The Regents of the University of California. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms are permitted |
| * provided that the above copyright notice and this paragraph are |
| * duplicated in all such forms and that any documentation, |
| * advertising materials, and other materials related to such |
| * distribution and use acknowledge that the software was developed |
| * by the University of California, Berkeley. The name of the |
| * University may not be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR |
| * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
| */ |
| |
| /* |
| FUNCTION |
| <<swscanf>>, <<fwscanf>>, <<wscanf>>---scan and format wide character input |
| |
| INDEX |
| wscanf |
| INDEX |
| _wscanf_r |
| INDEX |
| fwscanf |
| INDEX |
| _fwscanf_r |
| INDEX |
| swscanf |
| INDEX |
| _swscanf_r |
| |
| ANSI_SYNOPSIS |
| #include <stdio.h> |
| |
| int wscanf(const wchar_t *__restrict <[format]>, ...); |
| int fwscanf(FILE *__restrict <[fd]>, |
| const wchar_t *__restrict <[format]>, ...); |
| int swscanf(const wchar_t *__restrict <[str]>, |
| const wchar_t *__restrict <[format]>, ...); |
| |
| int _wscanf_r(struct _reent *<[ptr]>, const wchar_t *<[format]>, ...); |
| int _fwscanf_r(struct _reent *<[ptr]>, FILE *<[fd]>, |
| const wchar_t *<[format]>, ...); |
| int _swscanf_r(struct _reent *<[ptr]>, const wchar_t *<[str]>, |
| const wchar_t *<[format]>, ...); |
| |
| |
| TRAD_SYNOPSIS |
| #include <stdio.h> |
| |
| int wscanf(<[format]> [, <[arg]>, ...]) |
| wchar_t *__restrict <[format]>; |
| |
| int fwscanf(<[fd]>, <[format]> [, <[arg]>, ...]); |
| FILE *<[fd]>; |
| wchar_t *<[format]>; |
| |
| int swscanf(<[str]>, <[format]> [, <[arg]>, ...]); |
| wchar_t *__restrict <[str]>; |
| wchar_t *__restrict <[format]>; |
| |
| int _wscanf_r(<[ptr]>, <[format]> [, <[arg]>, ...]) |
| struct _reent *<[ptr]>; |
| wchar_t *<[format]>; |
| |
| int _fwscanf_r(<[ptr]>, <[fd]>, <[format]> [, <[arg]>, ...]); |
| struct _reent *<[ptr]>; |
| FILE *<[fd]>; |
| wchar_t *<[format]>; |
| |
| int _swscanf_r(<[ptr]>, <[str]>, <[format]> [, <[arg]>, ...]); |
| struct _reent *<[ptr]>; |
| wchar_t *<[str]>; |
| wchar_t *<[format]>; |
| |
| |
| DESCRIPTION |
| <<wscanf>> scans a series of input fields from standard input, |
| one wide character at a time. Each field is interpreted according to |
| a format specifier passed to <<wscanf>> in the format string at |
| <<*<[format]>>>. <<wscanf>> stores the interpreted input from |
| each field at the address passed to it as the corresponding argument |
| following <[format]>. You must supply the same number of |
| format specifiers and address arguments as there are input fields. |
| |
| There must be sufficient address arguments for the given format |
| specifiers; if not the results are unpredictable and likely |
| disasterous. Excess address arguments are merely ignored. |
| |
| <<wscanf>> often produces unexpected results if the input diverges from |
| an expected pattern. Since the combination of <<gets>> or <<fgets>> |
| followed by <<swscanf>> is safe and easy, that is the preferred way |
| to be certain that a program is synchronized with input at the end |
| of a line. |
| |
| <<fwscanf>> and <<swscanf>> are identical to <<wscanf>>, other than the |
| source of input: <<fwscanf>> reads from a file, and <<swscanf>> |
| from a string. |
| |
| The routines <<_wscanf_r>>, <<_fwscanf_r>>, and <<_swscanf_r>> are reentrant |
| versions of <<wscanf>>, <<fwscanf>>, and <<swscanf>> that take an additional |
| first argument pointing to a reentrancy structure. |
| |
| The string at <<*<[format]>>> is a wide character sequence composed |
| of zero or more directives. Directives are composed of |
| one or more whitespace characters, non-whitespace characters, |
| and format specifications. |
| |
| Whitespace characters are blank (<< >>), tab (<<\t>>), or |
| newline (<<\n>>). |
| When <<wscanf>> encounters a whitespace character in the format string |
| it will read (but not store) all consecutive whitespace characters |
| up to the next non-whitespace character in the input. |
| |
| Non-whitespace characters are all other ASCII characters except the |
| percent sign (<<%>>). When <<wscanf>> encounters a non-whitespace |
| character in the format string it will read, but not store |
| a matching non-whitespace character. |
| |
| Format specifications tell <<wscanf>> to read and convert characters |
| from the input field into specific types of values, and store then |
| in the locations specified by the address arguments. |
| |
| Trailing whitespace is left unread unless explicitly |
| matched in the format string. |
| |
| The format specifiers must begin with a percent sign (<<%>>) |
| and have the following form: |
| |
| . %[*][<[width]>][<[size]>]<[type]> |
| |
| Each format specification begins with the percent character (<<%>>). |
| The other fields are: |
| o+ |
| o * |
| an optional marker; if present, it suppresses interpretation and |
| assignment of this input field. |
| |
| o <[width]> |
| an optional maximum field width: a decimal integer, |
| which controls the maximum number of characters that |
| will be read before converting the current input field. If the |
| input field has fewer than <[width]> characters, <<wscanf>> |
| reads all the characters in the field, and then |
| proceeds with the next field and its format specification. |
| |
| If a whitespace or a non-convertable wide character occurs |
| before <[width]> character are read, the characters up |
| to that character are read, converted, and stored. |
| Then <<wscanf>> proceeds to the next format specification. |
| |
| o size |
| <<h>>, <<j>>, <<l>>, <<L>>, <<t>>, and <<z>> are optional size |
| characters which override the default way that <<wscanf>> |
| interprets the data type of the corresponding argument. |
| |
| |
| .Modifier Type(s) |
| . hh d, i, o, u, x, n convert input to char, |
| . store in char object |
| . |
| . h d, i, o, u, x, n convert input to short, |
| . store in short object |
| . |
| . h e, f, c, s, p no effect |
| . |
| . j d, i, o, u, x, n convert input to intmax_t, |
| . store in intmax_t object |
| . |
| . j all others no effect |
| . |
| . l d, i, o, u, x, n convert input to long, |
| . store in long object |
| . |
| . l e, f, g convert input to double |
| . store in a double object |
| . |
| . l c, s, [ the input is stored in a wchar_t object |
| . |
| . l p no effect |
| . |
| . ll d, i, o, u, x, n convert to long long, |
| . store in long long |
| . |
| . L d, i, o, u, x, n convert to long long, |
| . store in long long |
| . |
| . L e, f, g, E, G convert to long double, |
| . store in long double |
| . |
| . L all others no effect |
| . |
| . t d, i, o, u, x, n convert input to ptrdiff_t, |
| . store in ptrdiff_t object |
| . |
| . t all others no effect |
| . |
| . z d, i, o, u, x, n convert input to size_t, |
| . store in size_t object |
| . |
| . z all others no effect |
| . |
| |
| |
| o <[type]> |
| |
| A character to specify what kind of conversion |
| <<wscanf>> performs. Here is a table of the conversion |
| characters: |
| |
| o+ |
| o % |
| No conversion is done; the percent character (<<%>>) is stored. |
| |
| o c |
| Scans one wide character. Corresponding <[arg]>: <<(char *arg)>>. |
| Otherwise, if an <<l>> specifier is present, the corresponding |
| <[arg]> is a <<(wchar_t *arg)>>. |
| |
| o s |
| Reads a character string into the array supplied. |
| Corresponding <[arg]>: <<(char arg[])>>. |
| If an <<l>> specifier is present, the corresponding <[arg]> is a <<(wchar_t *arg)>>. |
| |
| o [<[pattern]>] |
| Reads a non-empty character string into memory |
| starting at <[arg]>. This area must be large |
| enough to accept the sequence and a |
| terminating null character which will be added |
| automatically. (<[pattern]> is discussed in the paragraph following |
| this table). Corresponding <[arg]>: <<(char *arg)>>. |
| If an <<l>> specifier is present, the corresponding <[arg]> is |
| a <<(wchar_t *arg)>>. |
| |
| o d |
| Reads a decimal integer into the corresponding <[arg]>: <<(int *arg)>>. |
| |
| o o |
| Reads an octal integer into the corresponding <[arg]>: <<(int *arg)>>. |
| |
| o u |
| Reads an unsigned decimal integer into the corresponding |
| <[arg]>: <<(unsigned int *arg)>>. |
| |
| o x,X |
| Read a hexadecimal integer into the corresponding <[arg]>: |
| <<(int *arg)>>. |
| |
| o e, f, g |
| Read a floating-point number into the corresponding <[arg]>: |
| <<(float *arg)>>. |
| |
| o E, F, G |
| Read a floating-point number into the corresponding <[arg]>: |
| <<(double *arg)>>. |
| |
| o i |
| Reads a decimal, octal or hexadecimal integer into the |
| corresponding <[arg]>: <<(int *arg)>>. |
| |
| o n |
| Stores the number of characters read in the corresponding |
| <[arg]>: <<(int *arg)>>. |
| |
| o p |
| Stores a scanned pointer. ANSI C leaves the details |
| to each implementation; this implementation treats |
| <<%p>> exactly the same as <<%U>>. Corresponding |
| <[arg]>: <<(void **arg)>>. |
| o- |
| |
| A <[pattern]> of characters surrounded by square brackets can be used |
| instead of the <<s>> type character. <[pattern]> is a set of |
| characters which define a search set of possible characters making up |
| the <<wscanf>> input field. If the first character in the brackets is a |
| caret (<<^>>), the search set is inverted to include all ASCII characters |
| except those between the brackets. There is no range facility as is |
| defined in the corresponding non-wide character scanf functions. |
| Ranges are not part of the POSIX standard. |
| |
| Here are some <[pattern]> examples: |
| o+ |
| o %[abcd] |
| matches wide character strings containing only |
| <<a>>, <<b>>, <<c>>, and <<d>>. |
| |
| o %[^abcd] |
| matches wide character strings containing any characters except |
| <<a>>, <<b>>, <<c>>, or <<d>>. |
| |
| o %[A-DW-Z] |
| Note: No wide character ranges, so this expression matches wide |
| character strings containing <<A>>, <<->>, <<D>>, <<W>>, <<Z>>. |
| o- |
| |
| Floating point numbers (for field types <<e>>, <<f>>, <<g>>, <<E>>, |
| <<F>>, <<G>>) must correspond to the following general form: |
| |
| . [+/-] ddddd[.]ddd [E|e[+|-]ddd] |
| |
| where objects inclosed in square brackets are optional, and <<ddd>> |
| represents decimal, octal, or hexadecimal digits. |
| o- |
| |
| RETURNS |
| <<wscanf>> returns the number of input fields successfully |
| scanned, converted and stored; the return value does |
| not include scanned fields which were not stored. |
| |
| If <<wscanf>> attempts to read at end-of-file, the return |
| value is <<EOF>>. |
| |
| If no fields were stored, the return value is <<0>>. |
| |
| <<wscanf>> might stop scanning a particular field before |
| reaching the normal field end character, or may |
| terminate entirely. |
| |
| <<wscanf>> stops scanning and storing the current field |
| and moves to the next input field (if any) |
| in any of the following situations: |
| |
| O+ |
| o The assignment suppressing character (<<*>>) appears |
| after the <<%>> in the format specification; the current |
| input field is scanned but not stored. |
| |
| o <[width]> characters have been read (<[width]> is a |
| width specification, a positive decimal integer). |
| |
| o The next wide character read cannot be converted |
| under the the current format (for example, |
| if a <<Z>> is read when the format is decimal). |
| |
| o The next wide character in the input field does not appear |
| in the search set (or does appear in the inverted search set). |
| O- |
| |
| When <<wscanf>> stops scanning the current input field for one of |
| these reasons, the next character is considered unread and |
| used as the first character of the following input field, or the |
| first character in a subsequent read operation on the input. |
| |
| <<wscanf>> will terminate under the following circumstances: |
| |
| O+ |
| o The next wide character in the input field conflicts |
| with a corresponding non-whitespace character in the |
| format string. |
| |
| o The next wide character in the input field is <<WEOF>>. |
| |
| o The format string has been exhausted. |
| O- |
| |
| When the format string contains a wide character sequence that is |
| not part of a format specification, the same wide character |
| sequence must appear in the input; <<wscanf>> will |
| scan but not store the matched characters. If a |
| conflict occurs, the first conflicting wide character remains in the |
| input as if it had never been read. |
| |
| PORTABILITY |
| <<wscanf>> is C99, POSIX-1.2008. |
| |
| Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, |
| <<lseek>>, <<read>>, <<sbrk>>, <<write>>. |
| */ |
| |
| #include <_ansi.h> |
| #include <reent.h> |
| #include <stdio.h> |
| #include <wchar.h> |
| #include <stdarg.h> |
| #include "local.h" |
| |
| #ifndef _REENT_ONLY |
| |
| int |
| swscanf (_CONST wchar_t *__restrict str, _CONST wchar_t *__restrict fmt, ...) |
| { |
| int ret; |
| va_list ap; |
| FILE f; |
| |
| f._flags = __SRD | __SSTR; |
| f._bf._base = f._p = (unsigned char *) str; |
| f._bf._size = f._r = wcslen (str) * sizeof (wchar_t); |
| f._read = __seofread; |
| f._ub._base = NULL; |
| f._lb._base = NULL; |
| f._file = -1; /* No file. */ |
| va_start (ap, fmt); |
| ret = __ssvfwscanf_r (_REENT, &f, fmt, ap); |
| va_end (ap); |
| return ret; |
| } |
| |
| #endif /* !_REENT_ONLY */ |
| |
| int |
| _swscanf_r (struct _reent *ptr, _CONST wchar_t *str, _CONST wchar_t *fmt, ...) |
| { |
| int ret; |
| va_list ap; |
| FILE f; |
| |
| f._flags = __SRD | __SSTR; |
| f._bf._base = f._p = (unsigned char *) str; |
| f._bf._size = f._r = wcslen (str) * sizeof (wchar_t); |
| f._read = __seofread; |
| f._ub._base = NULL; |
| f._lb._base = NULL; |
| f._file = -1; /* No file. */ |
| va_start (ap, fmt); |
| ret = __ssvfwscanf_r (ptr, &f, fmt, ap); |
| va_end (ap); |
| return ret; |
| } |