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
extend(Sfstr_t * p,int n)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
sfclose(Sfio_t * f)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
sfprintf(Sfio_t * f,const char * fmt,...)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*
sfprints(const char * fmt,...)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
sfputc(Sfio_t * f,int c)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
sfputr(Sfio_t * f,const char * buf,int sep)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*
sfstrbase(Sfio_t * f)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*
sfstropen(void)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*
sfstrseek(Sfio_t * f,int n,int w)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*
sfstrset(Sfio_t * f,int n)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
sfstrtell(Sfio_t * f)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*
sfstruse(Sfio_t * f)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
sfwrite(Sfio_t * f,void * buf,int n)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