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 <ast.h> 23#include <stdarg.h> 24 25#define STR (8*1024) 26 27#define VALID(p,f) ((p=(Sfstr_t*)f)>=&strs[0]&&p<&strs[elementsof(strs)]) 28 29static Sfstr_t strs[64]; 30 31static int 32extend(Sfstr_t* p, int n) 33{ 34 int o; 35 36 if (n < STR) 37 n = STR; 38 n += p->end - p->beg; 39 o = p->nxt - p->beg; 40 if (!(p->beg = realloc(p->beg, n))) 41 return -1; 42 p->nxt = p->beg + o; 43 p->end = p->beg + n; 44 return 0; 45} 46 47int 48sfclose(Sfio_t* f) 49{ 50 Sfstr_t* p; 51 int r; 52 53 if (VALID(p, f)) 54 { 55 p->nxt = 0; 56 r = 0; 57 } 58 else 59 r = fclose(f); 60 return r; 61} 62 63int 64sfprintf(Sfio_t* f, const char* fmt, ...) 65{ 66 Sfstr_t* p; 67 char* s; 68 va_list ap; 69 int r; 70 71 static char buf[STR]; 72 73 va_start(ap, fmt); 74 if (!VALID(p, f)) 75 r = vfprintf(f, fmt, ap); 76 else if ((r = vsnprintf(buf, sizeof(buf), fmt, ap)) > 0) 77 r = sfwrite(f, buf, r); 78 va_end(ap); 79 return r; 80} 81 82char* 83sfprints(const char* fmt, ...) 84{ 85 va_list ap; 86 int r; 87 88 static char buf[STR]; 89 90 va_start(ap, fmt); 91 r = vsnprintf(buf, sizeof(buf), fmt, ap); 92 va_end(ap); 93 return r > 0 ? buf : (char*)0; 94} 95 96int 97sfputc(Sfio_t* f, int c) 98{ 99 Sfstr_t* p; 100 int r; 101 102 if (VALID(p, f)) 103 { 104 if (p->nxt >= p->end && extend(p, 1)) 105 return -1; 106 *p->nxt++ = c; 107 r = 1; 108 } 109 else 110 r = fputc(c, f); 111 return r; 112} 113 114int 115sfputr(Sfio_t* f, const char* buf, int sep) 116{ 117 Sfstr_t* p; 118 int r; 119 int n; 120 121 n = strlen(buf); 122 if (VALID(p, f)) 123 { 124 r = n + (sep >= 0); 125 if (r > (p->end - p->nxt) && extend(p, r)) 126 return -1; 127 memcpy(p->nxt, buf, n); 128 p->nxt += n; 129 if (sep >= 0) 130 *p->nxt++ = sep; 131 } 132 else 133 { 134 r = fwrite(buf, 1, n, f); 135 if (sep >= 0 && fputc(sep, f) != EOF) 136 r++; 137 } 138 return r; 139} 140 141char* 142sfstrbase(Sfio_t* f) 143{ 144 Sfstr_t* p; 145 146 if (VALID(p, f)) 147 return p->beg; 148 return 0; 149} 150 151Sfio_t* 152sfstropen(void) 153{ 154 Sfstr_t* p; 155 156 for (p = &strs[0]; p < &strs[elementsof(strs)]; p++) 157 if (!p->nxt) 158 { 159 if (!p->beg) 160 { 161 if (!(p->beg = malloc(STR))) 162 break; 163 p->end = p->beg + STR; 164 } 165 p->nxt = p->beg; 166 return (Sfio_t*)p; 167 } 168 return 0; 169} 170 171#define _sf_strseek(f,p,m) \ 172 ( (m) == SEEK_SET ? \ 173 (((p) < 0 || (p) > ((f)->end - (f)->beg)) ? (char*)0 : \ 174 (char*)((f)->nxt = (f)->beg+(p)) ) \ 175 : (m) == SEEK_CUR ? \ 176 ((f)->nxt += (p), \ 177 (((f)->nxt < (f)->beg || (f)->nxt > (f)->end) ? \ 178 ((f)->nxt -= (p), (char*)0) : (char*)(f)->nxt ) ) \ 179 : (m) == SEEK_END ? \ 180 ( ((p) > 0 || (((f)->end - (f)->beg) + (p)) < 0) ? (char*)0 : \ 181 (char*)((f)->nxt = (f)->end+(p)) ) \ 182 : (char*)0 \ 183 ) 184 185char* 186sfstrseek(Sfio_t* f, int n, int w) 187{ 188 Sfstr_t* p; 189 190 if (VALID(p, f)) 191 return _sf_strseek(p, n, w); 192 return 0; 193} 194 195char* 196sfstrset(Sfio_t* f, int n) 197{ 198 Sfstr_t* p; 199 200 if (VALID(p, f) && n >= 0 && n < (p->nxt - p->beg)) 201 return p->nxt = p->beg + n; 202 return 0; 203} 204 205int 206sfstrtell(Sfio_t* f) 207{ 208 Sfstr_t* p; 209 int r; 210 211 if (VALID(p, f) && p->nxt) 212 r = p->nxt - p->beg; 213 else 214 r = -1; 215 return r; 216} 217 218char* 219sfstruse(Sfio_t* f) 220{ 221 Sfstr_t* p; 222 223 if (VALID(p, f) && (p->nxt < p->end || !extend(p, 1))) 224 { 225 *p->nxt = 0; 226 return p->nxt = p->beg; 227 } 228 return 0; 229} 230 231int 232sfwrite(Sfio_t* f, void* buf, int n) 233{ 234 Sfstr_t* p; 235 236 if (VALID(p, f)) 237 { 238 if (n > (p->end - p->nxt) && extend(p, n)) 239 return -1; 240 memcpy(p->nxt, buf, n); 241 p->nxt += n; 242 } 243 else 244 n = fwrite(buf, 1, n, f); 245 return n; 246} 247