summaryrefslogtreecommitdiff
path: root/newlib/libc/stdio/sscanf.c
diff options
context:
space:
mode:
Diffstat (limited to 'newlib/libc/stdio/sscanf.c')
-rw-r--r--newlib/libc/stdio/sscanf.c386
1 files changed, 386 insertions, 0 deletions
diff --git a/newlib/libc/stdio/sscanf.c b/newlib/libc/stdio/sscanf.c
new file mode 100644
index 00000000000..eb344238db4
--- /dev/null
+++ b/newlib/libc/stdio/sscanf.c
@@ -0,0 +1,386 @@
+/*
+ * 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
+ <<scanf>>, <<fscanf>>, <<sscanf>>---scan and format input
+
+INDEX
+ scanf
+INDEX
+ fscanf
+INDEX
+ sscanf
+
+ANSI_SYNOPSIS
+ #include <stdio.h>
+
+ int scanf(const char *<[format]> [, <[arg]>, ...]);
+ int fscanf(FILE *<[fd]>, const char *<[format]> [, <[arg]>, ...]);
+ int sscanf(const char *<[str]>, const char *<[format]>
+ [, <[arg]>, ...]);
+
+
+TRAD_SYNOPSIS
+ #include <stdio.h>
+
+ int scanf(<[format]> [, <[arg]>, ...])
+ char *<[format]>;
+
+ int fscanf(<[fd]>, <[format]> [, <[arg]>, ...]);
+ FILE *<[fd]>;
+ char *<[format]>;
+
+ int sscanf(<[str]>, <[format]> [, <[arg]>, ...]);
+ char *<[str]>;
+ char *<[format]>;
+
+
+DESCRIPTION
+ <<scanf>> scans a series of input fields from standard input,
+ one character at a time. Each field is interpreted according to
+ a format specifier passed to <<scanf>> in the format string at
+ <<*<[format]>>>. <<scanf>> 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.
+
+ <<scanf>> often produces unexpected results if the input diverges from
+ an expected pattern. Since the combination of <<gets>> or <<fgets>>
+ followed by <<sscanf>> 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.
+
+ <<fscanf>> and <<sscanf>> are identical to <<scanf>>, other than the
+ source of input: <<fscanf>> reads from a file, and <<sscanf>>
+ from a string.
+
+ The string at <<*<[format]>>> is a 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 <<scanf>> 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 <<scanf>> encounters a non-whitespace
+ character in the format string it will read, but not store
+ a matching non-whitespace character.
+
+ Format specifications tell <<scanf>> 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, <<scanf>>
+ 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 character occurs
+ before <[width]> character are read, the characters up
+ to that character are read, converted, and stored.
+ Then <<scanf>> proceeds to the next format specification.
+
+ o size
+ <<h>>, <<l>>, and <<L>> are optional size characters which
+ override the default way that <<scanf>> interprets the
+ data type of the corresponding argument.
+
+
+.Modifier Type(s)
+. h d, i, o, u, x convert input to short,
+. store in short object
+.
+. h D, I, O, U, X no effect
+. e, f, c, s, n, p
+.
+. l d, i, o, u, x convert input to long,
+. store in long object
+.
+. l e, f, g convert input to double
+. store in a double object
+.
+. l D, I, O, U, X no effect
+. c, s, n, p
+.
+. L d, i, o, u, x convert to long double,
+. store in long double
+.
+. L all others no effect
+
+
+ o <[type]>
+
+ A character to specify what kind of conversion
+ <<scanf>> performs. Here is a table of the conversion
+ characters:
+
+ o+
+ o %
+ No conversion is done; the percent character (<<%>>) is stored.
+
+ o c
+ Scans one character. Corresponding <[arg]>: <<(char *arg)>>.
+
+ o s
+ Reads a character string into the array supplied.
+ Corresponding <[arg]>: <<(char 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 D
+ Reads a decimal integer into the corresponding
+ <[arg]>: <<(long *arg)>>.
+
+ o o
+ Reads an octal integer into the corresponding <[arg]>: <<(int *arg)>>.
+
+ o O
+ Reads an octal integer into the corresponding <[arg]>: <<(long *arg)>>.
+
+ o u
+ Reads an unsigned decimal integer into the corresponding
+ <[arg]>: <<(unsigned int *arg)>>.
+
+
+ o U
+ Reads an unsigned decimal integer into the corresponding <[arg]>:
+ <<(unsigned long *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 I
+ Reads a decimal, octal or hexadecimal integer into the
+ corresponding <[arg]>: <<(long *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 <<scanf>> 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 also a range facility
+ which you can use as a shortcut. <<%[0-9] >> matches all decimal digits.
+ The hyphen must not be the first or last character in the set.
+ The character prior to the hyphen must be lexically less than the
+ character after it.
+
+ Here are some <[pattern]> examples:
+ o+
+ o %[abcd]
+ matches strings containing only <<a>>, <<b>>, <<c>>, and <<d>>.
+
+ o %[^abcd]
+ matches strings containing any characters except <<a>>, <<b>>,
+ <<c>>, or <<d>>
+
+ o %[A-DW-Z]
+ matches strings containing <<A>>, <<B>>, <<C>>, <<D>>, <<W>>,
+ <<X>>, <<Y>>, <<Z>>
+
+ o %[z-a]
+ matches the characters <<z>>, <<->>, and <<a>>
+ 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
+ <<scanf>> returns the number of input fields successfully
+ scanned, converted and stored; the return value does
+ not include scanned fields which were not stored.
+
+ If <<scanf>> attempts to read at end-of-file, the return
+ value is <<EOF>>.
+
+ If no fields were stored, the return value is <<0>>.
+
+ <<scanf>> might stop scanning a particular field before
+ reaching the normal field end character, or may
+ terminate entirely.
+
+ <<scanf>> 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 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 character in the input field does not appear
+ in the search set (or does appear in the inverted search set).
+ O-
+
+ When <<scanf>> 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.
+
+ <<scanf>> will terminate under the following circumstances:
+
+ O+
+ o The next character in the input field conflicts
+ with a corresponding non-whitespace character in the
+ format string.
+
+ o The next character in the input field is <<EOF>>.
+
+ o The format string has been exhausted.
+ O-
+
+ When the format string contains a character sequence that is
+ not part of a format specification, the same character
+ sequence must appear in the input; <<scanf>> will
+ scan but not store the matched characters. If a
+ conflict occurs, the first conflicting character remains in the input
+ as if it had never been read.
+
+PORTABILITY
+<<scanf>> is ANSI C.
+
+Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
+<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
+*/
+
+#include <_ansi.h>
+#include <reent.h>
+#include <stdio.h>
+#include <string.h>
+#ifdef _HAVE_STDC
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#include "local.h"
+
+/* | ARGSUSED */
+/*SUPPRESS 590*/
+static
+int
+eofread (cookie, buf, len)
+ _PTR cookie;
+ char *buf;
+ int len;
+{
+ return 0;
+}
+
+#ifdef _HAVE_STDC
+int
+_DEFUN (sscanf, (str, fmt), _CONST char *str _AND _CONST char *fmt _DOTS)
+#else
+int
+sscanf (str, fmt, va_alist)
+ _CONST char *str;
+ _CONST char *fmt;
+ va_dcl
+#endif
+{
+ int ret;
+ va_list ap;
+ FILE f;
+
+ f._flags = __SRD;
+ f._bf._base = f._p = (unsigned char *) str;
+ f._bf._size = f._r = strlen (str);
+ f._read = eofread;
+ f._ub._base = NULL;
+ f._lb._base = NULL;
+ f._data = _REENT;
+#ifdef _HAVE_STDC
+ va_start (ap, fmt);
+#else
+ va_start (ap);
+#endif
+ ret = __svfscanf (&f, fmt, ap);
+ va_end (ap);
+ return ret;
+}