os/ossrv/genericopenlibs/cstdlib/LSTDIO/SSCANF.C
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/* SSCANF.C
sl@0
     2
 * 
sl@0
     3
 * Portions Copyright (c) 1990-2006 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     4
 * All rights reserved.
sl@0
     5
 */
sl@0
     6
sl@0
     7
/*
sl@0
     8
 * Copyright (c) 1990 The Regents of the University of California.
sl@0
     9
 * All rights reserved.
sl@0
    10
 *
sl@0
    11
 * Redistribution and use in source and binary forms are permitted
sl@0
    12
 * provided that the above copyright notice and this paragraph are
sl@0
    13
 * duplicated in all such forms and that any documentation,
sl@0
    14
 * advertising materials, and other materials related to such
sl@0
    15
 * distribution and use acknowledge that the software was developed
sl@0
    16
 * by the University of California, Berkeley.  The name of the
sl@0
    17
 * University may not be used to endorse or promote products derived
sl@0
    18
 * from this software without specific prior written permission.
sl@0
    19
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
sl@0
    20
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
sl@0
    21
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
sl@0
    22
 */
sl@0
    23
sl@0
    24
/*
sl@0
    25
sl@0
    26
FUNCTION
sl@0
    27
	<<scanf>>, <<fscanf>>, <<sscanf>>---scan and format input
sl@0
    28
sl@0
    29
INDEX
sl@0
    30
	scanf
sl@0
    31
INDEX
sl@0
    32
	fscanf
sl@0
    33
INDEX
sl@0
    34
	sscanf
sl@0
    35
sl@0
    36
ANSI_SYNOPSIS
sl@0
    37
        #include <stdio.h>
sl@0
    38
sl@0
    39
        int scanf(const char *<[format]> [, <[arg]>, ...]);
sl@0
    40
        int fscanf(FILE *<[fd]>, const char *<[format]> [, <[arg]>, ...]);
sl@0
    41
        int sscanf(const char *<[str]>, const char *<[format]> 
sl@0
    42
                   [, <[arg]>, ...]);
sl@0
    43
sl@0
    44
sl@0
    45
TRAD_SYNOPSIS
sl@0
    46
	#include <stdio.h>
sl@0
    47
sl@0
    48
	int scanf(<[format]> [, <[arg]>, ...])
sl@0
    49
	char *<[format]>;
sl@0
    50
sl@0
    51
	int fscanf(<[fd]>, <[format]> [, <[arg]>, ...]);
sl@0
    52
	FILE *<[fd]>;
sl@0
    53
	char *<[format]>;
sl@0
    54
sl@0
    55
	int sscanf(<[str]>, <[format]> [, <[arg]>, ...]);
sl@0
    56
	char *<[str]>;
sl@0
    57
	char *<[format]>;
sl@0
    58
sl@0
    59
sl@0
    60
DESCRIPTION
sl@0
    61
        <<scanf>> scans a series of input fields from standard input,
sl@0
    62
		one character at a time.  Each field is interpreted according to
sl@0
    63
		a format specifier passed to <<scanf>> in the format string at
sl@0
    64
        <<*<[format]>>>.  <<scanf>> stores the interpreted input from
sl@0
    65
		each field at the address passed to it as the corresponding argument
sl@0
    66
		following <[format]>.  You must supply the same number of
sl@0
    67
		format specifiers and address arguments as there are input fields.
sl@0
    68
sl@0
    69
        There must be sufficient address arguments for the given format
sl@0
    70
        specifiers; if not the results are unpredictable and likely
sl@0
    71
        disasterous.  Excess address arguments are merely ignored.
sl@0
    72
sl@0
    73
        <<scanf>> often produces unexpected results if the input diverges from
sl@0
    74
        an expected pattern. Since the combination of <<gets>> or <<fgets>>
sl@0
    75
        followed by <<sscanf>> is safe and easy, that is the preferred way
sl@0
    76
        to be certain that a program is synchronized with input at the end
sl@0
    77
		of a line.
sl@0
    78
sl@0
    79
        <<fscanf>> and <<sscanf>> are identical to <<scanf>>, other than the
sl@0
    80
        source of input: <<fscanf>> reads from a file, and <<sscanf>>
sl@0
    81
		from a string.
sl@0
    82
sl@0
    83
        The string at <<*<[format]>>> is a character sequence composed
sl@0
    84
        of zero or more directives. Directives are composed of
sl@0
    85
        one or more whitespace characters, non-whitespace characters,
sl@0
    86
        and format specifications.
sl@0
    87
sl@0
    88
        Whitespace characters are blank (<< >>), tab (<<\t>>), or
sl@0
    89
		newline (<<\n>>).
sl@0
    90
        When <<scanf>> encounters a whitespace character in the format string
sl@0
    91
        it will read (but not store) all consecutive whitespace characters
sl@0
    92
        up to the next non-whitespace character in the input.
sl@0
    93
sl@0
    94
        Non-whitespace characters are all other ASCII characters except the
sl@0
    95
        percent sign (<<%>>).  When <<scanf>> encounters a non-whitespace
sl@0
    96
        character in the format string it will read, but not store
sl@0
    97
        a matching non-whitespace character.
sl@0
    98
sl@0
    99
        Format specifications tell <<scanf>> to read and convert characters
sl@0
   100
        from the input field into specific types of values, and store then
sl@0
   101
        in the locations specified by the address arguments.
sl@0
   102
sl@0
   103
        Trailing whitespace is left unread unless explicitly
sl@0
   104
        matched in the format string.
sl@0
   105
sl@0
   106
        The format specifiers must begin with a percent sign (<<%>>)
sl@0
   107
        and have the following form:
sl@0
   108
sl@0
   109
.       %[*][<[width]>][<[size]>]<[type]>
sl@0
   110
sl@0
   111
        Each format specification begins with the percent character (<<%>>).
sl@0
   112
        The other fields are:
sl@0
   113
	o+
sl@0
   114
		o *
sl@0
   115
		an optional marker; if present, it suppresses interpretation and
sl@0
   116
        assignment of this input field.
sl@0
   117
sl@0
   118
        o <[width]>
sl@0
   119
		an optional maximum field width: a decimal integer,
sl@0
   120
		which controls the maximum number of characters that
sl@0
   121
		will be read before converting the current input field.  If the
sl@0
   122
		input field has fewer than <[width]> characters, <<scanf>>
sl@0
   123
		reads all the characters in the field, and then
sl@0
   124
		proceeds with the next field and its format specification.
sl@0
   125
sl@0
   126
		If a whitespace or a non-convertable character occurs
sl@0
   127
		before <[width]> character are read, the characters up
sl@0
   128
		to that character are read, converted, and stored.
sl@0
   129
		Then <<scanf>> proceeds to the next format specification.
sl@0
   130
sl@0
   131
        o size
sl@0
   132
		<<h>>, <<l>>, and <<L>> are optional size characters which
sl@0
   133
		override the default way that <<scanf>> interprets the
sl@0
   134
		data type of the corresponding argument.
sl@0
   135
sl@0
   136
sl@0
   137
.Modifier   Type(s)
sl@0
   138
.   h       d, i, o, u, x     convert input to short,
sl@0
   139
.                             store in short object
sl@0
   140
.
sl@0
   141
.   h       D, I, O, U, X     no effect
sl@0
   142
.           e, f, c, s, n, p
sl@0
   143
.
sl@0
   144
.   l       d, i, o, u, x     convert input to long,
sl@0
   145
.                             store in long object
sl@0
   146
.
sl@0
   147
.   l       e, f, g           convert input to double
sl@0
   148
.                             store in a double object
sl@0
   149
.
sl@0
   150
.   l       D, I, O, U, X     no effect
sl@0
   151
.           c, s, n, p
sl@0
   152
.
sl@0
   153
.   L       d, i, o, u, x     convert to long double,
sl@0
   154
.                             store in long double
sl@0
   155
.
sl@0
   156
.   L      all others         no effect
sl@0
   157
sl@0
   158
sl@0
   159
        o <[type]>
sl@0
   160
sl@0
   161
		A character to specify what kind of conversion
sl@0
   162
                <<scanf>> performs.  Here is a table of the conversion
sl@0
   163
                characters:
sl@0
   164
sl@0
   165
		o+
sl@0
   166
		o  %
sl@0
   167
		No conversion is done; the percent character (<<%>>) is stored.
sl@0
   168
sl@0
   169
		o c
sl@0
   170
		Scans one character.  Corresponding <[arg]>: <<(char *arg)>>.
sl@0
   171
sl@0
   172
		o s
sl@0
   173
		Reads a character string into the array supplied.
sl@0
   174
		Corresponding <[arg]>: <<(char arg[])>>.
sl@0
   175
sl@0
   176
		o  [<[pattern]>]
sl@0
   177
		Reads a non-empty character string into memory
sl@0
   178
		starting at <[arg]>.  This area must be large
sl@0
   179
		enough to accept the sequence and a
sl@0
   180
		terminating null character which will be added
sl@0
   181
		automatically.  (<[pattern]> is discussed in the paragraph following
sl@0
   182
		this table). Corresponding <[arg]>: <<(char *arg)>>.
sl@0
   183
sl@0
   184
		o d
sl@0
   185
		Reads a decimal integer into the corresponding <[arg]>: <<(int *arg)>>.
sl@0
   186
sl@0
   187
		o D
sl@0
   188
		Reads a decimal integer into the corresponding
sl@0
   189
		<[arg]>: <<(long *arg)>>.
sl@0
   190
sl@0
   191
		o o
sl@0
   192
		Reads an octal integer into the corresponding <[arg]>: <<(int *arg)>>.
sl@0
   193
sl@0
   194
		o O
sl@0
   195
		Reads an octal integer into the corresponding <[arg]>: <<(long *arg)>>.
sl@0
   196
sl@0
   197
		o u
sl@0
   198
		Reads an unsigned decimal integer into the corresponding
sl@0
   199
		<[arg]>: <<(unsigned int *arg)>>.
sl@0
   200
			
sl@0
   201
sl@0
   202
		o U
sl@0
   203
		Reads an unsigned decimal integer into the corresponding <[arg]>:
sl@0
   204
		<<(unsigned long *arg)>>.
sl@0
   205
sl@0
   206
		o x,X
sl@0
   207
		Read a hexadecimal integer into the corresponding <[arg]>:
sl@0
   208
		<<(int *arg)>>.
sl@0
   209
sl@0
   210
		o e, f, g
sl@0
   211
		Read a floating point number into the corresponding <[arg]>:
sl@0
   212
		<<(float *arg)>>.
sl@0
   213
sl@0
   214
		o E, F, G
sl@0
   215
		Read a floating point number into the corresponding <[arg]>:
sl@0
   216
		<<(double *arg)>>.
sl@0
   217
sl@0
   218
		o  i
sl@0
   219
		Reads a decimal, octal or hexadecimal integer into the
sl@0
   220
		corresponding <[arg]>: <<(int *arg)>>.
sl@0
   221
sl@0
   222
		o  I
sl@0
   223
		Reads a decimal, octal or hexadecimal integer into the
sl@0
   224
		corresponding <[arg]>: <<(long *arg)>>.
sl@0
   225
sl@0
   226
		o  n
sl@0
   227
		Stores the number of characters read in the corresponding
sl@0
   228
		<[arg]>: <<(int *arg)>>.
sl@0
   229
sl@0
   230
		o  p
sl@0
   231
                Stores a scanned pointer.  ANSI C leaves the details
sl@0
   232
		to each implementation; this implementation treats
sl@0
   233
		<<%p>> exactly the same as <<%U>>.  Corresponding
sl@0
   234
		<[arg]>: <<(void **arg)>>.  
sl@0
   235
                o-
sl@0
   236
sl@0
   237
	A <[pattern]> of characters surrounded by square brackets can be used
sl@0
   238
	instead of the <<s>> type character.  <[pattern]> is a set of
sl@0
   239
	characters which define a search set of possible characters making up
sl@0
   240
	the <<scanf>> input field.  If the first character in the brackets is a
sl@0
   241
	caret (<<^>>), the search set is inverted to include all ASCII characters
sl@0
   242
	except those between the brackets.  There is also a range facility
sl@0
   243
	which you can use as a shortcut. <<%[0-9] >> matches all decimal digits.
sl@0
   244
	The hyphen must not be the first or last character in the set.
sl@0
   245
	The character prior to the hyphen must be lexically less than the
sl@0
   246
	character after it.
sl@0
   247
sl@0
   248
	Here are some <[pattern]> examples:
sl@0
   249
		o+
sl@0
   250
		o %[abcd]
sl@0
   251
		matches strings containing only <<a>>, <<b>>, <<c>>, and <<d>>.
sl@0
   252
sl@0
   253
		o %[^abcd]
sl@0
   254
		matches strings containing any characters except <<a>>, <<b>>,
sl@0
   255
		<<c>>, or <<d>>
sl@0
   256
sl@0
   257
		o %[A-DW-Z]
sl@0
   258
		matches strings containing <<A>>, <<B>>, <<C>>, <<D>>, <<W>>,
sl@0
   259
		<<X>>, <<Y>>, <<Z>>
sl@0
   260
sl@0
   261
		o %[z-a]
sl@0
   262
		matches the characters  <<z>>, <<->>, and <<a>>
sl@0
   263
		o-
sl@0
   264
sl@0
   265
	Floating point numbers (for field types <<e>>, <<f>>, <<g>>, <<E>>,
sl@0
   266
	<<F>>, <<G>>) must correspond to the following general form:
sl@0
   267
sl@0
   268
.		[+/-] ddddd[.]ddd [E|e[+|-]ddd]
sl@0
   269
sl@0
   270
	where objects inclosed in square brackets are optional, and <<ddd>>
sl@0
   271
	represents decimal, octal, or hexadecimal digits.
sl@0
   272
	o-
sl@0
   273
sl@0
   274
RETURNS
sl@0
   275
        <<scanf>> returns the number of input fields successfully
sl@0
   276
        scanned, converted and stored; the return value does
sl@0
   277
        not include scanned fields which were not stored.
sl@0
   278
sl@0
   279
        If <<scanf>> attempts to read at end-of-file, the return
sl@0
   280
        value is <<EOF>>.
sl@0
   281
sl@0
   282
        If no fields were stored, the return value is <<0>>.
sl@0
   283
sl@0
   284
        <<scanf>> might stop scanning a particular field before
sl@0
   285
        reaching the normal field end character, or may
sl@0
   286
        terminate entirely.
sl@0
   287
sl@0
   288
        <<scanf>> stops scanning and storing the current field
sl@0
   289
        and moves to the next input field (if any)
sl@0
   290
        in any of the following situations:
sl@0
   291
sl@0
   292
	O+
sl@0
   293
	o       The assignment suppressing character (<<*>>) appears
sl@0
   294
	after the <<%>> in the format specification; the current
sl@0
   295
	input field is scanned but not stored.
sl@0
   296
sl@0
   297
	o       <[width]> characters have been read (<[width]> is a
sl@0
   298
	width specification, a positive decimal integer).
sl@0
   299
sl@0
   300
	o       The next character read cannot be converted
sl@0
   301
	under the the current format (for example,
sl@0
   302
	if a <<Z>> is read when the format is decimal).
sl@0
   303
sl@0
   304
	o       The next character in the input field does not appear
sl@0
   305
	in the search set (or does appear in the inverted search set).
sl@0
   306
	O-
sl@0
   307
sl@0
   308
	When <<scanf>> stops scanning the current input field for one of
sl@0
   309
	these reasons, the next character is considered unread and
sl@0
   310
	used as the first character of the following input field, or the
sl@0
   311
	first character in a subsequent read operation on the input.
sl@0
   312
sl@0
   313
	<<scanf>> will terminate under the following circumstances:
sl@0
   314
sl@0
   315
	O+
sl@0
   316
	o       The next character in the input field conflicts
sl@0
   317
	with a corresponding non-whitespace character in the
sl@0
   318
	format string.
sl@0
   319
sl@0
   320
	o       The next character in the input field is <<EOF>>.
sl@0
   321
sl@0
   322
	o       The format string has been exhausted.
sl@0
   323
	O-
sl@0
   324
sl@0
   325
	When the format string contains a character sequence that is
sl@0
   326
	not part of a format specification, the same character
sl@0
   327
	sequence must appear in the input; <<scanf>> will
sl@0
   328
	scan but not store the matched characters.  If a
sl@0
   329
	conflict occurs, the first conflicting character remains in the input
sl@0
   330
	as if it had never been read.
sl@0
   331
sl@0
   332
PORTABILITY
sl@0
   333
<<scanf>> is ANSI C.
sl@0
   334
sl@0
   335
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
sl@0
   336
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
sl@0
   337
*/
sl@0
   338
