1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1985-2008 AT&T Intellectual Property * 5 * and is licensed under the * 6 * Common Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.opensource.org/licenses/cpl1.0.txt * 11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 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 33 typedef 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 47 static ssize_t pfxwrite(Sfio_t* f, const Void_t* buf, register size_t n, Sfdisc_t* dp) 48 #else 49 static ssize_t pfxwrite(f, buf, n, dp) 50 Sfio_t* f; 51 Void_t* buf; 52 register size_t n; 53 Sfdisc_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 95 static int pfxexcept(Sfio_t* f, int type, Void_t* data, Sfdisc_t* dp) 96 #else 97 static int pfxexcept(f, type, data, dp) 98 Sfio_t* f; 99 int type; 100 Void_t* data; 101 Sfdisc_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 114 int sfdcprefix(Sfio_t* f, const char* prefix) 115 #else 116 int sfdcprefix(f, prefix) 117 Sfio_t* f; 118 char* 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