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/disc | |
download | ksh-upstream.tar.gz |
Imported Upstream version 93u+upstream
Diffstat (limited to 'src/lib/libast/disc')
-rw-r--r-- | src/lib/libast/disc/memfatal.c | 82 | ||||
-rw-r--r-- | src/lib/libast/disc/sfdcdio.c | 229 | ||||
-rw-r--r-- | src/lib/libast/disc/sfdcdos.c | 416 | ||||
-rw-r--r-- | src/lib/libast/disc/sfdcfilter.c | 186 | ||||
-rw-r--r-- | src/lib/libast/disc/sfdchdr.h | 28 | ||||
-rw-r--r-- | src/lib/libast/disc/sfdcmore.c | 369 | ||||
-rw-r--r-- | src/lib/libast/disc/sfdcprefix.c | 153 | ||||
-rw-r--r-- | src/lib/libast/disc/sfdcseekable.c | 227 | ||||
-rw-r--r-- | src/lib/libast/disc/sfdcslow.c | 84 | ||||
-rw-r--r-- | src/lib/libast/disc/sfdcsubstr.c | 217 | ||||
-rw-r--r-- | src/lib/libast/disc/sfdctee.c | 102 | ||||
-rw-r--r-- | src/lib/libast/disc/sfdcunion.c | 203 | ||||
-rw-r--r-- | src/lib/libast/disc/sfkeyprintf.c | 392 | ||||
-rw-r--r-- | src/lib/libast/disc/sfstrtmp.c | 62 |
14 files changed, 2750 insertions, 0 deletions
diff --git a/src/lib/libast/disc/memfatal.c b/src/lib/libast/disc/memfatal.c new file mode 100644 index 0000000..9016d36 --- /dev/null +++ b/src/lib/libast/disc/memfatal.c @@ -0,0 +1,82 @@ +/*********************************************************************** +* * +* 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> * +* * +***********************************************************************/ +#pragma prototyped + +/* + * install error message handler for fatal malloc exceptions + */ + +#include <ast.h> +#include <error.h> +#include <vmalloc.h> + +#include "FEATURE/vmalloc" + +#if _std_malloc + +void +memfatal(void) +{ +} + +#else + +/* + * print message and fail on VM_BADADDR,VM_NOMEM + */ + +static int +nomalloc(Vmalloc_t* region, int type, void* obj, Vmdisc_t* disc) +{ + Vmstat_t st; + + NoP(disc); + switch (type) + { +#ifdef VM_BADADDR + case VM_BADADDR: + error(ERROR_SYSTEM|3, "invalid pointer %p passed to free or realloc", obj); + return(-1); +#endif + case VM_NOMEM: + vmstat(region, &st); + error(ERROR_SYSTEM|3, "storage allocator out of space on %lu byte request ( region %lu segments %lu busy %lu:%lu:%lu free %lu:%lu:%lu )", (size_t)obj, st.extent, st.n_seg, st.n_busy, st.s_busy, st.m_busy, st.n_free, st.s_free, st.m_free); + return(-1); + } + return(0); +} + +/* + * initialize the malloc exception handler + */ + +void +memfatal(void) +{ + Vmdisc_t* disc; + + malloc(0); + if (disc = vmdisc(Vmregion, NiL)) + disc->exceptf = nomalloc; +} + +#endif diff --git a/src/lib/libast/disc/sfdcdio.c b/src/lib/libast/disc/sfdcdio.c new file mode 100644 index 0000000..e8277f1 --- /dev/null +++ b/src/lib/libast/disc/sfdcdio.c @@ -0,0 +1,229 @@ +/*********************************************************************** +* * +* 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 "sfdchdr.h" + +/* Discipline to turn on direct IO capability. +** This currently only works for XFS on SGI's. +** +** Written by Kiem-Phong Vo, kpv@research.att.com, 03/18/1998. +*/ + +#ifndef FDIRECT +#undef F_FIOINFO +#endif + +typedef struct _direct_s +{ Sfdisc_t disc; /* Sfio discipline */ + int cntl; /* file control flags */ +#ifdef F_DIOINFO + struct dioattr dio; /* direct IO params */ +#endif +} Direct_t; + +/* convert a pointer to an int */ +#define P2I(p) (Sfulong_t)((char*)(p) - (char*)0) + +#if __STD_C +static ssize_t diordwr(Sfio_t* f, Void_t* buf, size_t n, Direct_t* di, int type) +#else +static ssize_t diordwr(f, buf, n, di, type) +Sfio_t* f; +Void_t* buf; +size_t n; +Direct_t* di; +int type; +#endif +{ + size_t rw, done; + ssize_t rv; + + done = 0; /* amount processed by direct IO */ + rv = 0; + +#ifdef F_DIOINFO + if((P2I(buf)%di->dio.d_mem) == 0 && + (f->here%di->dio.d_miniosz) == 0 && n >= di->dio.d_miniosz ) + { /* direct IO ok, make sure we're in the right mode */ + if(!(di->cntl & FDIRECT) ) + { di->cntl |= FDIRECT; + (void)fcntl(f->file, F_SETFL, di->cntl); + } + + for(rw = (n/di->dio.d_miniosz)*di->dio.d_miniosz;; ) + { size_t io; + + if((io = rw) > di->dio.d_maxiosz ) + io = di->dio.d_maxiosz; + if(type == SF_READ) + rv = read(f->file,buf,io); + else rv = write(f->file,buf,io); + + if(rv > 0) + { rw -= rv; done += rv; + buf = (Void_t*)((char*)buf + rv); + } + + if(rv < io || rw < di->dio.d_miniosz) + break; + } + } + + if(done < n && (di->cntl & FDIRECT) ) + { /* turn off directIO for remaining IO operation */ + di->cntl &= ~FDIRECT; + (void)fcntl(f->file, F_SETFL, di->cntl); + } +#endif /*F_DIOINFO*/ + + if((rw = n-done) > 0 && + (rv = type == SF_READ ? read(f->file,buf,rw) : write(f->file,buf,rw)) > 0 ) + done += rv; + + return done ? done : rv; +} + +#if __STD_C +static ssize_t dioread(Sfio_t* f, Void_t* buf, size_t n, Sfdisc_t* disc) +#else +static ssize_t dioread(f, buf, n, disc) +Sfio_t* f; +Void_t* buf; +size_t n; +Sfdisc_t* disc; +#endif +{ + return diordwr(f, buf, n, (Direct_t*)disc, SF_READ); +} + +#if __STD_C +static ssize_t diowrite(Sfio_t* f, const Void_t* buf, size_t n, Sfdisc_t* disc) +#else +static ssize_t diowrite(f, buf, n, disc) +Sfio_t* f; +Void_t* buf; +size_t n; +Sfdisc_t* disc; +#endif +{ + return diordwr(f, (Void_t*)buf, n, (Direct_t*)disc, SF_WRITE); +} + +#if __STD_C +static int dioexcept(Sfio_t* f, int type, Void_t* data, Sfdisc_t* disc) +#else +static int dioexcept(f,type,data,disc) +Sfio_t* f; +int type; +Void_t* data; +Sfdisc_t* disc; +#endif +{ + Direct_t* di = (Direct_t*)disc; + + if(type == SF_FINAL || type == SF_DPOP) + { +#ifdef F_DIOINFO + if(di->cntl&FDIRECT) + { di->cntl &= ~FDIRECT; + (void)fcntl(f->file,F_SETFL,di->cntl); + } +#endif + free(disc); + } + + return 0; +} + +#if __STD_C +int sfdcdio(Sfio_t* f, size_t bufsize) +#else +int sfdcdio(f, bufsize) +Sfio_t* f; +size_t bufsize; +#endif +{ +#ifndef F_DIOINFO + return -1; +#else + int cntl; + struct dioattr dio; + Void_t* buf; + Direct_t* di; + + if(f->extent < 0 || (f->flags&SF_STRING)) + return -1; + + if((cntl = fcntl(f->file,F_GETFL,0)) < 0) + return -1; + + if(!(cntl&FDIRECT) ) + { cntl |= FDIRECT; + if(fcntl(f->file,F_SETFL,cntl) < 0) + return -1; + } + + if(fcntl(f->file,F_DIOINFO,&dio) < 0) + goto no_direct; + + if(bufsize > 0) + bufsize = (bufsize/dio.d_miniosz)*dio.d_miniosz; + if(bufsize <= 0) + bufsize = dio.d_miniosz*64; + if(bufsize > dio.d_maxiosz) + bufsize = dio.d_maxiosz; + + if(!(di = (Direct_t*)malloc(sizeof(Direct_t))) ) + goto no_direct; + + if(!(buf = (Void_t*)memalign(dio.d_mem,bufsize)) ) + { free(di); + goto no_direct; + } + + sfsetbuf(f,buf,bufsize); + if(sfsetbuf(f,buf,0) == buf) + sfset(f,SF_MALLOC,1); + else + { free(buf); + free(di); + goto no_direct; + } + + di->disc.readf = dioread; + di->disc.writef = diowrite; + di->disc.seekf = NIL(Sfseek_f); + di->disc.exceptf = dioexcept; + di->cntl = cntl; + di->dio = dio; + + if(sfdisc(f,(Sfdisc_t*)di) != (Sfdisc_t*)di) + { free(di); + no_direct: + cntl &= ~FDIRECT; + (void)fcntl(f->file,F_SETFL,cntl); + return -1; + } + + return 0; + +#endif /*F_DIOINFO*/ +} diff --git a/src/lib/libast/disc/sfdcdos.c b/src/lib/libast/disc/sfdcdos.c new file mode 100644 index 0000000..15b7865 --- /dev/null +++ b/src/lib/libast/disc/sfdcdos.c @@ -0,0 +1,416 @@ +/*********************************************************************** +* * +* 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 "sfdchdr.h" + +/* Discipline to turn \r\n into \n. +** This is useful to deal with DOS text files. +** +** Written by David Korn (03/18/1998). +*/ + +#define MINMAP 8 +#define CHUNK 1024 + +struct map +{ + Sfoff_t logical; + Sfoff_t physical; +}; + +typedef struct _dosdisc +{ + Sfdisc_t disc; + struct map *maptable; + int mapsize; + int maptop; + Sfoff_t lhere; + Sfoff_t llast; + Sfoff_t lmax; + Sfoff_t pmax; + Sfoff_t phere; + Sfoff_t plast; + Sfoff_t begin; + int skip; + void *buff; + char last; + char extra; + int bsize; +} Dosdisc_t; + +#if __STD_C +static void addmapping(register Dosdisc_t *dp) +#else +static void addmapping(dp) +register Dosdisc_t *dp; +#endif +{ + register int n; + if((n=dp->maptop++)>=dp->mapsize) + { + dp->mapsize *= 2; + if(!(dp->maptable=(struct map*)realloc((void*)dp->maptable,(dp->mapsize+1)*sizeof(struct map)))) + { + dp->maptop--; + dp->mapsize *= 2; + return; + } + } + dp->maptable[n].physical = dp->phere; + dp->maptable[n].logical = dp->lhere; + dp->maptable[dp->maptop].logical=0; +} + +#if __STD_C +static struct map *getmapping(Dosdisc_t *dp, Sfoff_t offset, register int whence) +#else +static struct map *getmapping(dp, offset, whence) +Dosdisc_t *dp; +Sfoff_t offset; +register int whence; +#endif +{ + register struct map *mp; + static struct map dummy; + if(offset <= dp->begin) + { + dummy.logical = dummy.physical = offset; + return(&dummy); + } + if(!(mp=dp->maptable)) + { + dummy.logical = dp->begin; + dummy.physical = dummy.logical+1; + return(&dummy); + } + while((++mp)->logical && (whence==SEEK_CUR?mp->physical:mp->logical) <= offset); + return(mp-1); +} + +#if __STD_C +static ssize_t dos_read(Sfio_t *iop, void *buff, size_t size, Sfdisc_t* disc) +#else +static ssize_t dos_read(iop, buff, size, disc) +Sfio_t *iop; +void *buff; +size_t size; +Sfdisc_t* disc; +#endif +{ + register Dosdisc_t *dp = (Dosdisc_t*)disc; + register char *cp = (char*)buff, *first, *cpmax; + register int n, count, m; + if(dp->extra) + { + dp->extra=0; + *cp = dp->last; + return(1); + } + while(1) + { + if((n = sfrd(iop,buff,size,disc)) <= 0) + return(n); + dp->plast=dp->phere; + dp->phere +=n; + dp->llast = dp->lhere; + cpmax = cp+n-1; + if(dp->last=='\r' && *cp!='\n') + { + /* should insert a '\r' */ ; + } + dp->last = *cpmax; + if(n>1) + break; + if(dp->last!='\r') + { + dp->lhere++; + return(1); + } + } + if(dp->last=='\r') + n--; + else if(dp->last!='\n' || cpmax[-1]!='\r') + *cpmax = '\r'; + dp->lhere += n; + while(1) + { + while(*cp++ != '\r'); + if(cp > cpmax || *cp=='\n') + break; + } + dp->skip = cp-1 - (char*)buff; + /* if not \r\n in buffer, just return */ + if((count = cpmax+1-cp) <=0) + { + *cpmax = dp->last; + if(!dp->maptable) + dp->begin +=n; + dp->skip++; + count=0; + goto done; + } + if(!dp->maptable) + { + dp->begin += cp - (char*)buff-1; + if(dp->maptable=(struct map*)malloc((MINMAP+1)*sizeof(struct map))) + { + dp->mapsize = MINMAP; + dp->maptable[0].logical= dp->begin; + dp->maptable[0].physical = dp->maptable[0].logical+1; + dp->maptable[1].logical=0; + dp->maptop = 1; + } + } + /* save original discipline inside buffer */ + if(count>dp->bsize) + { + if(dp->bsize==0) + dp->buff = malloc(count); + else + dp->buff = realloc(dp->buff,count); + dp->bsize = count; + if(!dp->buff) + return(-1); + } + memcpy(dp->buff, cp, count); + count=1; + while(1) + { + first=cp; + if(cp==cpmax) + cp++; + else + while(*cp++ != '\r'); + if(cp<=cpmax && *cp!='\n') + continue; + if((m=(cp-first)-1) >0) + memcpy(first-count, first, m); + if(cp > cpmax) + break; + count++; + } + cpmax[-count] = dp->last; + dp->lhere -= count; +done: + if(dp->lhere>dp->lmax) + { + dp->lmax = dp->lhere; + dp->pmax = dp->phere; + if(dp->maptable && dp->lmax > dp->maptable[dp->maptop-1].logical+CHUNK) + addmapping(dp); + } + return(n-count); +} + +/* + * returns the current offset + * <offset> must be in the current buffer + * if <whence> is SEEK_CUR, physical offset converted to logical offset + * otherwise, logical offset is converted to physical offset + */ +#if __STD_C +static Sfoff_t cur_offset(Dosdisc_t *dp, Sfoff_t offset,Sfio_t *iop,register int whence) +#else +static Sfoff_t cur_offset(dp, offset, iop, whence) +Dosdisc_t *dp; +Sfoff_t offset; +Sfio_t *iop; +register int whence; +#endif +{ + register Sfoff_t n,m=0; + register char *cp; + + if(whence==SEEK_CUR) + { + whence= -1; + n = offset - dp->plast; + iop->next = iop->data + n; + offset = dp->llast; + } + else + { + whence = 1; + n = offset - dp->llast; + offset = dp->plast; + } + offset +=n; + if((n -= dp->skip) > 0) + { + m=whence; + cp = (char*)dp->buff; + while(n--) + { + if(*cp++=='\r' && *cp=='\n') + { + m += whence; + if(whence>0) + n++; + } + } + } + if(whence<0) + iop->next += m; + return(offset+m); +} + +#if __STD_C +static Sfoff_t dos_seek(Sfio_t *iop, Sfoff_t offset, register int whence, Sfdisc_t* disc) +#else +static Sfoff_t dos_seek(iop, offset, whence, disc) +Sfio_t *iop; +Sfoff_t offset; +register int whence; +Sfdisc_t* disc; +#endif +{ + register Dosdisc_t *dp = (Dosdisc_t*)disc; + struct map dummy, *mp=0; + Sfoff_t physical; + register int n,size; +retry: + switch(whence) + { + case SEEK_CUR: + offset = sfsk(iop, (Sfoff_t)0,SEEK_CUR,disc); + if(offset<=dp->begin) + return(offset); + /* check for seek outside buffer */ + if(offset==dp->phere) + return(dp->lhere); + else if(offset==dp->plast) + return(dp->llast); + else if(offset<dp->plast || offset>dp->phere) + mp = getmapping(dp,offset,whence); + break; + case SEEK_SET: + /* check for seek outside buffer */ + if(offset<dp->llast || offset > dp->lhere) + mp = getmapping(dp,offset,whence); + break; + case SEEK_END: + if(!dp->maptable) + return(sfsk(iop,offset,SEEK_END,disc)); + mp = &dummy; + mp->physical = dp->plast; + mp->logical = dp->llast; + break; + } + if(sfsetbuf(iop,(char*)iop,0)) + size = sfvalue(iop); + else + size = iop->endb-iop->data; + if(mp) + { + sfsk(iop,mp->physical,SEEK_SET,disc); + dp->phere = mp->physical; + dp->lhere = mp->logical; + if((*disc->readf)(iop,iop->data,size,disc)<0) + return(-1); + } + while(1) + { + if(whence==SEEK_CUR && dp->phere>=offset) + break; + if(whence==SEEK_SET && dp->lhere>=offset) + break; + n=(*disc->readf)(iop,iop->data,size,disc); + if(n < 0) + return(-1); + if(n==0) + { + if(whence==SEEK_END && offset<0) + { + offset = dp->lhere; + whence=SEEK_SET; + goto retry; + } + break; + } + } + if(whence==SEEK_END) + offset += dp->lhere; + else + { + physical = cur_offset(dp,offset,iop,whence); + if(whence==SEEK_SET) + { + sfsk(iop, physical ,SEEK_SET,disc); + dp->phere = physical; + dp->lhere = offset; + } + else + offset = physical; + } + return(offset); +} + +#if __STD_C +static int dos_except(Sfio_t *iop, int type, void *arg, Sfdisc_t *disc) +#else +static int dos_except(iop, type, arg, disc) +Sfio_t *iop; +int type; +void *arg; +Sfdisc_t *disc; +#endif +{ + register Dosdisc_t *dp = (Dosdisc_t*)disc; + if(type==SF_DPOP || type==SF_FINAL) + { + if(dp->bsize>0) + free((void*)dp->buff); + if(dp->mapsize) + free((void*)dp->maptable); + free((void*)disc); + } + return(0); +} + +#if __STD_C +int sfdcdos(Sfio_t *f) +#else +int sfdcdos(f) +Sfio_t *f; +#endif +{ + Dosdisc_t *dos; + + /* this is a readonly discipline */ + if(sfset(f,0,0)&SF_WRITE) + return(-1); + + if(!(dos = (Dosdisc_t*)malloc(sizeof(Dosdisc_t))) ) + return -1; + memset(dos,'\0',sizeof(Dosdisc_t)); + + dos->disc.readf = dos_read; + dos->disc.writef = NIL(Sfwrite_f); + dos->disc.seekf = dos_seek; + dos->disc.exceptf = dos_except; + + if(sfdisc(f,(Sfdisc_t*)dos) != (Sfdisc_t*)dos) + { free(dos); + return -1; + } + + return(0); +} diff --git a/src/lib/libast/disc/sfdcfilter.c b/src/lib/libast/disc/sfdcfilter.c new file mode 100644 index 0000000..16a2219 --- /dev/null +++ b/src/lib/libast/disc/sfdcfilter.c @@ -0,0 +1,186 @@ +/*********************************************************************** +* * +* 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 "sfdchdr.h" + +/* Discipline to invoke UNIX processes as data filters. +** These processes must be able to fit in pipelines. +** +** Written by Kiem-Phong Vo, kpv@research.att.com, 03/18/1998. +*/ + +typedef struct _filter_s +{ Sfdisc_t disc; /* discipline structure */ + Sfio_t* filter; /* the filter stream */ + char* next; /* data unwritten */ + char* endb; /* end of data */ + char raw[4096]; /* raw data buffer */ +} Filter_t; + +/* read data from the filter */ +#if __STD_C +static ssize_t filterread(Sfio_t* f, Void_t* buf, size_t n, Sfdisc_t* disc) +#else +static ssize_t filterread(f, buf, n, disc) +Sfio_t* f; /* stream reading from */ +Void_t* buf; /* buffer to read into */ +size_t n; /* number of bytes requested */ +Sfdisc_t* disc; /* discipline */ +#endif +{ + Filter_t* fi; + ssize_t r, w; + + fi = (Filter_t*)disc; + for(;;) + { + /* get some raw data to stuff down the pipe */ + if(fi->next && fi->next >= fi->endb ) + { if((r = sfrd(f,fi->raw,sizeof(fi->raw),disc)) > 0) + { fi->next = fi->raw; + fi->endb = fi->raw+r; + } + else + { /* eof, close write end of pipes */ + sfset(fi->filter,SF_READ,0); + close(sffileno(fi->filter)); + sfset(fi->filter,SF_READ,1); + fi->next = fi->endb = NIL(char*); + } + } + + if(fi->next && (w = fi->endb - fi->next) > 0 ) + { /* see if pipe is ready for write */ + sfset(fi->filter, SF_READ, 0); + r = sfpoll(&fi->filter, 1, 1); + sfset(fi->filter, SF_READ, 1); + + if(r == 1) /* non-blocking write */ + { errno = 0; + if((w = sfwr(fi->filter, fi->next, w, 0)) > 0) + fi->next += w; + else if(errno != EAGAIN) + return 0; + } + } + + /* see if pipe is ready for read */ + sfset(fi->filter, SF_WRITE, 0); + w = sfpoll(&fi->filter, 1, fi->next ? 1 : -1); + sfset(fi->filter, SF_WRITE, 1); + + if(!fi->next || w == 1) /* non-blocking read */ + { errno = 0; + if((r = sfrd(fi->filter, buf, n, 0)) > 0) + return r; + if(errno != EAGAIN) + return 0; + } + } +} + +#if __STD_C +static ssize_t filterwrite(Sfio_t* f, const Void_t* buf, size_t n, Sfdisc_t* disc) +#else +static ssize_t filterwrite(f, buf, n, disc) +Sfio_t* f; /* stream writing to */ +Void_t* buf; /* buffer to write into */ +size_t n; /* number of bytes requested */ +Sfdisc_t* disc; /* discipline */ +#endif +{ + return -1; +} + +/* for the duration of this discipline, the stream is unseekable */ +#if __STD_C +static Sfoff_t filterseek(Sfio_t* f, Sfoff_t addr, int offset, Sfdisc_t* disc) +#else +static Sfoff_t filterseek(f, addr, offset, disc) +Sfio_t* f; +Sfoff_t addr; +int offset; +Sfdisc_t* disc; +#endif +{ f = NIL(Sfio_t*); + addr = 0; + offset = 0; + disc = NIL(Sfdisc_t*); + return (Sfoff_t)(-1); +} + +/* on close, remove the discipline */ +#if __STD_C +static int filterexcept(Sfio_t* f, int type, Void_t* data, Sfdisc_t* disc) +#else +static int filterexcept(f,type,data,disc) +Sfio_t* f; +int type; +Void_t* data; +Sfdisc_t* disc; +#endif +{ + if(type == SF_FINAL || type == SF_DPOP) + { sfclose(((Filter_t*)disc)->filter); + free(disc); + } + + return 0; +} + +#if __STD_C +int sfdcfilter(Sfio_t* f, const char* cmd) +#else +int sfdcfilter(f, cmd) +Sfio_t* f; /* stream to filter data */ +char* cmd; /* program to run as a filter */ +#endif +{ + reg Filter_t* fi; + reg Sfio_t* filter; + + /* open filter for read&write */ + if(!(filter = sfpopen(NIL(Sfio_t*),cmd,"r+")) ) + return -1; + + /* unbuffered stream */ + sfsetbuf(filter,NIL(Void_t*),0); + + if(!(fi = (Filter_t*)malloc(sizeof(Filter_t))) ) + { sfclose(filter); + return -1; + } + + fi->disc.readf = filterread; + fi->disc.writef = filterwrite; + fi->disc.seekf = filterseek; + fi->disc.exceptf = filterexcept; + fi->filter = filter; + fi->next = fi->endb = fi->raw; + + if(sfdisc(f,(Sfdisc_t*)fi) != (Sfdisc_t*)fi) + { sfclose(filter); + free(fi); + return -1; + } + + return 0; +} diff --git a/src/lib/libast/disc/sfdchdr.h b/src/lib/libast/disc/sfdchdr.h new file mode 100644 index 0000000..7e5bbca --- /dev/null +++ b/src/lib/libast/disc/sfdchdr.h @@ -0,0 +1,28 @@ +/*********************************************************************** +* * +* 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> * +* * +***********************************************************************/ +/* + * common header for discipline functions + */ + +#include "sfhdr.h" + +#include <sfdisc.h> diff --git a/src/lib/libast/disc/sfdcmore.c b/src/lib/libast/disc/sfdcmore.c new file mode 100644 index 0000000..900b55d --- /dev/null +++ b/src/lib/libast/disc/sfdcmore.c @@ -0,0 +1,369 @@ +/*********************************************************************** +* * +* 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 "sfdchdr.h" + +#if _PACKAGE_ast +#include <ast_tty.h> +#include <signal.h> +#endif + +/* + * a simple but fast more style pager discipline + * if on sfstdout then sfstdin ops reset the page state + * + * Glenn Fowler + * AT&T Research + * + * @(#)$Id: sfdcmore (AT&T Research) 1998-06-25 $ + */ + +typedef struct +{ + Sfdisc_t disc; /* sfio discipline */ + Sfio_t* input; /* tied with this input stream */ + Sfio_t* error; /* tied with this error stream */ + int rows; /* max rows */ + int cols; /* max cols */ + int row; /* current row */ + int col; /* current col */ + int match; /* match length, 0 if none */ + char pattern[128]; /* match pattern */ + char prompt[1]; /* prompt string */ +} More_t; + +/* + * more read + * we assume line-at-a-time input + */ + +#if __STD_C +static ssize_t moreread(Sfio_t* f, void* buf, size_t n, Sfdisc_t* dp) +#else +static ssize_t moreread(f, buf, n, dp) +Sfio_t* f; +void* buf; +size_t n; +Sfdisc_t* dp; +#endif +{ + register More_t* more = (More_t*)dp; + + more->match = 0; + more->row = 2; + more->col = 1; + return sfrd(f, buf, n, dp); +} + +/* + * output label on wfd and return next char on rfd with no echo + * return < -1 is -(signal + 1) + */ + +#if __STD_C +static int ttyquery(Sfio_t* rp, Sfio_t* wp, const char* label, Sfdisc_t* dp) +#else +static int ttyquery(rp, wp, label, dp) +Sfio_t* rp; +Sfio_t* wp; +char* label; +Sfdisc_t* dp; +#endif +{ + register int r; + int n; + +#ifdef TCSADRAIN + unsigned char c; + struct termios old; + struct termios tty; + int rfd = sffileno(rp); + int wfd = sffileno(rp); + + if (!label) + n = 0; + else if (n = strlen(label)) + write(wfd, label, n); + tcgetattr(rfd, &old); + tty = old; + tty.c_cc[VTIME] = 0; + tty.c_cc[VMIN] = 1; + tty.c_lflag &= ~(ICANON|ECHO|ECHOK|ISIG); + tcsetattr(rfd, TCSADRAIN, &tty); + if ((r = read(rfd, &c, 1)) == 1) + { + if (c == old.c_cc[VEOF]) + r = -1; + else if (c == old.c_cc[VINTR]) + r = -(SIGINT + 1); + else if (c == old.c_cc[VQUIT]) + r = -(SIGQUIT + 1); + else if (c == '\r') + r = '\n'; + else + r = c; + } + tcsetattr(rfd, TCSADRAIN, &old); + if (n) + { + write(wfd, "\r", 1); + while (n-- > 0) + write(wfd, " ", 1); + write(wfd, "\r", 1); + } +#else + register char* s; + + if (label && (n = strlen(label))) + sfwr(wp, label, n, dp); + r = (s = sfgetr(rp, '\n', 0)) ? *s : -1; +#endif + return r; +} + +/* + * more write + */ + +#if __STD_C +static ssize_t morewrite(Sfio_t* f, const Void_t* buf, register size_t n, Sfdisc_t* dp) +#else +static ssize_t morewrite(f, buf, n, dp) +Sfio_t* f; +Void_t* buf; +register size_t n; +Sfdisc_t* dp; +#endif +{ + register More_t* more = (More_t*)dp; + register char* b; + register char* s; + register char* e; + register ssize_t w; + register int r; + + if (!more->row) + return n; + if (!more->col) + return sfwr(f, buf, n, dp); + w = 0; + b = (char*)buf; + s = b; + e = s + n; + if (more->match) + { + match: + for (r = more->pattern[0];; s++) + { + if (s >= e) + return n; + if (*s == '\n') + b = s + 1; + else if (*s == r && (e - s) >= more->match && !strncmp(s, more->pattern, more->match)) + break; + } + s = b; + w += b - (char*)buf; + more->match = 0; + } + while (s < e) + { + switch (*s++) + { + case '\t': + more->col = ((more->col + 8) & ~7) - 1; + /*FALLTHROUGH*/ + default: + if (++more->col <= more->cols || s < e && *s == '\n') + continue; + /*FALLTHROUGH*/ + case '\n': + more->col = 1; + if (++more->row < more->rows) + continue; + break; + case '\b': + if (more->col > 1) + more->col--; + continue; + case '\r': + more->col = 1; + continue; + } + w += sfwr(f, b, s - b, dp); + b = s; + r = ttyquery(sfstdin, f, more->prompt, dp); + if (r == '/' || r == 'n') + { + if (r == '/') + { + sfwr(f, "/", 1, dp); + if ((s = sfgetr(sfstdin, '\n', 1)) && (n = sfvalue(sfstdin) - 1) > 0) + { + if (n >= sizeof(more->pattern)) + n = sizeof(more->pattern) - 1; + memcpy(more->pattern, s, n); + more->pattern[n] = 0; + } + } + if (more->match = strlen(more->pattern)) + { + more->row = 1; + more->col = 1; + goto match; + } + } + switch (r) + { + case '\n': + case '\r': + more->row--; + more->col = 1; + break; + case ' ': + more->row = 2; + more->col = 1; + break; + default: + more->row = 0; + return n; + } + } + if (s > b) + w += sfwr(f, b, s - b, dp); + return w; +} + +/* + * remove the discipline on close + */ + +#if __STD_C +static int moreexcept(Sfio_t* f, int type, Void_t* data, Sfdisc_t* dp) +#else +static int moreexcept(f, type, data, dp) +Sfio_t* f; +int type; +Void_t* data; +Sfdisc_t* dp; +#endif +{ + register More_t* more = (More_t*)dp; + + if (type == SF_FINAL || type == SF_DPOP) + { + if (f = more->input) + { + more->input = 0; + sfdisc(f, SF_POPDISC); + } + else if (f = more->error) + { + more->error = 0; + sfdisc(f, SF_POPDISC); + } + else + free(dp); + } + else if (type == SF_SYNC) + { + more->match = 0; + more->row = 1; + more->col = 1; + } + return 0; +} + +/* + * push the more discipline on f + * if prompt==0 then a default ansi prompt is used + * if rows==0 or cols==0 then they are deterimined from the tty + * if f==sfstdout then input on sfstdin also resets the state + */ + +#if __STD_C +int sfdcmore(Sfio_t* f, const char* prompt, int rows, int cols) +#else +int sfdcmore(f, prompt, rows, cols) +Sfio_t* f; +char* prompt; +int rows; +int cols; +#endif +{ + register More_t* more; + size_t n; + + /* + * this is a writeonly discipline for interactive io + */ + + if (!(sfset(f, 0, 0) & SF_WRITE) || !isatty(sffileno(sfstdin)) || !isatty(sffileno(sfstdout))) + return -1; + if (!prompt) + prompt = "\033[7m More\033[m"; + n = strlen(prompt) + 1; + if (!(more = (More_t*)malloc(sizeof(More_t) + n))) + return -1; + memset(more, 0, sizeof(*more)); + + more->disc.readf = moreread; + more->disc.writef = morewrite; + more->disc.exceptf = moreexcept; + memcpy(more->prompt, prompt, n); + if (!rows || !cols) + { +#if _PACKAGE_ast + astwinsize(sffileno(sfstdin), &rows, &cols); +#endif + if (!rows) + rows = 24; + if (!cols) + cols = 80; + } + more->rows = rows; + more->cols = cols; + more->row = 1; + more->col = 1; + + if (sfdisc(f, &more->disc) != &more->disc) + { + free(more); + return -1; + } + if (f == sfstdout) + { + if (sfdisc(sfstdin, &more->disc) != &more->disc) + { + sfdisc(f, SF_POPDISC); + return -1; + } + more->input = sfstdin; + if (sfdisc(sfstderr, &more->disc) != &more->disc) + { + sfdisc(f, SF_POPDISC); + return -1; + } + more->error = sfstdin; + } + + return 0; +} diff --git a/src/lib/libast/disc/sfdcprefix.c b/src/lib/libast/disc/sfdcprefix.c new file mode 100644 index 0000000..29f3fd4 --- /dev/null +++ b/src/lib/libast/disc/sfdcprefix.c @@ -0,0 +1,153 @@ +/*********************************************************************** +* * +* 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 "sfdchdr.h" + +/* + * a discipline that prepends a prefix string to each output line + * + * Glenn Fowler + * AT&T Research + * + * @(#)$Id: sfdcprefix (AT&T Research) 1998-06-25 $ + */ + +typedef struct +{ + Sfdisc_t disc; /* sfio discipline */ + size_t length; /* prefix length */ + size_t empty; /* empty line prefix length */ + int skip; /* this line already prefixed */ + char prefix[1]; /* prefix string */ +} Prefix_t; + +/* + * prefix write + */ + +#if __STD_C +static ssize_t pfxwrite(Sfio_t* f, const Void_t* buf, register size_t n, Sfdisc_t* dp) +#else +static ssize_t pfxwrite(f, buf, n, dp) +Sfio_t* f; +Void_t* buf; +register size_t n; +Sfdisc_t* dp; +#endif +{ + register Prefix_t* pfx = (Prefix_t*)dp; + register char* b; + register char* s; + register char* e; + register char* t; + register ssize_t w; + int skip; + + skip = 0; + w = 0; + b = (char*)buf; + s = b; + e = s + n; + do + { + if (!(t = memchr(s, '\n', e - s))) + { + skip = 1; + t = e - 1; + } + n = t - s + 1; + if (pfx->skip) + pfx->skip = 0; + else + sfwr(f, pfx->prefix, n > 1 ? pfx->length : pfx->empty, dp); + w += sfwr(f, s, n, dp); + if ((s = t + 1) >= e) + return w; + } while ((s = t + 1) < e); + pfx->skip = skip; + return w; + +} + +/* + * remove the discipline on close + */ + +#if __STD_C +static int pfxexcept(Sfio_t* f, int type, Void_t* data, Sfdisc_t* dp) +#else +static int pfxexcept(f, type, data, dp) +Sfio_t* f; +int type; +Void_t* data; +Sfdisc_t* dp; +#endif +{ + if (type == SF_FINAL || type == SF_DPOP) + free(dp); + return 0; +} + +/* + * push the prefix discipline on f + */ + +#if __STD_C +int sfdcprefix(Sfio_t* f, const char* prefix) +#else +int sfdcprefix(f, prefix) +Sfio_t* f; +char* prefix; +#endif +{ + register Prefix_t* pfx; + register char* s; + size_t n; + + /* + * this is a writeonly discipline + */ + + if (!prefix || !(n = strlen(prefix)) || !(sfset(f, 0, 0) & SF_WRITE)) + return -1; + if (!(pfx = (Prefix_t*)malloc(sizeof(Prefix_t) + n))) + return -1; + memset(pfx, 0, sizeof(*pfx)); + + pfx->disc.writef = pfxwrite; + pfx->disc.exceptf = pfxexcept; + pfx->length = n; + memcpy(pfx->prefix, prefix, n); + s = (char*)prefix + n; + while (--s > (char*)prefix && (*s == ' ' || *s == '\t')); + n = s - (char*)prefix; + if (*s != ' ' || *s != '\t') + n++; + pfx->empty = n; + + if (sfdisc(f, &pfx->disc) != &pfx->disc) + { + free(pfx); + return -1; + } + + return 0; +} diff --git a/src/lib/libast/disc/sfdcseekable.c b/src/lib/libast/disc/sfdcseekable.c new file mode 100644 index 0000000..23c5b93 --- /dev/null +++ b/src/lib/libast/disc/sfdcseekable.c @@ -0,0 +1,227 @@ +/*********************************************************************** +* * +* 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 "sfdchdr.h" + +/* Discipline to make an unseekable read stream seekable +** +** sfraise(f,SFSK_DISCARD,0) discards previous seek data +** but seeks from current offset on still allowed +** +** Written by Kiem-Phong Vo, kpv@research.att.com, 03/18/1998. +*/ + +typedef struct _skable_s +{ Sfdisc_t disc; /* sfio discipline */ + Sfio_t* shadow; /* to shadow data */ + Sfoff_t discard;/* sfseek(f,-1,SEEK_SET) discarded data */ + Sfoff_t extent; /* shadow extent */ + int eof; /* if eof has been reached */ +} Seek_t; + +#if __STD_C +static ssize_t skwrite(Sfio_t* f, const Void_t* buf, size_t n, Sfdisc_t* disc) +#else +static ssize_t skwrite(f, buf, n, disc) +Sfio_t* f; /* stream involved */ +Void_t* buf; /* buffer to read into */ +size_t n; /* number of bytes to read */ +Sfdisc_t* disc; /* discipline */ +#endif +{ + return (ssize_t)(-1); +} + +#if __STD_C +static ssize_t skread(Sfio_t* f, Void_t* buf, size_t n, Sfdisc_t* disc) +#else +static ssize_t skread(f, buf, n, disc) +Sfio_t* f; /* stream involved */ +Void_t* buf; /* buffer to read into */ +size_t n; /* number of bytes to read */ +Sfdisc_t* disc; /* discipline */ +#endif +{ + Seek_t* sk; + Sfio_t* sf; + Sfoff_t addr; + ssize_t r, w, p; + + sk = (Seek_t*)disc; + sf = sk->shadow; + if(sk->eof) + return sfread(sf,buf,n); + + addr = sfseek(sf,(Sfoff_t)0,SEEK_CUR); + + if(addr+n <= sk->extent) + return sfread(sf,buf,n); + + if((r = (ssize_t)(sk->extent-addr)) > 0) + { if((w = sfread(sf,buf,r)) != r) + return w; + buf = (char*)buf + r; + n -= r; + } + + /* do a raw read */ + if((w = sfrd(f,buf,n,disc)) <= 0) + { sk->eof = 1; + w = 0; + } + else + { + if((p = sfwrite(sf,buf,w)) != w) + sk->eof = 1; + if(p > 0) + sk->extent += p; + } + + return r+w; +} + +#if __STD_C +static Sfoff_t skseek(Sfio_t* f, Sfoff_t addr, int type, Sfdisc_t* disc) +#else +static Sfoff_t skseek(f, addr, type, disc) +Sfio_t* f; +Sfoff_t addr; +int type; +Sfdisc_t* disc; +#endif +{ + Seek_t* sk; + Sfio_t* sf; + char buf[SF_BUFSIZE]; + ssize_t r, w; + + sk = (Seek_t*)disc; + sf = sk->shadow; + + switch (type) + { + case SEEK_SET: + addr -= sk->discard; + break; + case SEEK_CUR: + addr += sftell(sf); + break; + case SEEK_END: + addr += sk->extent; + break; + default: + return -1; + } + + if(addr < 0) + return (Sfoff_t)(-1); + else if(addr > sk->extent) + { if(sk->eof) + return (Sfoff_t)(-1); + + /* read enough to reach the seek point */ + while(addr > sk->extent) + { if(addr > sk->extent+sizeof(buf) ) + w = sizeof(buf); + else w = (int)(addr-sk->extent); + if((r = sfrd(f,buf,w,disc)) <= 0) + w = r-1; + else if((w = sfwrite(sf,buf,r)) > 0) + sk->extent += w; + if(w != r) + { sk->eof = 1; + break; + } + } + + if(addr > sk->extent) + return (Sfoff_t)(-1); + } + + return sfseek(sf,addr,SEEK_SET) + sk->discard; +} + +/* on close, remove the discipline */ +#if __STD_C +static int skexcept(Sfio_t* f, int type, Void_t* data, Sfdisc_t* disc) +#else +static int skexcept(f,type,data,disc) +Sfio_t* f; +int type; +Void_t* data; +Sfdisc_t* disc; +#endif +{ + Seek_t* sk; + + sk = (Seek_t*)disc; + + switch (type) + { + case SF_FINAL: + case SF_DPOP: + sfclose(sk->shadow); + free(disc); + break; + case SFSK_DISCARD: + sk->eof = 0; + sk->discard += sk->extent; + sk->extent = 0; + sfseek(sk->shadow,(Sfoff_t)0,SEEK_SET); + break; + } + return 0; +} + +#if __STD_C +int sfdcseekable(Sfio_t* f) +#else +int sfdcseekable(f) +Sfio_t* f; +#endif +{ + reg Seek_t* sk; + + /* see if already seekable */ + if(sfseek(f,(Sfoff_t)0,SEEK_CUR) >= 0) + return 0; + + if(!(sk = (Seek_t*)malloc(sizeof(Seek_t))) ) + return -1; + memset(sk, 0, sizeof(*sk)); + + sk->disc.readf = skread; + sk->disc.writef = skwrite; + sk->disc.seekf = skseek; + sk->disc.exceptf = skexcept; + sk->shadow = sftmp(SF_BUFSIZE); + sk->discard = 0; + sk->extent = 0; + sk->eof = 0; + + if(sfdisc(f, (Sfdisc_t*)sk) != (Sfdisc_t*)sk) + { sfclose(sk->shadow); + free(sk); + return -1; + } + + return 0; +} diff --git a/src/lib/libast/disc/sfdcslow.c b/src/lib/libast/disc/sfdcslow.c new file mode 100644 index 0000000..e75f438 --- /dev/null +++ b/src/lib/libast/disc/sfdcslow.c @@ -0,0 +1,84 @@ +/*********************************************************************** +* * +* 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 "sfdchdr.h" + +/* Make a stream op return immediately on interrupts. +** This is useful on slow streams (hence the name). +** +** Written by Glenn Fowler (03/18/1998). +*/ + +#if __STD_C +static int slowexcept(Sfio_t* f, int type, Void_t* v, Sfdisc_t* disc) +#else +static int slowexcept(f, type, v, disc) +Sfio_t* f; +int type; +Void_t* v; +Sfdisc_t* disc; +#endif +{ + NOTUSED(f); + NOTUSED(v); + NOTUSED(disc); + + switch (type) + { + case SF_FINAL: + case SF_DPOP: + free(disc); + break; + case SF_READ: + case SF_WRITE: + if (errno == EINTR) + return(-1); + break; + } + + return(0); +} + +#if __STD_C +int sfdcslow(Sfio_t* f) +#else +int sfdcslow(f) +Sfio_t* f; +#endif +{ + Sfdisc_t* disc; + + if(!(disc = (Sfdisc_t*)malloc(sizeof(Sfdisc_t))) ) + return(-1); + + disc->readf = NIL(Sfread_f); + disc->writef = NIL(Sfwrite_f); + disc->seekf = NIL(Sfseek_f); + disc->exceptf = slowexcept; + + if(sfdisc(f,disc) != disc) + { free(disc); + return(-1); + } + sfset(f,SF_IOINTR,1); + + return(0); +} diff --git a/src/lib/libast/disc/sfdcsubstr.c b/src/lib/libast/disc/sfdcsubstr.c new file mode 100644 index 0000000..c0fae9b --- /dev/null +++ b/src/lib/libast/disc/sfdcsubstr.c @@ -0,0 +1,217 @@ +/*********************************************************************** +* * +* 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 "sfdchdr.h" + + +/* Discipline to treat a contiguous segment of a stream as a stream +** in its own right. The hard part in all this is to allow multiple +** segments of the stream to be used as substreams at the same time. +** +** Written by David G. Korn and Kiem-Phong Vo (03/18/1998) +*/ + +typedef struct _subfile_s +{ + Sfdisc_t disc; /* sfio discipline */ + Sfio_t* parent; /* parent stream */ + Sfoff_t offset; /* starting offset */ + Sfoff_t extent; /* size wanted */ + Sfoff_t here; /* current seek location */ +} Subfile_t; + +#if __STD_C +static ssize_t streamio(Sfio_t* f, Void_t* buf, size_t n, Sfdisc_t* disc, int type) +#else +static ssize_t streamio(f, buf, n, disc, type) +Sfio_t* f; +Void_t* buf; +size_t n; +Sfdisc_t* disc; +int type; +#endif +{ + reg Subfile_t *su; + reg Sfoff_t here, parent; + reg ssize_t io; + + su = (Subfile_t*)disc; + + /* read just what we need */ + if(su->extent >= 0 && (ssize_t)n > (io = (ssize_t)(su->extent - su->here)) ) + n = io; + if(n <= 0) + return n; + + /* save current location in parent stream */ + parent = sfsk(f,(Sfoff_t)0,SEEK_CUR,disc); + + /* read data */ + here = su->here + su->offset; + if(sfsk(f,here,SEEK_SET,disc) != here) + io = 0; + else + { if(type == SF_WRITE) + io = sfwr(f,buf,n,disc); + else io = sfrd(f,buf,n,disc); + if(io > 0) + su->here += io; + } + + /* restore parent current position */ + sfsk(f,parent,SEEK_SET,disc); + + return io; +} + +#if __STD_C +static ssize_t streamwrite(Sfio_t* f, const Void_t* buf, size_t n, Sfdisc_t* disc) +#else +static ssize_t streamwrite(f, buf, n, disc) +Sfio_t* f; +Void_t* buf; +size_t n; +Sfdisc_t* disc; +#endif +{ + return streamio(f,(Void_t*)buf,n,disc,SF_WRITE); +} + +#if __STD_C +static ssize_t streamread(Sfio_t* f, Void_t* buf, size_t n, Sfdisc_t* disc) +#else +static ssize_t streamread(f, buf, n, disc) +Sfio_t* f; +Void_t* buf; +size_t n; +Sfdisc_t* disc; +#endif +{ + return streamio(f,buf,n,disc,SF_READ); +} + +#if __STD_C +static Sfoff_t streamseek(Sfio_t* f, Sfoff_t pos, int type, Sfdisc_t* disc) +#else +static Sfoff_t streamseek(f, pos, type, disc) +Sfio_t* f; +Sfoff_t pos; +int type; +Sfdisc_t* disc; +#endif +{ + reg Subfile_t* su; + reg Sfoff_t here, parent; + + su = (Subfile_t*)disc; + + switch(type) + { + case SEEK_SET: + here = 0; + break; + case SEEK_CUR: + here = su->here; + break; + case SEEK_END: + if(su->extent >= 0) + here = su->extent; + else + { parent = sfsk(f,(Sfoff_t)0,SEEK_CUR,disc); + if((here = sfsk(f,(Sfoff_t)0,SEEK_END,disc)) < 0) + return -1; + else here -= su->offset; + sfsk(f,parent,SEEK_SET,disc); + } + break; + default: + return -1; + } + + pos += here; + if(pos < 0 || (su->extent >= 0 && pos >= su->extent)) + return -1; + + return (su->here = pos); +} + +#if __STD_C +static int streamexcept(Sfio_t* f, int type, Void_t* data, Sfdisc_t* disc) +#else +static int streamexcept(f, type, data, disc) +Sfio_t* f; +int type; +Void_t* data; +Sfdisc_t* disc; +#endif +{ + if(type == SF_FINAL || type == SF_DPOP) + free(disc); + return 0; +} + +#if __STD_C +Sfio_t* sfdcsubstream(Sfio_t* f, Sfio_t* parent, Sfoff_t offset, Sfoff_t extent) +#else +Sfio_t* sfdcsubstream(f, parent, offset, extent) +Sfio_t* f; /* stream */ +Sfio_t* parent; /* parent stream */ +Sfoff_t offset; /* offset in f */ +Sfoff_t extent; /* desired size */ +#endif +{ + reg Sfio_t* sp; + reg Subfile_t* su; + reg Sfoff_t here; + + /* establish that we can seek to offset */ + if((here = sfseek(parent,(Sfoff_t)0,SEEK_CUR)) < 0 || sfseek(parent,offset,SEEK_SET) < 0) + return 0; + else sfseek(parent,here,SEEK_SET); + sfpurge(parent); + + if (!(sp = f) && !(sp = sfnew(NIL(Sfio_t*), NIL(Void_t*), (size_t)SF_UNBOUND, dup(sffileno(parent)), parent->flags))) + return 0; + + if(!(su = (Subfile_t*)malloc(sizeof(Subfile_t)))) + { if(sp != f) + sfclose(sp); + return 0; + } + memset(su, 0, sizeof(*su)); + + su->disc.readf = streamread; + su->disc.writef = streamwrite; + su->disc.seekf = streamseek; + su->disc.exceptf = streamexcept; + su->parent = parent; + su->offset = offset; + su->extent = extent; + + if(sfdisc(sp, (Sfdisc_t*)su) != (Sfdisc_t*)su) + { free(su); + if(sp != f) + sfclose(sp); + return 0; + } + + return sp; +} diff --git a/src/lib/libast/disc/sfdctee.c b/src/lib/libast/disc/sfdctee.c new file mode 100644 index 0000000..66bf71e --- /dev/null +++ b/src/lib/libast/disc/sfdctee.c @@ -0,0 +1,102 @@ +/*********************************************************************** +* * +* 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 "sfdchdr.h" + +/* A discipline to tee the output to a stream to another stream. +** This is similar to what the "tee" program does. As implemented +** this discipline only works with file streams. +** +** Written by Kiem-Phong Vo, kpv@research.att.com, 03/18/1998. +*/ + +/* the discipline structure for tee-ing */ +typedef struct _tee_s +{ Sfdisc_t disc; /* the sfio discipline structure */ + Sfio_t* tee; /* the stream to tee to */ + int status; /* if tee stream is still ok */ +} Tee_t; + +/* write to the teed stream. */ +#if __STD_C +static ssize_t teewrite(Sfio_t* f, const Void_t* buf, size_t size, Sfdisc_t* disc) +#else +static ssize_t teewrite(f,buf,size,disc) +Sfio_t* f; /* the stream being written to */ +Void_t* buf; /* the buffer of data being output */ +size_t size; /* the data size */ +Sfdisc_t* disc; /* the tee discipline */ +#endif +{ + reg Tee_t* te = (Tee_t*)disc; + + /* tee data if still ok */ + if(te->status == 0 && sfwrite(te->tee,buf,size) != (ssize_t)size) + te->status = -1; + + /* do the actual write */ + return sfwr(f,buf,size,disc); +} + +/* on close, remove the discipline */ +#if __STD_C +static int teeexcept(Sfio_t* f, int type, Void_t* data, Sfdisc_t* disc) +#else +static int teeexcept(f,type,data,disc) +Sfio_t* f; +int type; +Void_t* data; +Sfdisc_t* disc; +#endif +{ + if(type == SF_FINAL || type == SF_DPOP) + free(disc); + + return 0; +} + +#if __STD_C +int sfdctee(Sfio_t* f, Sfio_t* tee) +#else +int sfdctee(f, tee) +Sfio_t* f; /* stream to tee from */ +Sfio_t* tee; /* stream to tee to */ +#endif +{ + reg Tee_t* te; + + if(!(te = (Tee_t*)malloc(sizeof(Tee_t))) ) + return -1; + + te->disc.readf = NIL(Sfread_f); + te->disc.seekf = NIL(Sfseek_f); + te->disc.writef = teewrite; + te->disc.exceptf = teeexcept; + te->tee = tee; + te->status = 0; + + if(sfdisc(f,(Sfdisc_t*)te) != (Sfdisc_t*)te) + { free(te); + return -1; + } + + return 0; +} diff --git a/src/lib/libast/disc/sfdcunion.c b/src/lib/libast/disc/sfdcunion.c new file mode 100644 index 0000000..1f45909 --- /dev/null +++ b/src/lib/libast/disc/sfdcunion.c @@ -0,0 +1,203 @@ +/*********************************************************************** +* * +* 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 "sfdchdr.h" + + +/* Make a sequence of streams act like a single stream. +** This is for reading only. +** +** Written by Kiem-Phong Vo, kpv@research.att.com, 03/18/1998. +*/ + +#define UNSEEKABLE 1 + +typedef struct _file_s +{ Sfio_t* f; /* the stream */ + Sfoff_t lower; /* its lowest end */ +} File_t; + +typedef struct _union_s +{ + Sfdisc_t disc; /* discipline structure */ + short type; /* type of streams */ + short c; /* current stream */ + short n; /* number of streams */ + Sfoff_t here; /* current location */ + File_t f[1]; /* array of streams */ +} Union_t; + +#if __STD_C +static ssize_t unwrite(Sfio_t* f, const Void_t* buf, size_t n, Sfdisc_t* disc) +#else +static ssize_t unwrite(f, buf, n, disc) +Sfio_t* f; /* stream involved */ +Void_t* buf; /* buffer to read into */ +size_t n; /* number of bytes to read */ +Sfdisc_t* disc; /* discipline */ +#endif +{ + return -1; +} + +#if __STD_C +static ssize_t unread(Sfio_t* f, Void_t* buf, size_t n, Sfdisc_t* disc) +#else +static ssize_t unread(f, buf, n, disc) +Sfio_t* f; /* stream involved */ +Void_t* buf; /* buffer to read into */ +size_t n; /* number of bytes to read */ +Sfdisc_t* disc; /* discipline */ +#endif +{ + reg Union_t* un; + reg ssize_t r, m; + + un = (Union_t*)disc; + m = n; + f = un->f[un->c].f; + while(1) + { if((r = sfread(f,buf,m)) < 0 || (r == 0 && un->c == un->n-1) ) + break; + + m -= r; + un->here += r; + + if(m == 0) + break; + + buf = (char*)buf + r; + if(sfeof(f) && un->c < un->n-1) + f = un->f[un->c += 1].f; + } + return n-m; +} + +#if __STD_C +static Sfoff_t unseek(Sfio_t* f, Sfoff_t addr, int type, Sfdisc_t* disc) +#else +static Sfoff_t unseek(f, addr, type, disc) +Sfio_t* f; +Sfoff_t addr; +int type; +Sfdisc_t* disc; +#endif +{ + reg Union_t* un; + reg int i; + reg Sfoff_t extent, s; + + un = (Union_t*)disc; + if(un->type&UNSEEKABLE) + return -1L; + + if(type == 2) + { extent = 0; + for(i = 0; i < un->n; ++i) + extent += (sfsize(un->f[i].f) - un->f[i].lower); + addr += extent; + } + else if(type == 1) + addr += un->here; + + if(addr < 0) + return -1; + + /* find the stream where the addr could be in */ + extent = 0; + for(i = 0; i < un->n-1; ++i) + { s = sfsize(un->f[i].f) - un->f[i].lower; + if(addr < extent + s) + break; + extent += s; + } + + s = (addr-extent) + un->f[i].lower; + if(sfseek(un->f[i].f,s,0) != s) + return -1; + + un->c = i; + un->here = addr; + + for(i += 1; i < un->n; ++i) + sfseek(un->f[i].f,un->f[i].lower,0); + + return addr; +} + +/* on close, remove the discipline */ +#if __STD_C +static int unexcept(Sfio_t* f, int type, Void_t* data, Sfdisc_t* disc) +#else +static int unexcept(f,type,data,disc) +Sfio_t* f; +int type; +Void_t* data; +Sfdisc_t* disc; +#endif +{ + if(type == SF_FINAL || type == SF_DPOP) + free(disc); + + return 0; +} + +#if __STD_C +int sfdcunion(Sfio_t* f, Sfio_t** array, int n) +#else +int sfdcunion(f, array, n) +Sfio_t* f; +Sfio_t** array; +int n; +#endif +{ + reg Union_t* un; + reg int i; + + if(n <= 0) + return -1; + + if(!(un = (Union_t*)malloc(sizeof(Union_t)+(n-1)*sizeof(File_t))) ) + return -1; + memset(un, 0, sizeof(*un)); + + un->disc.readf = unread; + un->disc.writef = unwrite; + un->disc.seekf = unseek; + un->disc.exceptf = unexcept; + un->n = n; + + for(i = 0; i < n; ++i) + { un->f[i].f = array[i]; + if(!(un->type&UNSEEKABLE)) + { un->f[i].lower = sfseek(array[i],(Sfoff_t)0,1); + if(un->f[i].lower < 0) + un->type |= UNSEEKABLE; + } + } + + if(sfdisc(f,(Sfdisc_t*)un) != (Sfdisc_t*)un) + { free(un); + return -1; + } + + return 0; +} diff --git a/src/lib/libast/disc/sfkeyprintf.c b/src/lib/libast/disc/sfkeyprintf.c new file mode 100644 index 0000000..c63fe37 --- /dev/null +++ b/src/lib/libast/disc/sfkeyprintf.c @@ -0,0 +1,392 @@ +/*********************************************************************** +* * +* 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> * +* * +***********************************************************************/ +#pragma prototyped + +/* + * Glenn Fowler + * AT&T Research + * + * keyword printf support + */ + +#define _AST_API_H 1 + +#include <ast.h> +#include <ccode.h> +#include <ctype.h> +#include <sfdisc.h> +#include <regex.h> + +#define FMT_case 1 +#define FMT_edit 2 + +typedef struct +{ + Sffmt_t fmt; + void* handle; + Sf_key_lookup_t lookup; + Sf_key_convert_t convert; + Sfio_t* tmp[2]; + regex_t red[2]; + regex_t* re[2]; + int invisible; + int level; + int version; +} Fmt_t; + +typedef struct +{ + char* next; + int delimiter; + int first; +} Field_t; + +typedef union +{ + char** p; + char* s; + Sflong_t q; + long l; + int i; + short h; + char c; +} Value_t; + +#define initfield(f,s) ((f)->first = (f)->delimiter = *((f)->next = (s))) + +static char* +getfield(register Field_t* f, int restore) +{ + register char* s; + register int n; + register int c; + register int lp; + register int rp; + char* b; + + if (!f->delimiter) + return 0; + s = f->next; + if (f->first) + f->first = 0; + else if (restore) + *s = f->delimiter; + b = ++s; + lp = rp = n = 0; + for (;;) + { + if (!(c = *s++)) + { + f->delimiter = 0; + break; + } + else if (c == CC_esc || c == '\\') + { + if (*s) + s++; + } + else if (c == lp) + n++; + else if (c == rp) + n--; + else if (n <= 0) + { + if (c == '(' && restore) + { + lp = '('; + rp = ')'; + n = 1; + } + else if (c == '[' && restore) + { + lp = '['; + rp = ']'; + n = 1; + } + else if (c == f->delimiter) + { + *(f->next = --s) = 0; + break; + } + } + } + return b; +} + +/* + * sfio %! extension function + */ + +static int +getfmt(Sfio_t* sp, void* vp, Sffmt_t* dp) +{ + register Fmt_t* fp = (Fmt_t*)dp; + Value_t* value = (Value_t*)vp; + register char* v; + char* t; + char* b; + char* a = 0; + char* s = 0; + Sflong_t n = 0; + int h = 0; + int i = 0; + int x = 0; + int d; + Field_t f; + regmatch_t match[10]; + + fp->level++; + if (fp->fmt.t_str && fp->fmt.n_str > 0 && (v = fmtbuf(fp->fmt.n_str + 1))) + { + memcpy(v, fp->fmt.t_str, fp->fmt.n_str); + v[fp->fmt.n_str] = 0; + b = v; + for (;;) + { + switch (*v++) + { + case 0: + break; + case '(': + h++; + continue; + case ')': + h--; + continue; + case '=': + case ':': + case ',': + if (h <= 0) + { + a = v; + break; + } + continue; + default: + continue; + } + if (i = *--v) + { + *v = 0; + if (i == ':' && fp->fmt.fmt == 's' && strlen(a) > 4 && !isalnum(*(a + 4))) + { + d = *(a + 4); + *(a + 4) = 0; + if (streq(a, "case")) + x = FMT_case; + else if (streq(a, "edit")) + x = FMT_edit; + *(a + 4) = d; + if (x) + a = 0; + } + } + break; + } + n = i; + t = fp->fmt.t_str; + fp->fmt.t_str = b; + h = (*fp->lookup)(fp->handle, &fp->fmt, a, &s, &n); + fp->fmt.t_str = t; + if (i) + *v++ = i; + } + else + { + h = (*fp->lookup)(fp->handle, &fp->fmt, a, &s, &n); + v = 0; + } + fp->fmt.flags |= SFFMT_VALUE; + switch (fp->fmt.fmt) + { + case 'c': + value->c = s ? *s : n; + break; + case 'd': + case 'i': + fp->fmt.size = sizeof(Sflong_t); + value->q = (Sflong_t)(s ? strtoll(s, NiL, 0) : n); + break; + case 'o': + case 'u': + case 'x': + fp->fmt.size = sizeof(Sflong_t); + value->q = s ? (Sflong_t)strtoull(s, NiL, 0) : n; + break; + case 'p': + if (s) + n = strtoll(s, NiL, 0); + value->p = pointerof(n); + break; + case 'q': + if (s) + { + fp->fmt.fmt = 's'; + value->s = fmtquote(s, "$'", "'", strlen(s), 0); + } + else + { + fp->fmt.fmt = 'd'; + value->q = n; + } + break; + case 's': + if (!s && (!h || !fp->tmp[1] && !(fp->tmp[1] = sfstropen()) || sfprintf(fp->tmp[1], "%I*d", sizeof(n), n) <= 0 || !(s = sfstruse(fp->tmp[1])))) + s = ""; + if (x) + { + h = 0; + d = initfield(&f, v + 4); + switch (x) + { + case FMT_case: + while ((a = getfield(&f, 1)) && (v = getfield(&f, 0))) + { + if (strmatch(s, a)) + { + Fmt_t fmt; + + fmt = *fp; + fmt.fmt.form = v; + for (h = 0; h < elementsof(fmt.tmp); h++) + fmt.tmp[h] = 0; + if (!fp->tmp[0] && !(fp->tmp[0] = sfstropen()) || sfprintf(fp->tmp[0], "%!", &fmt) <= 0 || !(s = sfstruse(fp->tmp[0]))) + s = ""; + *(v - 1) = d; + if (f.delimiter) + *f.next = d; + for (h = 0; h < elementsof(fmt.tmp); h++) + if (fmt.tmp[h]) + sfclose(fmt.tmp[h]); + h = 1; + break; + } + *(v - 1) = d; + } + break; + case FMT_edit: + for (x = 0; *f.next; x ^= 1) + { + if (fp->re[x]) + regfree(fp->re[x]); + else + fp->re[x] = &fp->red[x]; + if (regcomp(fp->re[x], f.next, REG_DELIMITED|REG_NULL)) + break; + f.next += fp->re[x]->re_npat; + if (regsubcomp(fp->re[x], f.next, NiL, 0, 0)) + break; + f.next += fp->re[x]->re_npat; + if (!regexec(fp->re[x], s, elementsof(match), match, 0) && !regsubexec(fp->re[x], s, elementsof(match), match)) + { + s = fp->re[x]->re_sub->re_buf; + if (fp->re[x]->re_sub->re_flags & REG_SUB_STOP) + break; + } + } + h = 1; + break; + } + if (!h) + s = ""; + } + value->s = s; + if (fp->level == 1) + while ((s = strchr(s, CC_esc)) && *(s + 1) == '[') + do fp->invisible++; while (*s && !islower(*s++)); + break; + case 'Z': + fp->fmt.fmt = 'c'; + value->c = 0; + break; + case '\n': + value->s = "\n"; + break; + case '.': + value->i = n; + break; + default: + if ((!fp->convert || !(value->s = (*fp->convert)(fp->handle, &fp->fmt, a, s, n))) && (!fp->tmp[0] && !(fp->tmp[0] = sfstropen()) || sfprintf(fp->tmp[0], "%%%c", fp->fmt.fmt) <= 0 || !(value->s = sfstruse(fp->tmp[0])))) + value->s = ""; + break; + } + fp->level--; + return 0; +} + +/* + * this is the original interface + */ + +int +sfkeyprintf(Sfio_t* sp, void* handle, const char* format, Sf_key_lookup_t lookup, Sf_key_convert_t convert) +{ + register int i; + int r; + Fmt_t fmt; + + memset(&fmt, 0, sizeof(fmt)); + fmt.fmt.version = SFIO_VERSION; + fmt.fmt.form = (char*)format; + fmt.fmt.extf = getfmt; + fmt.handle = handle; + fmt.lookup = lookup; + fmt.convert = convert; + r = sfprintf(sp, "%!", &fmt) - fmt.invisible; + for (i = 0; i < elementsof(fmt.tmp); i++) + if (fmt.tmp[i]) + sfclose(fmt.tmp[i]); + for (i = 0; i < elementsof(fmt.re); i++) + if (fmt.re[i]) + regfree(fmt.re[i]); + return r; +} + +#undef _AST_API_H + +#include <ast_api.h> + +/* + * Sffmt_t* callback args + */ + +int +sfkeyprintf_20000308(Sfio_t* sp, void* handle, const char* format, Sf_key_lookup_t lookup, Sf_key_convert_t convert) +{ + register int i; + int r; + Fmt_t fmt; + + memset(&fmt, 0, sizeof(fmt)); + fmt.version = 20030909; + fmt.fmt.version = SFIO_VERSION; + fmt.fmt.form = (char*)format; + fmt.fmt.extf = getfmt; + fmt.handle = handle; + fmt.lookup = lookup; + fmt.convert = convert; + r = sfprintf(sp, "%!", &fmt) - fmt.invisible; + for (i = 0; i < elementsof(fmt.tmp); i++) + if (fmt.tmp[i]) + sfclose(fmt.tmp[i]); + return r; +} diff --git a/src/lib/libast/disc/sfstrtmp.c b/src/lib/libast/disc/sfstrtmp.c new file mode 100644 index 0000000..beed91b --- /dev/null +++ b/src/lib/libast/disc/sfstrtmp.c @@ -0,0 +1,62 @@ +/*********************************************************************** +* * +* 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> * +* * +***********************************************************************/ +#pragma prototyped +/* + * Glenn Fowler + * AT&T Research + * + * sfio tmp string buffer support + */ + +#include <sfio_t.h> +#include <ast.h> + +#if __OBSOLETE__ >= 20070101 /* sfstr* macros now use sfsetbuf() */ + +NoN(sfstrtmp) + +#else + +#if defined(__EXPORT__) +#define extern __EXPORT__ +#endif + +/* + * replace buffer in string stream f for either SF_READ or SF_WRITE + */ + +extern int +sfstrtmp(register Sfio_t* f, int mode, void* buf, size_t siz) +{ + if (!(f->_flags & SF_STRING)) + return -1; + if (f->_flags & SF_MALLOC) + free(f->_data); + f->_flags &= ~(SF_ERROR|SF_MALLOC); + f->mode = mode; + f->_next = f->_data = (unsigned char*)buf; + f->_endw = f->_endr = f->_endb = f->_data + siz; + f->_size = siz; + return 0; +} + +#endif |