Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2009-03-11 14:53:22 +0300
committerCorinna Vinschen <corinna@vinschen.de>2009-03-11 14:53:22 +0300
commitd0b85c158fbe7a30d665f41c60bb5800da562ce8 (patch)
tree0a6bdcb338566b97077e802d1515f583d02f3cf7 /newlib/libc/stdio/swscanf.c
parente20efdda164c04d8e6731db0aed019a110699b1b (diff)
* libc/include/wchar.h (fwscanf, swscanf, vfwscanf, vswscanf, vwscanf,
wscanf): Declare. (_fwscanf_r, _swscanf_r, _vfwscanf_r, _vswscanf_r, _vwscanf_r, _wscanf_r): Declare. * libc/stdio/Makefile.am: Add new wscanf files. * libc/stdio/Makefile.in: Regenerate. * libc/stdio/fwscanf.c: New file. * libc/stdio/local.h (__svfwscanf_r, __ssvfwscanf_r, __svfiwscanf_r, __ssvfiwscanf_r): Declare. * libc/stdio/stdio.tex: Add new documentation references. * libc/stdio/swscanf.c: New file. * libc/stdio/vfwscanf.c: New file. * libc/stdio/vswscanf.c: New file. * libc/stdio/vwscanf.c: New file. * libc/stdio/wscanf.c: New file. * libc/stdio/vfscanf.c (_sungetc_r): Make externaly available. Only define if INTEGER_ONLY is defined. Declare otherwise. (__ssrefill_r): Ditto. (_sfread_r): Ditto. Remove static eofread/eofread1 functions and use __seofread function instead, throughout. * libc/stdio/local.h (__seofread): Declare. * libc/stdio/stdio.c (__seofread): Define. * libc/stdio/fgetwc.c (__fgetwc): Fix compiler warning. * libc/stdio/fgetws.c (_fgetws_r): Ditto. * libc/stdio/fread.c (_fread_r): Ditto. * libc/stdio/vfprintf.c: Ditto. * libc/stdio/vswprintf.c: Ditto.
Diffstat (limited to 'newlib/libc/stdio/swscanf.c')
-rw-r--r--newlib/libc/stdio/swscanf.c417
1 files changed, 417 insertions, 0 deletions
diff --git a/newlib/libc/stdio/swscanf.c b/newlib/libc/stdio/swscanf.c
new file mode 100644
index 000000000..e4e251f95
--- /dev/null
+++ b/newlib/libc/stdio/swscanf.c
@@ -0,0 +1,417 @@
+/*
+ * 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 *<[format]>, ...);
+ int fwscanf(FILE *<[fd]>, const wchar_t *<[format]>, ...);
+ int swscanf(const wchar_t *<[str]>, const wchar_t *<[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 *<[format]>;
+
+ int fwscanf(<[fd]>, <[format]> [, <[arg]>, ...]);
+ FILE *<[fd]>;
+ wchar_t *<[format]>;
+
+ int swscanf(<[str]>, <[format]> [, <[arg]>, ...]);
+ wchar_t *<[str]>;
+ wchar_t *<[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)>>.
+
+ 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 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>>.
+
+ 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 *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 (_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;
+}