1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
21 ***********************************************************************/
24 /* Push back one byte to a given SF_READ stream
26 ** Written by Kiem-Phong Vo.
29 static int _uexcept(Sfio_t
* f
, int type
, Void_t
* val
, Sfdisc_t
* disc
)
31 static int _uexcept(f
,type
,val
,disc
)
40 /* hmm! This should never happen */
44 /* close the unget stream */
45 if(type
!= SF_CLOSING
)
46 (void)sfclose((*_Sfstack
)(f
,NIL(Sfio_t
*)));
52 int sfungetc(Sfio_t
* f
, int c
)
55 Sfio_t
* f
; /* push back one byte to this stream */
56 int c
; /* the value to be pushed back */
64 if(c
< 0 || (f
->mode
!= SF_READ
&& _sfmode(f
,SF_READ
,0) < 0))
68 /* fast handling of the typical unget */
69 if(f
->next
> f
->data
&& f
->next
[-1] == (uchar
)c
)
74 /* make a string stream for unget characters */
75 if(f
->disc
!= _Sfudisc
)
76 { if(!(uf
= sfnew(NIL(Sfio_t
*),NIL(char*),(size_t)SF_UNBOUND
,
77 -1,SF_STRING
|SF_READ
)))
81 _Sfudisc
->exceptf
= _uexcept
;
83 SFOPEN(f
,0); (void)sfstack(f
,uf
); SFLOCK(f
,0);
87 if(f
->next
== f
->data
)
91 if(!(data
= (uchar
*)malloc(f
->size
+16)))
95 f
->flags
|= SF_MALLOC
;
97 memcpy((char*)(data
+16),(char*)f
->data
,f
->size
);
101 f
->endb
= data
+f
->size
;
104 *--f
->next
= (uchar
)c
;