1*4887Schin /***********************************************************************
2*4887Schin *                                                                      *
3*4887Schin *               This software is part of the ast package               *
4*4887Schin *           Copyright (c) 1985-2007 AT&T Knowledge Ventures            *
5*4887Schin *                      and is licensed under the                       *
6*4887Schin *                  Common Public License, Version 1.0                  *
7*4887Schin *                      by AT&T Knowledge Ventures                      *
8*4887Schin *                                                                      *
9*4887Schin *                A copy of the License is available at                 *
10*4887Schin *            http://www.opensource.org/licenses/cpl1.0.txt             *
11*4887Schin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12*4887Schin *                                                                      *
13*4887Schin *              Information and Software Systems Research               *
14*4887Schin *                            AT&T Research                             *
15*4887Schin *                           Florham Park NJ                            *
16*4887Schin *                                                                      *
17*4887Schin *                 Glenn Fowler <gsf@research.att.com>                  *
18*4887Schin *                  David Korn <dgk@research.att.com>                   *
19*4887Schin *                   Phong Vo <kpv@research.att.com>                    *
20*4887Schin *                                                                      *
21*4887Schin ***********************************************************************/
22*4887Schin #pragma prototyped
23*4887Schin 
24*4887Schin #include "stdhdr.h"
25*4887Schin 
26*4887Schin extern char*
27*4887Schin _stdgets(Sfio_t* f, char* us, int n, int isgets)
28*4887Schin {
29*4887Schin 	int		p;
30*4887Schin 	unsigned char*	is;
31*4887Schin 	unsigned char*	ps;
32*4887Schin 
33*4887Schin 	if(n <= 0 || !us || (f->mode != SF_READ && _sfmode(f,SF_READ,0) < 0))
34*4887Schin 		return NIL(char*);
35*4887Schin 
36*4887Schin 	SFLOCK(f,0);
37*4887Schin 
38*4887Schin 	n -= 1;
39*4887Schin 	is = (uchar*)us;
40*4887Schin 
41*4887Schin 	while(n)
42*4887Schin 	{	/* peek the read buffer for data */
43*4887Schin 		if((p = f->endb - (ps = f->next)) <= 0 )
44*4887Schin 		{	f->getr = '\n';
45*4887Schin 			f->mode |= SF_RC;
46*4887Schin 			if(SFRPEEK(f,ps,p) <= 0)
47*4887Schin 				break;
48*4887Schin 		}
49*4887Schin 
50*4887Schin 		if(p > n)
51*4887Schin 			p = n;
52*4887Schin 
53*4887Schin #if _lib_memccpy
54*4887Schin 		if((ps = (uchar*)memccpy((char*)is,(char*)ps,'\n',p)) != NIL(uchar*))
55*4887Schin 			p = ps-is;
56*4887Schin 		is += p;
57*4887Schin 		ps  = f->next+p;
58*4887Schin #else
59*4887Schin 		if(!(f->flags&(SF_BOTH|SF_MALLOC)))
60*4887Schin 		{	while(p-- && (*is++ = *ps++) != '\n')
61*4887Schin 				;
62*4887Schin 			p = ps-f->next;
63*4887Schin 		}
64*4887Schin 		else
65*4887Schin 		{	reg int	c = ps[p-1];
66*4887Schin 			if(c != '\n')
67*4887Schin 				ps[p-1] = '\n';
68*4887Schin 			while((*is++ = *ps++) != '\n')
69*4887Schin 				;
70*4887Schin 			if(c != '\n')
71*4887Schin 			{	f->next[p-1] = c;
72*4887Schin 				if((ps-f->next) >= p)
73*4887Schin 					is[-1] = c;
74*4887Schin 			}
75*4887Schin 		}
76*4887Schin #endif
77*4887Schin 
78*4887Schin 		/* gobble up read data and continue */
79*4887Schin 		f->next = ps;
80*4887Schin 		if(is[-1] == '\n')
81*4887Schin 			break;
82*4887Schin 		else if(n > 0)
83*4887Schin 			n -= p;
84*4887Schin 	}
85*4887Schin 
86*4887Schin 	if((_Sfi = is - ((uchar*)us)) <= 0)
87*4887Schin 		us = NIL(char*);
88*4887Schin 	else if(isgets && is[-1] == '\n')
89*4887Schin 	{	is[-1] = '\0';
90*4887Schin 		_Sfi -= 1;
91*4887Schin 	}
92*4887Schin 	else	*is = '\0';
93*4887Schin 
94*4887Schin 	SFOPEN(f,0);
95*4887Schin 	return us;
96*4887Schin }
97*4887Schin 
98*4887Schin char*
99*4887Schin fgets(char* s, int n, Sfio_t* f)
100*4887Schin {
101*4887Schin 	STDIO_PTR(f, "fgets", char*, (char*, int, Sfio_t*), (s, n, f))
102*4887Schin 
103*4887Schin 	return _stdgets(f, s, n, 0);
104*4887Schin }
105*4887Schin 
106*4887Schin char*
107*4887Schin gets(char* s)
108*4887Schin {
109*4887Schin 	return _stdgets(sfstdin, s, BUFSIZ, 1);
110*4887Schin }
111