da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1985-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Phong Vo <kpv@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "sfhdr.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* Put out a null-terminated string
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin**
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin** Written by Kiem-Phong Vo.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if __STD_C
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinssize_t sfputr(Sfio_t* f, const char* s, int rc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinssize_t sfputr(f,s,rc)
7c2fbfb345896881c631598ee3852ce9ce33fb07April ChinSfio_t* f; /* write to this stream */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchar* s; /* string to write */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinint rc; /* record separator. */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reg ssize_t p, n, w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reg uchar* ps;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin SFMTXDECL(f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin SFMTXENTER(f,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(f->mode != SF_WRITE && _sfmode(f,SF_WRITE,0) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SFMTXRETURN(f, -1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SFLOCK(f,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(w = 0; (*s || rc >= 0); )
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz { if(SFWPEEK(f,ps,p) < 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(p == 0 || (f->flags&SF_WHOLE) )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { n = strlen(s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(p >= (n + (rc < 0 ? 0 : 1)) )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { /* buffer can hold everything */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { memcpy(ps, s, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ps += n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin w += n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(rc >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { *ps++ = rc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin w += 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->next = ps;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { /* create a reserve buffer to hold data */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfrsrv_t* rsrv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p = n + (rc >= 0 ? 1 : 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(rsrv = _sfrsrv(f, p)) )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { if(n > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(rsrv->data, s, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(rc >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rsrv->data[n] = rc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((n = SFWRITE(f,rsrv->data,p)) < 0 )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin w += n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*s == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { *ps++ = rc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->next = ps;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin w += 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _lib_memccpy && !__ia64 /* these guys may never get it right */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((ps = (uchar*)memccpy(ps,s,'\0',p)) != NIL(uchar*))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ps -= 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else ps = f->next+p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s += ps - f->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(; p > 0; --p, ++ps, ++s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((*ps = *s) == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin w += ps - f->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->next = ps;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* sync unseekable shared streams */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(f->extent < 0 && (f->flags&SF_SHARE) )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (void)SFFLSBUF(f,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for line buffering */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if((f->flags&SF_LINE) && !(f->flags&SF_STRING) && (n = f->next-f->data) > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { if(n > w)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->next -= n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (void)SFWRITE(f,(Void_t*)f->next,n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SFOPEN(f,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SFMTXRETURN(f, w);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}