xref: /onnv-gate/usr/src/lib/libast/common/disc/sfdcprefix.c (revision 12068:08a39a083754)
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 "sfdchdr.h"
234887Schin 
244887Schin /*
254887Schin  * a discipline that prepends a prefix string to each output line
264887Schin  *
274887Schin  * Glenn Fowler
284887Schin  * AT&T Research
294887Schin  *
304887Schin  * @(#)$Id: sfdcprefix (AT&T Research) 1998-06-25 $
314887Schin  */
324887Schin 
334887Schin typedef struct
344887Schin {
354887Schin 	Sfdisc_t	disc;		/* sfio discipline		*/
364887Schin 	size_t		length;		/* prefix length		*/
374887Schin 	size_t		empty;		/* empty line prefix length	*/
384887Schin 	int		skip;		/* this line already prefixed	*/
394887Schin 	char		prefix[1];	/* prefix string		*/
404887Schin } Prefix_t;
414887Schin 
424887Schin /*
434887Schin  * prefix write
444887Schin  */
454887Schin 
464887Schin #if __STD_C
pfxwrite(Sfio_t * f,const Void_t * buf,register size_t n,Sfdisc_t * dp)474887Schin static ssize_t pfxwrite(Sfio_t* f, const Void_t* buf, register size_t n, Sfdisc_t* dp)
484887Schin #else
494887Schin static ssize_t pfxwrite(f, buf, n, dp)
504887Schin Sfio_t* 	f;
514887Schin Void_t*		buf;
524887Schin register size_t	n;
534887Schin Sfdisc_t*	dp;
544887Schin #endif
554887Schin {
564887Schin 	register Prefix_t*	pfx = (Prefix_t*)dp;
574887Schin 	register char*		b;
584887Schin 	register char*		s;
594887Schin 	register char*		e;
604887Schin 	register char*		t;
614887Schin 	register ssize_t	w;
624887Schin 	int			skip;
634887Schin 
644887Schin 	skip = 0;
654887Schin 	w = 0;
664887Schin 	b = (char*)buf;
674887Schin 	s = b;
684887Schin 	e = s + n;
694887Schin 	do
704887Schin 	{
714887Schin 		if (!(t = memchr(s, '\n', e - s)))
724887Schin 		{
734887Schin 			skip = 1;
744887Schin 			t = e - 1;
754887Schin 		}
764887Schin 		n = t - s + 1;
774887Schin 		if (pfx->skip)
784887Schin 			pfx->skip = 0;
794887Schin 		else
804887Schin 			sfwr(f, pfx->prefix, n > 1 ? pfx->length : pfx->empty, dp);
814887Schin 		w += sfwr(f, s, n, dp);
824887Schin 		if ((s = t + 1) >= e)
834887Schin 			return w;
844887Schin 	} while ((s = t + 1) < e);
854887Schin 	pfx->skip = skip;
864887Schin 	return w;
874887Schin 
884887Schin }
894887Schin 
904887Schin /*
914887Schin  * remove the discipline on close
924887Schin  */
934887Schin 
944887Schin #if __STD_C
pfxexcept(Sfio_t * f,int type,Void_t * data,Sfdisc_t * dp)954887Schin static int pfxexcept(Sfio_t* f, int type, Void_t* data, Sfdisc_t* dp)
964887Schin #else
974887Schin static int pfxexcept(f, type, data, dp)
984887Schin Sfio_t*		f;
994887Schin int		type;
1004887Schin Void_t*		data;
1014887Schin Sfdisc_t*	dp;
1024887Schin #endif
1034887Schin {
1044887Schin 	if (type == SF_FINAL || type == SF_DPOP)
1054887Schin 		free(dp);
1064887Schin 	return 0;
1074887Schin }
1084887Schin 
1094887Schin /*
1104887Schin  * push the prefix discipline on f
1114887Schin  */
1124887Schin 
1134887Schin #if __STD_C
sfdcprefix(Sfio_t * f,const char * prefix)1144887Schin int sfdcprefix(Sfio_t* f, const char* prefix)
1154887Schin #else
1164887Schin int sfdcprefix(f, prefix)
1174887Schin Sfio_t*		f;
1184887Schin char*		prefix;
1194887Schin #endif
1204887Schin {
1214887Schin 	register Prefix_t*	pfx;
1224887Schin 	register char*		s;
1234887Schin 	size_t			n;
1244887Schin 
1254887Schin 	/*
1264887Schin 	 * this is a writeonly discipline
1274887Schin 	 */
1284887Schin 
1294887Schin 	if (!prefix || !(n = strlen(prefix)) || !(sfset(f, 0, 0) & SF_WRITE))
1304887Schin 		return -1;
1314887Schin 	if (!(pfx = (Prefix_t*)malloc(sizeof(Prefix_t) + n)))
1324887Schin 		return -1;
1334887Schin 	memset(pfx, 0, sizeof(*pfx));
1344887Schin 
1354887Schin 	pfx->disc.writef = pfxwrite;
1364887Schin 	pfx->disc.exceptf = pfxexcept;
1374887Schin 	pfx->length = n;
1384887Schin 	memcpy(pfx->prefix, prefix, n);
1394887Schin 	s = (char*)prefix + n;
1404887Schin 	while (--s > (char*)prefix && (*s == ' ' || *s == '\t'));
1414887Schin 	n = s - (char*)prefix;
1424887Schin 	if (*s != ' ' || *s != '\t')
1434887Schin 		n++;
1444887Schin 	pfx->empty = n;
1454887Schin 
1464887Schin 	if (sfdisc(f, &pfx->disc) != &pfx->disc)
1474887Schin 	{
1484887Schin 		free(pfx);
1494887Schin 		return -1;
1504887Schin 	}
1514887Schin 
1524887Schin 	return 0;
1534887Schin }
154