/* fscanf.c - scan a file. stdio.h */ /* Copyright 1992-1995 Wind River Systems, Inc. */ /* modification history -------------------- 01d,24jan95,rhp doc: avoid 'L' in fscanf(), no long doubles in VxWorks (see SPR#3886) 01c,05mar93,jdi documentation cleanup for 5.1. 01b,20sep92,smb documentation additions 01a,29jul92,jcf Added OBJ_VERIFY +smb taken from UCB stdio */ /* DESCRIPTION * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. INCLUDE FILE: stdio.h, stdarg.h SEE ALSO: American National Standard X3.159-1989 NOMANUAL */ #include "vxWorks.h" #include "fioLib.h" #include "stdarg.h" #include "objLib.h" #include "private/stdioP.h" /****************************************************************************** * * fscanf - read and convert characters from a stream (ANSI) * * This routine reads characters from a specified stream, and interprets them * according to format specifications in the string , which specifies * the admissible input sequences and how they are to be converted for * assignment, using subsequent arguments as pointers to the objects to * receive the converted input. * * If there are insufficient arguments for the format, the behavior is * undefined. If the format is exhausted while arguments remain, the excess * arguments are evaluated but are otherwise ignored. * * The format is a multibyte character sequence, beginning and ending in * its initial shift state. The format is composed of zero or more directives: * one or more white-space characters; an ordinary multibyte character (neither * `%' nor a white-space character); or a conversion specification. Each * conversion specification is introduced by the `%' character. After the `%', * the following appear in sequence: * * .iP "" 4 * An optional assignment-suppressing character `*'. * .iP * An optional non-zero decimal integer that specifies the maximum field * width. * .iP * An optional `h' or `l' (el) indicating the size of the receiving * object. The conversion specifiers `d', `i', and `n' should be preceded by * `h' if the corresponding argument is a pointer to `short int' rather * than a pointer to `int', or by `l' if it is a pointer to `long int'. * Similarly, the conversion specifiers `o', `u', and `x' shall be preceded * by `h' if the corresponding argument is a pointer to `unsigned short int' * rather than a pointer to `unsigned int', or by `l' if it is a pointer to * `unsigned long int'. Finally, the conversion specifiers `e', `f', and `g' * shall be preceded by `l' if the corresponding argument is a pointer to * `double' rather than a pointer to `float'. If an `h' or `l' appears * with any other conversion specifier, the behavior is undefined. * * \&WARNING: ANSI C also specifies an optional `L' in some of the same * contexts as `l' above, corresponding to a `long double *' argument. * However, the current release of the VxWorks libraries does not support * `long double' data; using the optional `L' gives unpredictable results. * .iP * A character that specifies the type of conversion to be applied. The * valid conversion specifiers are described below. * .LP * * The fscanf() routine executes each directive of the format in turn. If a * directive fails, as detailed below, fscanf() returns. Failures * are described as input failures (due to the unavailability of input * characters), or matching failures (due to inappropriate input). * * A directive composed of white-space character(s) is executed by reading * input up to the first non-white-space character (which remains unread), * or until no more characters can be read. * * A directive that is an ordinary multibyte character is executed by reading * the next characters of the stream. If one of the characters differs from * one comprising the directive, the directive fails, and the differing and * subsequent characters remain unread. * * A directive that is a conversion specification defines a set of matching * input sequences, as described below for each specifier. A conversion * specification is executed in the following steps: * * Input white-space characters (as specified by the isspace() function) are * skipped, unless the specification includes a `[', `c', or `n' specifier. * * An input item is read from the stream, unless the specification includes * an `n' specifier. An input item is defined as the longest matching * sequence of input characters, unless that exceeds a specified field width, * in which case it is the initial subsequence of that length in the * sequence. The first character, if any, after the input item remains * unread. If the length of the input item is zero, the execution of the * directive fails: this condition is a matching failure, unless an error * prevented input from the stream, in which case it is an input failure. * * Except in the case of a `%' specifier, the input item is converted to a * type appropriate to the conversion specifier. If the input item is not a * matching sequence, the execution of the directive fails: this condition * is a matching failure. Unless assignment suppression was indicated by a * `*', the result of the conversion is placed in the object pointed to by * the first argument following the argument that has not already * received a conversion result. If this object does not have an appropriate * type, or if the result of the conversion cannot be represented in the * space provided, the behavior is undefined. * * The following conversion specifiers are valid: * * .iP `d' * Matches an optionally signed decimal integer whose format is * the same as expected for the subject sequence of the strtol() * function with the value 10 for the argument. The * corresponding argument should be a pointer to `int'. * .iP `i' * Matches an optionally signed integer, whose format is the * same as expected for the subject sequence of the strtol() * function with the value 0 for the argument. The * corresponding argument should be a pointer to `int'. * .iP `o' * Matches an optionally signed octal integer, whose format is the * same as expected for the subject sequence of the strtoul() * function with the value 8 for the argument. The * corresponding argument should be a pointer to `unsigned int'. * .iP `u' * Matches an optionally signed decimal integer, whose format is * the same as expected for the subject sequence of the strtoul() * function with the value 10 for the argument. The * corresponding argument should be a pointer to `unsigned int'. * .iP `x' * Matches an optionally signed hexadecimal integer, whose format is * the same as expected for the subject sequence of the strtoul() * function with the value 16 for the argument. The * corresponding argument should be a pointer to `unsigned int'. * .iP "`e', `f', `g'" * Match an optionally signed floating-point number, whose format * is the same as expected for the subject string of the strtod() * function. The corresponding argument should be a pointer to `float'. * .iP `s' * Matches a sequence of non-white-space characters. The * corresponding argument should be a pointer to the initial * character of an array large enough to accept the sequence * and a terminating null character, which will be added * automatically. * .iP `[' * Matches a non-empty sequence of characters from a set of * expected characters (the `scanset'). The corresponding argument * should be a pointer to the initial character of an array large * enough to accept the sequence and a terminating null character, * which is added automatically. The conversion specifier * includes all subsequent character in the format string, up to * and including the matching right bracket (`]'). The characters * between the brackets (the `scanlist') comprise the scanset, * unless the character after the left bracket is a circumflex (`^') * in which case the scanset contains all characters that do not * appear in the scanlist between the circumflex and the right * bracket. If the conversion specifier begins with "[]" or "[^]", the * right bracket character is in the scanlist and the next * right bracket character is the matching right bracket that ends * the specification; otherwise the first right bracket character * is the one that ends the specification. * .iP `c' * Matches a sequence of characters of the number specified by the * field width (1 if no field width is present in the directive). * The corresponding argument should be a pointer to the initial * character of an array large enough to accept the sequence. * No null character is added. * .iP `p' * Matches an implementation-defined set of sequences, which should be * the same as the set of sequences that may be produced by the %p * conversion of the fprintf() function. The corresponding argument * should be a pointer to a pointer to `void'. VxWorks defines its * pointer input field to be consistent with pointers written by the * fprintf() function ("0x" hexadecimal notation). If the input item is * a value converted earlier during the same program execution, the * pointer that results should compare equal to that value; otherwise * the behavior of the %p conversion is undefined. * .iP `n' * No input is consumed. The corresponding argument should be a pointer to * `int' into which the number of characters read from the input stream so * far by this call to fscanf() is written. Execution of a %n directive does * not increment the assignment count returned when fscanf() completes * execution. * .iP `%' * Matches a single `%'; no conversion or assignment occurs. The * complete conversion specification is %%. * .LP * * If a conversion specification is invalid, the behavior is undefined. * * The conversion specifiers `E', `G', and `X' are also valid and behave the * same as `e', `g', and `x', respectively. * * If end-of-file is encountered during input, conversion is terminated. If * end-of-file occurs before any characters matching the current directive * have been read (other than leading white space, where permitted), execution * of the current directive terminates with an input failure; otherwise, unless * execution of the current directive is terminated with a matching failure, * execution of the following directive (if any) is terminated with an input * failure. * * If conversion terminates on a conflicting input character, the offending * input character is left unread in the input stream. Trailing white space * (including new-line characters) is left unread unless matched by a * directive. The success of literal matches and suppressed assignments is * not directly determinable other than via the %n directive. * * INCLUDE FILES: stdio.h * * RETURNS: * The number of input items assigned, which can be fewer than provided for, * or even zero, in the event of an early matching failure; or EOF if an * input failure occurs before any conversion. * * SEE ALSO: scanf(), sscanf() */ int fscanf ( FILE * fp, /* stream to read from */ char const * fmt, /* format string */ ... /* arguments to format string */ ) { int nArgs; int unget; va_list vaList; /* vararg list */ if (OBJ_VERIFY (fp, fpClassId) != OK) return (EOF); va_start (vaList, fmt); nArgs = fioScanV (fmt, fgetc, (int) fp, &unget, vaList); va_end (vaList); if (unget != -1) ungetc (unget, fp); return (nArgs); }