diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2012-06-24 22:28:35 +0000 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2012-06-24 22:28:35 +0000 |
commit | 3950ffe2a485479f6561c27364d3d7df5a21d124 (patch) | |
tree | 468c6e14449d1b1e279222ec32f676b0311917d2 /src/lib/libast/astsa/sfstr.c | |
download | ksh-upstream.tar.gz |
Imported Upstream version 93u+upstream
Diffstat (limited to 'src/lib/libast/astsa/sfstr.c')
-rw-r--r-- | src/lib/libast/astsa/sfstr.c | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/src/lib/libast/astsa/sfstr.c b/src/lib/libast/astsa/sfstr.c new file mode 100644 index 0000000..7fc0be3 --- /dev/null +++ b/src/lib/libast/astsa/sfstr.c @@ -0,0 +1,246 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1985-2011 AT&T Intellectual Property * +* and is licensed under the * +* Eclipse Public License, Version 1.0 * +* by AT&T Intellectual Property * +* * +* A copy of the License is available at * +* http://www.eclipse.org/org/documents/epl-v10.html * +* (with md5 checksum b35adb5213ca9657e911e9befb180842) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* Glenn Fowler <gsf@research.att.com> * +* David Korn <dgk@research.att.com> * +* Phong Vo <kpv@research.att.com> * +* * +***********************************************************************/ +#include <ast.h> +#include <stdarg.h> + +#define STR (8*1024) + +#define VALID(p,f) ((p=(Sfstr_t*)f)>=&strs[0]&&p<&strs[elementsof(strs)]) + +static Sfstr_t strs[64]; + +static int +extend(Sfstr_t* p, int n) +{ + int o; + + if (n < STR) + n = STR; + n += p->end - p->beg; + o = p->nxt - p->beg; + if (!(p->beg = realloc(p->beg, n))) + return -1; + p->nxt = p->beg + o; + p->end = p->beg + n; + return 0; +} + +int +sfclose(Sfio_t* f) +{ + Sfstr_t* p; + int r; + + if (VALID(p, f)) + { + p->nxt = 0; + r = 0; + } + else + r = fclose(f); + return r; +} + +int +sfprintf(Sfio_t* f, const char* fmt, ...) +{ + Sfstr_t* p; + char* s; + va_list ap; + int r; + + static char buf[STR]; + + va_start(ap, fmt); + if (!VALID(p, f)) + r = vfprintf(f, fmt, ap); + else if ((r = vsnprintf(buf, sizeof(buf), fmt, ap)) > 0) + r = sfwrite(f, buf, r); + va_end(ap); + return r; +} + +char* +sfprints(const char* fmt, ...) +{ + va_list ap; + int r; + + static char buf[STR]; + + va_start(ap, fmt); + r = vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + return r > 0 ? buf : (char*)0; +} + +int +sfputc(Sfio_t* f, int c) +{ + Sfstr_t* p; + int r; + + if (VALID(p, f)) + { + if (p->nxt >= p->end && extend(p, 1)) + return -1; + *p->nxt++ = c; + r = 1; + } + else + r = fputc(c, f); + return r; +} + +int +sfputr(Sfio_t* f, const char* buf, int sep) +{ + Sfstr_t* p; + int r; + int n; + + n = strlen(buf); + if (VALID(p, f)) + { + r = n + (sep >= 0); + if (r > (p->end - p->nxt) && extend(p, r)) + return -1; + memcpy(p->nxt, buf, n); + p->nxt += n; + if (sep >= 0) + *p->nxt++ = sep; + } + else + { + r = fwrite(buf, 1, n, f); + if (sep >= 0 && fputc(sep, f) != EOF) + r++; + } + return r; +} + +char* +sfstrbase(Sfio_t* f) +{ + Sfstr_t* p; + + if (VALID(p, f)) + return p->beg; + return 0; +} + +Sfio_t* +sfstropen(void) +{ + Sfstr_t* p; + + for (p = &strs[0]; p < &strs[elementsof(strs)]; p++) + if (!p->nxt) + { + if (!p->beg) + { + if (!(p->beg = malloc(STR))) + break; + p->end = p->beg + STR; + } + p->nxt = p->beg; + return (Sfio_t*)p; + } + return 0; +} + +#define _sf_strseek(f,p,m) \ + ( (m) == SEEK_SET ? \ + (((p) < 0 || (p) > ((f)->end - (f)->beg)) ? (char*)0 : \ + (char*)((f)->nxt = (f)->beg+(p)) ) \ + : (m) == SEEK_CUR ? \ + ((f)->nxt += (p), \ + (((f)->nxt < (f)->beg || (f)->nxt > (f)->end) ? \ + ((f)->nxt -= (p), (char*)0) : (char*)(f)->nxt ) ) \ + : (m) == SEEK_END ? \ + ( ((p) > 0 || (((f)->end - (f)->beg) + (p)) < 0) ? (char*)0 : \ + (char*)((f)->nxt = (f)->end+(p)) ) \ + : (char*)0 \ + ) + +char* +sfstrseek(Sfio_t* f, int n, int w) +{ + Sfstr_t* p; + + if (VALID(p, f)) + return _sf_strseek(p, n, w); + return 0; +} + +char* +sfstrset(Sfio_t* f, int n) +{ + Sfstr_t* p; + + if (VALID(p, f) && n >= 0 && n < (p->nxt - p->beg)) + return p->nxt = p->beg + n; + return 0; +} + +int +sfstrtell(Sfio_t* f) +{ + Sfstr_t* p; + int r; + + if (VALID(p, f) && p->nxt) + r = p->nxt - p->beg; + else + r = -1; + return r; +} + +char* +sfstruse(Sfio_t* f) +{ + Sfstr_t* p; + + if (VALID(p, f) && (p->nxt < p->end || !extend(p, 1))) + { + *p->nxt = 0; + return p->nxt = p->beg; + } + return 0; +} + +int +sfwrite(Sfio_t* f, void* buf, int n) +{ + Sfstr_t* p; + + if (VALID(p, f)) + { + if (n > (p->end - p->nxt) && extend(p, n)) + return -1; + memcpy(p->nxt, buf, n); + p->nxt += n; + } + else + n = fwrite(buf, 1, n, f); + return n; +} |