14887Schin /*********************************************************************** 24887Schin * * 34887Schin * This software is part of the ast package * 4*8462SApril.Chin@Sun.COM * Copyright (c) 1985-2008 AT&T Intellectual Property * 54887Schin * and is licensed under the * 64887Schin * Common Public License, Version 1.0 * 7*8462SApril.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 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 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 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