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