14887Schin /***********************************************************************
24887Schin * *
34887Schin * This software is part of the ast package *
4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1985-2010 AT&T Intellectual Property *
54887Schin * and is licensed under the *
64887Schin * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
84887Schin * *
94887Schin * A copy of the License is available at *
104887Schin * http://www.opensource.org/licenses/cpl1.0.txt *
114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
124887Schin * *
134887Schin * Information and Software Systems Research *
144887Schin * AT&T Research *
154887Schin * Florham Park NJ *
164887Schin * *
174887Schin * Glenn Fowler <gsf@research.att.com> *
184887Schin * David Korn <dgk@research.att.com> *
194887Schin * Phong Vo <kpv@research.att.com> *
204887Schin * *
214887Schin ***********************************************************************/
224887Schin #include "sfhdr.h"
234887Schin
244887Schin /* Put out a null-terminated string
254887Schin **
264887Schin ** Written by Kiem-Phong Vo.
274887Schin */
284887Schin #if __STD_C
sfputr(Sfio_t * f,const char * s,int rc)298462SApril.Chin@Sun.COM ssize_t sfputr(Sfio_t* f, const char* s, int rc)
304887Schin #else
314887Schin ssize_t sfputr(f,s,rc)
328462SApril.Chin@Sun.COM Sfio_t* f; /* write to this stream */
334887Schin char* s; /* string to write */
348462SApril.Chin@Sun.COM int rc; /* record separator. */
354887Schin #endif
364887Schin {
374887Schin reg ssize_t p, n, w;
384887Schin reg uchar* ps;
398462SApril.Chin@Sun.COM SFMTXDECL(f);
404887Schin
418462SApril.Chin@Sun.COM SFMTXENTER(f,-1);
424887Schin
434887Schin if(f->mode != SF_WRITE && _sfmode(f,SF_WRITE,0) < 0)
444887Schin SFMTXRETURN(f, -1);
454887Schin
464887Schin SFLOCK(f,0);
474887Schin
484887Schin for(w = 0; (*s || rc >= 0); )
4910898Sroland.mainz@nrubsig.org { if(SFWPEEK(f,ps,p) < 0)
5010898Sroland.mainz@nrubsig.org break;
514887Schin
524887Schin if(p == 0 || (f->flags&SF_WHOLE) )
534887Schin { n = strlen(s);
544887Schin if(p >= (n + (rc < 0 ? 0 : 1)) )
554887Schin { /* buffer can hold everything */
564887Schin if(n > 0)
574887Schin { memcpy(ps, s, n);
584887Schin ps += n;
594887Schin w += n;
604887Schin }
614887Schin if(rc >= 0)
624887Schin { *ps++ = rc;
634887Schin w += 1;
644887Schin }
654887Schin f->next = ps;
664887Schin }
674887Schin else
684887Schin { /* create a reserve buffer to hold data */
694887Schin Sfrsrv_t* rsrv;
704887Schin
714887Schin p = n + (rc >= 0 ? 1 : 0);
724887Schin if(!(rsrv = _sfrsrv(f, p)) )
734887Schin n = 0;
744887Schin else
754887Schin { if(n > 0)
764887Schin memcpy(rsrv->data, s, n);
774887Schin if(rc >= 0)
784887Schin rsrv->data[n] = rc;
794887Schin if((n = SFWRITE(f,rsrv->data,p)) < 0 )
804887Schin n = 0;
814887Schin }
824887Schin
834887Schin w += n;
844887Schin }
854887Schin break;
864887Schin }
874887Schin
884887Schin if(*s == 0)
894887Schin { *ps++ = rc;
904887Schin f->next = ps;
914887Schin w += 1;
924887Schin break;
934887Schin }
944887Schin
954887Schin #if _lib_memccpy && !__ia64 /* these guys may never get it right */
964887Schin if((ps = (uchar*)memccpy(ps,s,'\0',p)) != NIL(uchar*))
974887Schin ps -= 1;
984887Schin else ps = f->next+p;
994887Schin s += ps - f->next;
1004887Schin #else
1014887Schin for(; p > 0; --p, ++ps, ++s)
1024887Schin if((*ps = *s) == 0)
1034887Schin break;
1044887Schin #endif
1054887Schin w += ps - f->next;
1064887Schin f->next = ps;
1074887Schin }
1084887Schin
1094887Schin /* sync unseekable shared streams */
1104887Schin if(f->extent < 0 && (f->flags&SF_SHARE) )
1114887Schin (void)SFFLSBUF(f,-1);
1124887Schin
1134887Schin /* check for line buffering */
1144887Schin else if((f->flags&SF_LINE) && !(f->flags&SF_STRING) && (n = f->next-f->data) > 0)
1154887Schin { if(n > w)
1164887Schin n = w;
1174887Schin f->next -= n;
1184887Schin (void)SFWRITE(f,(Void_t*)f->next,n);
1194887Schin }
1204887Schin
1214887Schin SFOPEN(f,0);
1224887Schin SFMTXRETURN(f, w);
1234887Schin }
124