OSDN Git Service

Initial revision
[pf3gnuchains/pf3gnuchains3x.git] / newlib / libc / stdio / fgets.c
1 /*
2  * Copyright (c) 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17
18 /*
19
20 FUNCTION
21         <<fgets>>---get character string from a file or stream
22 INDEX
23         fgets
24
25 ANSI_SYNOPSIS
26         #include <stdio.h>
27         char *fgets(char *<[buf]>, int <[n]>, FILE *<[fp]>);
28
29 TRAD_SYNOPSIS
30         #include <stdio.h>
31         char *fgets(<[buf]>,<[n]>,<[fp]>)
32         char *<[buf]>;
33         int <[n]>;
34         FILE *<[fp]>;
35
36 DESCRIPTION
37         Reads at most <[n-1]> characters from <[fp]> until a newline
38         is found. The characters including to the newline are stored
39         in <[buf]>. The buffer is terminated with a 0.
40
41
42 RETURNS
43         <<fgets>> returns the buffer passed to it, with the data
44         filled in. If end of file occurs with some data already
45         accumulated, the data is returned with no other indication. If
46         no data are read, NULL is returned instead.
47
48 PORTABILITY
49         <<fgets>> should replace all uses of <<gets>>. Note however
50         that <<fgets>> returns all of the data, while <<gets>> removes
51         the trailing newline (with no indication that it has done so.)
52
53 Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
54 <<lseek>>, <<read>>, <<sbrk>>, <<write>>.
55 */
56
57 #include <stdio.h>
58 #include <string.h>
59
60 extern int __srefill ();
61
62 /*
63  * Read at most n-1 characters from the given file.
64  * Stop when a newline has been read, or the count runs out.
65  * Return first argument, or NULL if no characters were read.
66  */
67
68 char *
69 _DEFUN (fgets, (buf, n, fp),
70         char *buf _AND
71         int n _AND
72         FILE * fp)
73 {
74   size_t len;
75   char *s;
76   unsigned char *p, *t;
77
78   if (n < 2)                    /* sanity check */
79     return 0;
80
81   s = buf;
82   n--;                          /* leave space for NUL */
83   do
84     {
85       /*
86        * If the buffer is empty, refill it.
87        */
88       if ((len = fp->_r) <= 0)
89         {
90           if (__srefill (fp))
91             {
92               /* EOF: stop with partial or no line */
93               if (s == buf)
94                 return 0;
95               break;
96             }
97           len = fp->_r;
98         }
99       p = fp->_p;
100
101       /*
102        * Scan through at most n bytes of the current buffer,
103        * looking for '\n'.  If found, copy up to and including
104        * newline, and stop.  Otherwise, copy entire chunk
105        * and loop.
106        */
107       if (len > n)
108         len = n;
109       t = (unsigned char *) memchr ((_PTR) p, '\n', len);
110       if (t != 0)
111         {
112           len = ++t - p;
113           fp->_r -= len;
114           fp->_p = t;
115           (void) memcpy ((_PTR) s, (_PTR) p, len);
116           s[len] = 0;
117           return (buf);
118         }
119       fp->_r -= len;
120       fp->_p += len;
121       (void) memcpy ((_PTR) s, (_PTR) p, len);
122       s += len;
123     }
124   while ((n -= len) != 0);
125   *s = 0;
126   return buf;
127 }