ref: 8e18df2cbaae08f7075076572f26f80a296701c1
dir: /sys/src/cmd/rc/io.c/
#include "rc.h"
#include "exec.h"
#include "io.h"
#include "fns.h"
enum {
NBUF = 8192,
};
void
vpfmt(io *f, char *fmt, va_list ap)
{
for(;*fmt;fmt++) {
if(*fmt!='%') {
pchr(f, *fmt);
continue;
}
if(*++fmt == '\0') /* "blah%"? */
break;
switch(*fmt){
case 'c':
pchr(f, va_arg(ap, int));
break;
case 'd':
pdec(f, va_arg(ap, int));
break;
case 'o':
poct(f, va_arg(ap, unsigned));
break;
case 'p':
pptr(f, va_arg(ap, void*));
break;
case 'Q':
pquo(f, va_arg(ap, char *));
break;
case 'q':
pwrd(f, va_arg(ap, char *));
break;
case 's':
pstr(f, va_arg(ap, char *));
break;
case 't':
pcmd(f, va_arg(ap, tree *));
break;
case 'v':
pval(f, va_arg(ap, word *));
break;
default:
pchr(f, *fmt);
break;
}
}
}
void
pfmt(io *f, char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vpfmt(f, fmt, ap);
va_end(ap);
}
void
pchr(io *b, int c)
{
if(b->bufp>=b->ebuf)
flushio(b);
*b->bufp++=c;
}
int
rchr(io *b)
{
if(b->bufp>=b->ebuf)
return emptyiobuf(b);
return *b->bufp++;
}
char*
rstr(io *b, char *stop)
{
char *s, *p;
int l, m, n;
do {
l = rchr(b);
if(l == EOF)
return 0;
} while(l && strchr(stop, l));
b->bufp--;
s = 0;
l = 0;
for(;;){
p = (char*)b->bufp;
n = (char*)b->ebuf - p;
if(n > 0){
for(m = 0; m < n; m++){
if(strchr(stop, p[m])==0)
continue;
b->bufp += m+1;
if(m > 0 || s==0){
s = erealloc(s, l+m+1);
memmove(s+l, p, m);
l += m;
}
s[l]='\0';
return s;
}
s = erealloc(s, l+m+1);
memmove(s+l, p, m);
l += m;
b->bufp += m;
}
if(emptyiobuf(b) == EOF){
if(s) s[l]='\0';
return s;
}
b->bufp--;
}
}
void
pquo(io *f, char *s)
{
pchr(f, '\'');
for(;*s;s++){
if(*s=='\'')
pchr(f, *s);
pchr(f, *s);
}
pchr(f, '\'');
}
void
pwrd(io *f, char *s)
{
char *t;
for(t = s;*t;t++) if(*t >= 0 && (*t <= ' ' || strchr("`^#*[]=|\\?${}()'<>&;", *t))) break;
if(t==s || *t)
pquo(f, s);
else pstr(f, s);
}
void
pptr(io *f, void *p)
{
static char hex[] = "0123456789ABCDEF";
unsigned long long v;
int n;
v = (unsigned long long)p;
if(sizeof(v) == sizeof(p) && v>>32)
for(n = 60;n>=32;n-=4) pchr(f, hex[(v>>n)&0xF]);
for(n = 28;n>=0;n-=4) pchr(f, hex[(v>>n)&0xF]);
}
void
pstr(io *f, char *s)
{
if(s==0)
s="(null)";
while(*s) pchr(f, *s++);
}
void
pdec(io *f, int n)
{
if(n<0){
n=-n;
if(n>=0){
pchr(f, '-');
pdec(f, n);
return;
}
/* n is two's complement minimum integer */
n = 1-n;
pchr(f, '-');
pdec(f, n/10);
pchr(f, n%10+'1');
return;
}
if(n>9)
pdec(f, n/10);
pchr(f, n%10+'0');
}
void
poct(io *f, unsigned n)
{
if(n>7)
poct(f, n>>3);
pchr(f, (n&7)+'0');
}
void
pval(io *f, word *a)
{
if(a==0)
return;
while(a->next && a->next->word){
pwrd(f, (char *)a->word);
pchr(f, ' ');
a = a->next;
}
pwrd(f, (char *)a->word);
}
io*
newio(unsigned char *buf, int len, int fd)
{
io *f = new(io);
f->buf = buf;
f->bufp = buf;
f->ebuf = buf+len;
f->fd = fd;
return f;
}
/*
* Open a string buffer for writing.
*/
io*
openiostr(void)
{
unsigned char *buf = emalloc(100+1);
memset(buf, '\0', 100+1);
return newio(buf, 100, -1);
}
/*
* Return the buf, free the io
*/
char*
closeiostr(io *f)
{
void *buf = f->buf;
free(f);
return buf;
}
/*
* Use a open file descriptor for reading.
*/
io*
openiofd(int fd)
{
return newio(emalloc(NBUF), 0, fd);
}
/*
* Open a corebuffer to read. EOF occurs after reading len
* characters from buf.
*/
io*
openiocore(void *buf, int len)
{
return newio(buf, len, -1);
}
void
flushio(io *f)
{
int n;
if(f->fd<0){
n = f->ebuf - f->buf;
f->buf = erealloc(f->buf, n+n+1);
f->bufp = f->buf + n;
f->ebuf = f->bufp + n;
memset(f->bufp, '\0', n+1);
}
else{
n = f->bufp - f->buf;
if(n && Write(f->fd, f->buf, n) != n){
if(ntrap)
dotrap();
}
f->bufp = f->buf;
f->ebuf = f->buf+NBUF;
}
}
void
closeio(io *f)
{
if(f->fd>=0) Close(f->fd);
free(closeiostr(f));
}
int
emptyiobuf(io *f)
{
int n;
if(f->fd<0 || (n = Read(f->fd, f->buf, NBUF))<=0) return EOF;
f->bufp = f->buf;
f->ebuf = f->buf + n;
return *f->bufp++;
}