os/ossrv/genericopenlibs/cstdlib/LSTDIO/FGETS.C
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/* FGETS.C
sl@0
     2
 * 
sl@0
     3
 * Portions Copyright (c) 1990-1999 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
        <<fgets>>---get character string from a file or stream
sl@0
    28
INDEX
sl@0
    29
	fgets
sl@0
    30
sl@0
    31
ANSI_SYNOPSIS
sl@0
    32
        #include <stdio.h>
sl@0
    33
	char *fgets(char *<[buf]>, int <[n]>, FILE *<[fp]>);
sl@0
    34
sl@0
    35
TRAD_SYNOPSIS
sl@0
    36
	#include <stdio.h>
sl@0
    37
	char *fgets(<[buf]>,<[n]>,<[fp]>)
sl@0
    38
        char *<[buf]>;
sl@0
    39
	int <[n]>;
sl@0
    40
	FILE *<[fp]>;
sl@0
    41
sl@0
    42
DESCRIPTION
sl@0
    43
	Reads at most <[n-1]> characters from <[fp]> until a newline
sl@0
    44
	is found. The characters including to the newline are stored
sl@0
    45
	in <[buf]>. The buffer is terminated with a 0.
sl@0
    46
sl@0
    47
sl@0
    48
RETURNS
sl@0
    49
	<<fgets>> returns the buffer passed to it, with the data
sl@0
    50
	filled in. If end of file occurs with some data already
sl@0
    51
	accumulated, the data is returned with no other indication. If
sl@0
    52
	no data are read, NULL is returned instead.
sl@0
    53
sl@0
    54
PORTABILITY
sl@0
    55
	<<fgets>> should replace all uses of <<gets>>. Note however
sl@0
    56
	that <<fgets>> returns all of the data, while <<gets>> removes
sl@0
    57
	the trailing newline (with no indication that it has done so.)
sl@0
    58
sl@0
    59
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
sl@0
    60
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
sl@0
    61
*/
sl@0
    62
sl@0
    63
#include <stdio.h>
sl@0
    64
#include <string.h>
sl@0
    65
#include "LOCAL.H"
sl@0
    66
sl@0
    67
/**
sl@0
    68
Get a string from a stream.
sl@0
    69
@return   On success, the string read is returned.
sl@0
    70
On end-of-file or error, null pointer is returned.
sl@0
    71
@param buf pointer to a buffer where to store data read. 
sl@0
    72
@param n max number of bytes to be read. 
sl@0
    73
@param fp pointer to an open file.
sl@0
    74
*/
sl@0
    75
EXPORT_C char *
sl@0
    76
fgets (char *buf, int n, FILE * fp)
sl@0
    77
{
sl@0
    78
  size_t len;
sl@0
    79
  char *s;
sl@0
    80
  unsigned char *p, *t;
sl@0
    81
sl@0
    82
  if (n < 2)			/* sanity check */
sl@0
    83
    return 0;
sl@0
    84
sl@0
    85
  s = buf;
sl@0
    86
  n--;				/* leave space for NUL */
sl@0
    87
  do
sl@0
    88
    {
sl@0
    89
      /*
sl@0
    90
       * If the buffer is empty, refill it.
sl@0
    91
       */
sl@0
    92
      if ((len = fp->_r) <= 0)
sl@0
    93
	{
sl@0
    94
	  if (__srefill (fp))
sl@0
    95
	    {
sl@0
    96
	      /* EOF: stop with partial or no line */
sl@0
    97
	      if (s == buf)
sl@0
    98
		return 0;
sl@0
    99
	      break;
sl@0
   100
	    }
sl@0
   101
	  len = fp->_r;
sl@0
   102
	}
sl@0
   103
      p = fp->_p;
sl@0
   104
sl@0
   105
      /*
sl@0
   106
       * Scan through at most n bytes of the current buffer,
sl@0
   107
       * looking for '\n'.  If found, copy up to and including
sl@0
   108
       * newline, and stop.  Otherwise, copy entire chunk
sl@0
   109
       * and loop.
sl@0
   110
       */
sl@0
   111
      if ((int)len > n)
sl@0
   112
	len = n;
sl@0
   113
      t = (unsigned char *) memchr ((void*) p, '\n', len);
sl@0
   114
      if (t != 0)
sl@0
   115
	{
sl@0
   116
	  len = ++t - p;
sl@0
   117
	  fp->_r -= len;
sl@0
   118
	  fp->_p = t;
sl@0
   119
	  (void) memcpy ((void*) s, (void*) p, len);
sl@0
   120
	  s[len] = 0;
sl@0
   121
	  return (buf);
sl@0
   122
	}
sl@0
   123
      fp->_r -= len;
sl@0
   124
      fp->_p += len;
sl@0
   125
      (void) memcpy ((void*) s, (void*) p, len);
sl@0
   126
      s += len;
sl@0
   127
    }
sl@0
   128
  while ((n -= len) != 0);
sl@0
   129
  *s = 0;
sl@0
   130
  return buf;
sl@0
   131
}