sfungetc.c revision 7c2fbfb345896881c631598ee3852ce9ce33fb07
fa9e4066f08beec538e775443c5be79dd423fcabahrens/***********************************************************************
fa9e4066f08beec538e775443c5be79dd423fcabahrens* *
fa9e4066f08beec538e775443c5be79dd423fcabahrens* This software is part of the ast package *
fa9e4066f08beec538e775443c5be79dd423fcabahrens* Copyright (c) 1985-2008 AT&T Intellectual Property *
fa9e4066f08beec538e775443c5be79dd423fcabahrens* and is licensed under the *
fa9e4066f08beec538e775443c5be79dd423fcabahrens* Common Public License, Version 1.0 *
fa9e4066f08beec538e775443c5be79dd423fcabahrens* by AT&T Intellectual Property *
fa9e4066f08beec538e775443c5be79dd423fcabahrens* *
fa9e4066f08beec538e775443c5be79dd423fcabahrens* A copy of the License is available at *
fa9e4066f08beec538e775443c5be79dd423fcabahrens* http://www.opensource.org/licenses/cpl1.0.txt *
fa9e4066f08beec538e775443c5be79dd423fcabahrens* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
fa9e4066f08beec538e775443c5be79dd423fcabahrens* *
fa9e4066f08beec538e775443c5be79dd423fcabahrens* Information and Software Systems Research *
fa9e4066f08beec538e775443c5be79dd423fcabahrens* AT&T Research *
fa9e4066f08beec538e775443c5be79dd423fcabahrens* Florham Park NJ *
fa9e4066f08beec538e775443c5be79dd423fcabahrens* *
fa9e4066f08beec538e775443c5be79dd423fcabahrens* Glenn Fowler <gsf@research.att.com> *
fa9e4066f08beec538e775443c5be79dd423fcabahrens* David Korn <dgk@research.att.com> *
fa9e4066f08beec538e775443c5be79dd423fcabahrens* Phong Vo <kpv@research.att.com> *
fa9e4066f08beec538e775443c5be79dd423fcabahrens* *
fa9e4066f08beec538e775443c5be79dd423fcabahrens***********************************************************************/
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include "sfhdr.h"
6b90ca488b504d3422b169269c3a86ccad80322clling
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* Push back one byte to a given SF_READ stream
fa9e4066f08beec538e775443c5be79dd423fcabahrens**
fa9e4066f08beec538e775443c5be79dd423fcabahrens** Written by Kiem-Phong Vo.
fa9e4066f08beec538e775443c5be79dd423fcabahrens*/
fa9e4066f08beec538e775443c5be79dd423fcabahrens#if __STD_C
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int _uexcept(Sfio_t* f, int type, Void_t* val, Sfdisc_t* disc)
fa9e4066f08beec538e775443c5be79dd423fcabahrens#else
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int _uexcept(f,type,val,disc)
fa9e4066f08beec538e775443c5be79dd423fcabahrensSfio_t *f;
fa9e4066f08beec538e775443c5be79dd423fcabahrensint type;
fa9e4066f08beec538e775443c5be79dd423fcabahrensVoid_t* val;
fa9e4066f08beec538e775443c5be79dd423fcabahrensSfdisc_t *disc;
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens NOTUSED(val);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* hmm! This should never happen */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if(disc != _Sfudisc)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return -1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* close the unget stream */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if(type != SF_CLOSING)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void)sfclose((*_Sfstack)(f,NIL(Sfio_t*)));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#if __STD_C
fa9e4066f08beec538e775443c5be79dd423fcabahrensint sfungetc(Sfio_t* f, int c)
fa9e4066f08beec538e775443c5be79dd423fcabahrens#else
fa9e4066f08beec538e775443c5be79dd423fcabahrensint sfungetc(f,c)
fa9e4066f08beec538e775443c5be79dd423fcabahrensSfio_t* f; /* push back one byte to this stream */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint c; /* the value to be pushed back */
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens reg Sfio_t* uf;
fa9e4066f08beec538e775443c5be79dd423fcabahrens SFMTXDECL(f);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens SFMTXENTER(f, -1)
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if(c < 0 || (f->mode != SF_READ && _sfmode(f,SF_READ,0) < 0))
fa9e4066f08beec538e775443c5be79dd423fcabahrens SFMTXRETURN(f, -1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens SFLOCK(f,0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* fast handling of the typical unget */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if(f->next > f->data && f->next[-1] == (uchar)c)
fa9e4066f08beec538e775443c5be79dd423fcabahrens { f->next -= 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto done;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* make a string stream for unget characters */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if(f->disc != _Sfudisc)
fa9e4066f08beec538e775443c5be79dd423fcabahrens { if(!(uf = sfnew(NIL(Sfio_t*),NIL(char*),(size_t)SF_UNBOUND,
fa9e4066f08beec538e775443c5be79dd423fcabahrens -1,SF_STRING|SF_READ)))
fa9e4066f08beec538e775443c5be79dd423fcabahrens { c = -1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto done;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens _Sfudisc->exceptf = _uexcept;
fa9e4066f08beec538e775443c5be79dd423fcabahrens sfdisc(uf,_Sfudisc);
fa9e4066f08beec538e775443c5be79dd423fcabahrens SFOPEN(f,0); (void)sfstack(f,uf); SFLOCK(f,0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* space for data */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if(f->next == f->data)
fa9e4066f08beec538e775443c5be79dd423fcabahrens { reg uchar* data;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if(f->size < 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens f->size = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if(!(data = (uchar*)malloc(f->size+16)))
fa9e4066f08beec538e775443c5be79dd423fcabahrens { c = -1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto done;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens f->flags |= SF_MALLOC;
fa9e4066f08beec538e775443c5be79dd423fcabahrens if(f->data)
fa9e4066f08beec538e775443c5be79dd423fcabahrens memcpy((char*)(data+16),(char*)f->data,f->size);
fa9e4066f08beec538e775443c5be79dd423fcabahrens f->size += 16;
fa9e4066f08beec538e775443c5be79dd423fcabahrens f->data = data;
fa9e4066f08beec538e775443c5be79dd423fcabahrens f->next = data+16;
fa9e4066f08beec538e775443c5be79dd423fcabahrens f->endb = data+f->size;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens *--f->next = (uchar)c;
fa9e4066f08beec538e775443c5be79dd423fcabahrensdone:
fa9e4066f08beec538e775443c5be79dd423fcabahrens SFOPEN(f,0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens SFMTXRETURN(f, c);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens