14887Schin /*********************************************************************** 24887Schin * * 34887Schin * This software is part of the ast package * 4*10898Sroland.mainz@nrubsig.org * Copyright (c) 1985-2009 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 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); ) 49*10898Sroland.mainz@nrubsig.org { if(SFWPEEK(f,ps,p) < 0) 50*10898Sroland.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