sl@0
   339
#include <_ansi.h>
sl@0
   340
#include <reent.h>
sl@0
   341
#include <stdio.h>
sl@0
   342
#include <string.h>
sl@0
   343
#include <stdarg.h>
sl@0
   344
#include "LOCAL.H"
sl@0
   345
sl@0
   346
static
sl@0
   347
int
sl@0
   348
eofread (void* cookie,char *buf,int len)
sl@0
   349
{
sl@0
   350
  	cookie=cookie;
sl@0
   351
	buf=buf;
sl@0
   352
	len=len;
sl@0
   353
	return 0;
sl@0
   354
}
sl@0
   355
sl@0
   356
/**
sl@0
   357
Read formatted data from string.
sl@0
   358
Reads data from the buffer specified and stores it
sl@0
   359
into the locations given by argument(s).
sl@0
   360
Locations pointed by each argument are filled with their corresponding type
sl@0
   361
of value requested in the format string.
sl@0
   362
sl@0
   363
@param str Buffer containing the string to be parsed for data. 
sl@0
   364
@param fmt String that can contain one or more of these items:
sl@0
   365
	   Whitespace characters: the function will read and ignore any whitespace
sl@0
   366
 	   characters (this includes blank, newline and tab characters) encountered
sl@0
   367
 	   before the next non-whitespace character. This includes any quantity of
sl@0
   368
 	   whitespace characters (including none). On-whitespace characters (any
sl@0
   369
 	   character not including blank, newline, tab, or any format specifier
sl@0
   370
 	   begining with % character): this cause that the function read and discard
sl@0
   371
 	   any character that match the given non-whitespace character. If this
sl@0
   372
 	   character is not found the function ends returning error.
sl@0
   373
 	   Format specifiers: A sequence of characters begining with '%' indicates
sl@0
   374
 	   that next data has to be readed and stored at the location pointed by its
sl@0
   375
 	   corresponding argument with a given format that is specified following this
sl@0
   376
 	   prototype: %[*][width][modifiers]type
sl@0
   377
 
sl@0
   378
@return	On Success, The number of items succesfully read. This count doesn't include any
sl@0
   379
 		ignored fields.
sl@0
   380
		On Failure, returns EOF, if an error has occurred before the first assignation
sl@0
   381
		could be done and errno may be set.
sl@0
   382
*/
sl@0
   383
EXPORT_C int sscanf(const char *str, const char *fmt, ...)
sl@0
   384
{
sl@0
   385
  int ret;
sl@0
   386
  va_list ap;
sl@0
   387
  FILE f;
sl@0
   388
sl@0
   389
  f._data = _REENT2;
sl@0
   390
  if (!f._data)
sl@0
   391
	return EOF; // Memory for library globals is not allocated (errno not set). 
sl@0
   392
  
sl@0
   393
  f._flags = __SRD;
sl@0
   394
  f._bf._base = f._p = (unsigned char *) str;
sl@0
   395
  f._bf._size = f._r = strlen (str);
sl@0
   396
  f._read = eofread;
sl@0
   397
  f._ub._base = NULL;
sl@0
   398
  f._lb._base = NULL;
sl@0
   399
  
sl@0
   400
  va_start (ap, fmt);
sl@0
   401
  ret = __svfscanf (&f, fmt, ap);
sl@0
   402
  va_end (ap);
sl@0
   403
  return ret;
sl@0
   404
}