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 29 static Sfstr_t strs[64]; 30 31 static int 32 extend(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 47 int 48 sfclose(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 63 int 64 sfprintf(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 82 char* 83 sfprints(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 96 int 97 sfputc(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 114 int 115 sfputr(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 141 char* 142 sfstrbase(Sfio_t* f) 143 { 144 Sfstr_t* p; 145 146 if (VALID(p, f)) 147 return p->beg; 148 return 0; 149 } 150 151 Sfio_t* 152 sfstropen(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 185 char* 186 sfstrseek(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 195 char* 196 sfstrset(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 205 int 206 sfstrtell(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 218 char* 219 sfstruse(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 231 int 232 sfwrite(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