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