xref: /onnv-gate/usr/src/lib/libast/common/disc/sfdcprefix.c (revision 4887:feebf9260c2e)
1*4887Schin /***********************************************************************
2*4887Schin *                                                                      *
3*4887Schin *               This software is part of the ast package               *
4*4887Schin *           Copyright (c) 1985-2007 AT&T Knowledge Ventures            *
5*4887Schin *                      and is licensed under the                       *
6*4887Schin *                  Common Public License, Version 1.0                  *
7*4887Schin *                      by AT&T Knowledge Ventures                      *
8*4887Schin *                                                                      *
9*4887Schin *                A copy of the License is available at                 *
10*4887Schin *            http://www.opensource.org/licenses/cpl1.0.txt             *
11*4887Schin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12*4887Schin *                                                                      *
13*4887Schin *              Information and Software Systems Research               *
14*4887Schin *                            AT&T Research                             *
15*4887Schin *                           Florham Park NJ                            *
16*4887Schin *                                                                      *
17*4887Schin *                 Glenn Fowler <gsf@research.att.com>                  *
18*4887Schin *                  David Korn <dgk@research.att.com>                   *
19*4887Schin *                   Phong Vo <kpv@research.att.com>                    *
20*4887Schin *                                                                      *
21*4887Schin ***********************************************************************/
22*4887Schin #include "sfdchdr.h"
23*4887Schin 
24*4887Schin /*
25*4887Schin  * a discipline that prepends a prefix string to each output line
26*4887Schin  *
27*4887Schin  * Glenn Fowler
28*4887Schin  * AT&T Research
29*4887Schin  *
30*4887Schin  * @(#)$Id: sfdcprefix (AT&T Research) 1998-06-25 $
31*4887Schin  */
32*4887Schin 
33*4887Schin typedef struct
34*4887Schin {
35*4887Schin 	Sfdisc_t	disc;		/* sfio discipline		*/
36*4887Schin 	size_t		length;		/* prefix length		*/
37*4887Schin 	size_t		empty;		/* empty line prefix length	*/
38*4887Schin 	int		skip;		/* this line already prefixed	*/
39*4887Schin 	char		prefix[1];	/* prefix string		*/
40*4887Schin } Prefix_t;
41*4887Schin 
42*4887Schin /*
43*4887Schin  * prefix write
44*4887Schin  */
45*4887Schin 
46*4887Schin #if __STD_C
47*4887Schin static ssize_t pfxwrite(Sfio_t* f, const Void_t* buf, register size_t n, Sfdisc_t* dp)
48*4887Schin #else
49*4887Schin static ssize_t pfxwrite(f, buf, n, dp)
50*4887Schin Sfio_t* 	f;
51*4887Schin Void_t*		buf;
52*4887Schin register size_t	n;
53*4887Schin Sfdisc_t*	dp;
54*4887Schin #endif
55*4887Schin {
56*4887Schin 	register Prefix_t*	pfx = (Prefix_t*)dp;
57*4887Schin 	register char*		b;
58*4887Schin 	register char*		s;
59*4887Schin 	register char*		e;
60*4887Schin 	register char*		t;
61*4887Schin 	register ssize_t	w;
62*4887Schin 	int			skip;
63*4887Schin 
64*4887Schin 	skip = 0;
65*4887Schin 	w = 0;
66*4887Schin 	b = (char*)buf;
67*4887Schin 	s = b;
68*4887Schin 	e = s + n;
69*4887Schin 	do
70*4887Schin 	{
71*4887Schin 		if (!(t = memchr(s, '\n', e - s)))
72*4887Schin 		{
73*4887Schin 			skip = 1;
74*4887Schin 			t = e - 1;
75*4887Schin 		}
76*4887Schin 		n = t - s + 1;
77*4887Schin 		if (pfx->skip)
78*4887Schin 			pfx->skip = 0;
79*4887Schin 		else
80*4887Schin 			sfwr(f, pfx->prefix, n > 1 ? pfx->length : pfx->empty, dp);
81*4887Schin 		w += sfwr(f, s, n, dp);
82*4887Schin 		if ((s = t + 1) >= e)
83*4887Schin 			return w;
84*4887Schin 	} while ((s = t + 1) < e);
85*4887Schin 	pfx->skip = skip;
86*4887Schin 	return w;
87*4887Schin 
88*4887Schin }
89*4887Schin 
90*4887Schin /*
91*4887Schin  * remove the discipline on close
92*4887Schin  */
93*4887Schin 
94*4887Schin #if __STD_C
95*4887Schin static int pfxexcept(Sfio_t* f, int type, Void_t* data, Sfdisc_t* dp)
96*4887Schin #else
97*4887Schin static int pfxexcept(f, type, data, dp)
98*4887Schin Sfio_t*		f;
99*4887Schin int		type;
100*4887Schin Void_t*		data;
101*4887Schin Sfdisc_t*	dp;
102*4887Schin #endif
103*4887Schin {
104*4887Schin 	if (type == SF_FINAL || type == SF_DPOP)
105*4887Schin 		free(dp);
106*4887Schin 	return 0;
107*4887Schin }
108*4887Schin 
109*4887Schin /*
110*4887Schin  * push the prefix discipline on f
111*4887Schin  */
112*4887Schin 
113*4887Schin #if __STD_C
114*4887Schin int sfdcprefix(Sfio_t* f, const char* prefix)
115*4887Schin #else
116*4887Schin int sfdcprefix(f, prefix)
117*4887Schin Sfio_t*		f;
118*4887Schin char*		prefix;
119*4887Schin #endif
120*4887Schin {
121*4887Schin 	register Prefix_t*	pfx;
122*4887Schin 	register char*		s;
123*4887Schin 	size_t			n;
124*4887Schin 
125*4887Schin 	/*
126*4887Schin 	 * this is a writeonly discipline
127*4887Schin 	 */
128*4887Schin 
129*4887Schin 	if (!prefix || !(n = strlen(prefix)) || !(sfset(f, 0, 0) & SF_WRITE))
130*4887Schin 		return -1;
131*4887Schin 	if (!(pfx = (Prefix_t*)malloc(sizeof(Prefix_t) + n)))
132*4887Schin 		return -1;
133*4887Schin 	memset(pfx, 0, sizeof(*pfx));
134*4887Schin 
135*4887Schin 	pfx->disc.writef = pfxwrite;
136*4887Schin 	pfx->disc.exceptf = pfxexcept;
137*4887Schin 	pfx->length = n;
138*4887Schin 	memcpy(pfx->prefix, prefix, n);
139*4887Schin 	s = (char*)prefix + n;
140*4887Schin 	while (--s > (char*)prefix && (*s == ' ' || *s == '\t'));
141*4887Schin 	n = s - (char*)prefix;
142*4887Schin 	if (*s != ' ' || *s != '\t')
143*4887Schin 		n++;
144*4887Schin 	pfx->empty = n;
145*4887Schin 
146*4887Schin 	if (sfdisc(f, &pfx->disc) != &pfx->disc)
147*4887Schin 	{
148*4887Schin 		free(pfx);
149*4887Schin 		return -1;
150*4887Schin 	}
151*4887Schin 
152*4887Schin 	return 0;
153*4887Schin }
154