aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/rc/io.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cmd/rc/io.c')
-rw-r--r--sys/cmd/rc/io.c573
1 files changed, 195 insertions, 378 deletions
diff --git a/sys/cmd/rc/io.c b/sys/cmd/rc/io.c
index e06bfcc..3e17369 100644
--- a/sys/cmd/rc/io.c
+++ b/sys/cmd/rc/io.c
@@ -1,446 +1,263 @@
+#include <limits.h>
#include "rc.h"
+#include "exec.h"
+#include "io.h"
+#include "fns.h"
-#define c0 t->child[0]
-#define c1 t->child[1]
-#define c2 t->child[2]
+io *err;
+int pfmtnest = 0;
-#undef bufsize
-#define bufsize 512
-#define strsize 100
-
-//------------------------------------------------------------------------
-// buffer operations
-
-/* open file */
-Io*
-openfd(int fd)
+void
+pfmt(io *f, char *fmt, ...)
{
- Io *f;
-
- f = emalloc(sizeof *f + bufsize);
- f->fd = fd;
- f->b = f->e = f->buf;
- return f;
+ va_list ap;
+ char err[ERRMAX];
+ va_start(ap, fmt);
+ pfmtnest++;
+ for(;*fmt;fmt++)
+ if(*fmt!='%')
+ pchr(f, *fmt);
+ else switch(*++fmt){
+ case '\0':
+ va_end(ap);
+ return;
+ 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 'r':
+ rerrstr(err, sizeof err); pstr(f, err);
+ break;
+ case 's':
+ pstr(f, va_arg(ap, char *));
+ break;
+ case 't':
+ pcmd(f, va_arg(ap, struct tree *));
+ break;
+ case 'v':
+ pval(f, va_arg(ap, struct word *));
+ break;
+ default:
+ pchr(f, *fmt);
+ break;
+ }
+ va_end(ap);
+ if(--pfmtnest==0)
+ flush(f);
}
-/* open string */
-Io*
-openstr(void)
+void
+pchr(io *b, int c)
{
- Io *f;
-
- f = emalloc(sizeof *f + strsize + 1);
- f->fd = -1;
- f->b = f->buf;
- f->e = f->buf+strsize;
- memset(f->b, 0, strsize+1);
-
- return f;
+ if(b->bufp==b->ebuf)
+ fullbuf(b, c);
+ else *b->bufp++=c;
}
-/* open core (not nil terminated) */
-Io*
-opencore(int len, char *s)
+int
+rchr(io *b)
{
- Io *f;
-
- f = emalloc(sizeof *f + len);
- f->fd = -1;
- f->b = f->buf;
- f->e = f->buf+len;
- memcpy(f->b, s, len);
-
- return f;
+ if(b->bufp==b->ebuf)
+ return emptybuf(b);
+ return *b->bufp++ & 0xFF;
}
void
-rewindio(Io *f)
+pquo(io *f, char *s)
{
- if (f->fd < 0)
- f->b = f->buf;
- else {
- f->b = f->e = f->buf;
- lseek(f->fd, 0, 0);
- }
+ pchr(f, '\'');
+ for(;*s;s++)
+ if(*s=='\'')
+ pfmt(f, "''");
+ else pchr(f, *s);
+ pchr(f, '\'');
}
void
-closeio(Io *f)
+pwrd(io *f, char *s)
{
- if (f->fd >= 0)
- close(f->fd);
-
- efree(f);
+ char *t;
+ for(t = s;*t;t++) if(!wordchr(*t)) break;
+ if(t==s || *t)
+ pquo(f, s);
+ else pstr(f, s);
}
-/* has the chance to realloc */
void
-flush(Io **fp)
+pptr(io *f, void *v)
{
- int n;
- char *s;
- Io *f;
+ int n;
+ uintptr p;
- f = *fp;
- if (f->fd < 0) {
- n = f->e - f->b;
- f = erealloc(f, sizeof *f + n + strsize + 1);
- if (!f)
- panic("can't realloc %d bytes in flush", n+strsize+1);
- f->b = f->buf+n;
- f->e = f->buf+n+strsize;
- memset(f->b, 0, strsize+1);
- } else {
- n = f->b - f->buf;
- if (n && write(f->fd, f->buf, n) < 0) {
- write(3, "write error\n", 12);
- // if (ntrap)
- // dotrap();
- }
- f->b = f->buf;
- f->e = f->buf + bufsize;
- }
+ p = (uintptr)v;
+ if(sizeof(uintptr) == sizeof(uvlong) && p>>32)
+ for(n = 60;n>=32;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
- *fp = f;
+ for(n = 28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
}
-//------------------------------------------------------------------------
-// read from io
-
-int
-rchr(Io *f)
-{
- int n;
- if (f->b == f->e) {
- if (f->fd < 0 || (n = read(f->fd, f->buf, bufsize)) <= 0)
- return EOF;
-
- f->b = f->buf;
- f->e = f->b + n;
- }
-
- return *f->b++&0xFF;
-}
-
-//------------------------------------------------------------------------
-// printf functionality
-
-/* character literal */
-int
-pchr(Io *f, int c)
+void
+pstr(io *f, char *s)
{
- if (f->b == f->e)
- flush(&f);
-
- return *f->b++=c;
+ if(s==0)
+ s="(null)";
+ while(*s) pchr(f, *s++);
}
-/* quote */
void
-pquo(Io *f, char *s)
+pdec(io *f, int n)
{
- pchr(f, '\'');
- for (; *s; s++)
- if (*s == '\'')
- pfmt(f, "''");
- else
- pchr(f, *s);
- pchr(f, '\'');
+ if(n<0){
+ if(n!=INT_MIN){
+ pchr(f, '-');
+ pdec(f, -n);
+ return;
+ }
+ /* n is two's complement minimum integer */
+ n = -(INT_MIN+1);
+ pchr(f, '-');
+ pdec(f, n/10);
+ pchr(f, n%10+'1');
+ return;
+ }
+ if(n>9)
+ pdec(f, n/10);
+ pchr(f, n%10+'0');
}
-/* word */
void
-pwrd(Io *f, char *s)
+poct(io *f, unsigned n)
{
- char *t;
- for(t = s; *t; t++)
- if(!wordchr(*t))
- break;
- if(t == s || *t)
- pquo(f, s);
- else
- pstr(f, s);
+ if(n>7)
+ poct(f, n>>3);
+ pchr(f, (n&7)+'0');
}
-/* pointer */
void
-pptr(Io *f, void *v)
+pval(io *f, word *a)
{
- int n;
- uintptr p;
-
- if (!v) {
- pstr(f, "<nil>");
- return;
- }
-
- p = (uintptr)v;
- if ((sizeof(uintptr) == sizeof(uvlong)) && p >>32)
- for (n = 60; n >= 32; n-=4)
- pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
- for (n = 28; n >= 0; n-=4)
- pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
+ if(a){
+ while(a->next && a->next->word){
+ pwrd(f, a->word);
+ pchr(f, ' ');
+ a = a->next;
+ }
+ pwrd(f, a->word);
+ }
}
-/* string */
-void
-pstr(Io *f, char *s)
+int
+fullbuf(io *f, int c)
{
- if(!s || !s[0])
- s = "<null>";
-
- while(*s)
- pchr(f, *s++);
+ flush(f);
+ return *f->bufp++=c;
}
-/* decimal */
void
-pdec(Io *f, int n)
+flush(io *f)
{
- if (n < 0) {
- n = -n;
- pchr(f, '-');
- if (n >= 0) {
- pdec(f, n);
- return;
- }
- n = 1 - n;
- pdec(f, n/10);
- pchr(f, n%10+'1');
- return;
- }
-
- if (n > 9)
- pdec(f, n/10);
- pchr(f, n%10+'0');
+ int n;
+ char *s;
+ if(f->strp){
+ n = f->ebuf-f->strp;
+ f->strp = realloc(f->strp, n+101);
+ if(f->strp==0)
+ panic("Can't realloc %d bytes in flush!", n+101);
+ f->bufp = f->strp+n;
+ f->ebuf = f->bufp+100;
+ for(s = f->bufp;s<=f->ebuf;s++) *s='\0';
+ }
+ else{
+ n = f->bufp-f->buf;
+ if(n && Write(f->fd, f->buf, n) < 0){
+ Write(3, "Write error\n", 12);
+ if(ntrap)
+ dotrap();
+ }
+ f->bufp = f->buf;
+ f->ebuf = f->buf+NBUF;
+ }
}
-/* octal */
-void
-poct(Io *f, uint n)
+io*
+openfd(int fd)
{
- if (n > 7)
- poct(f, n>>3);
- pchr(f, (n&7)+'0');
+ io *f = new(struct io);
+ f->fd = fd;
+ f->bufp = f->ebuf = f->buf;
+ f->strp = 0;
+ return f;
}
-/* value */
-void
-pval(Io *f, Word *a)
+io*
+openstr(void)
{
- if(a) {
- while(a->link && a->link->word) {
- pwrd(f, a->word);
- pchr(f, ' ');
- a = a->link;
- }
- pwrd(f, a->word);
- }
+ io *f = new(struct io);
+ char *s;
+ f->fd=-1;
+ f->bufp = f->strp = emalloc(101);
+ f->ebuf = f->bufp+100;
+ for(s = f->bufp;s<=f->ebuf;s++) *s='\0';
+ return f;
}
+/*
+ * Open a corebuffer to read. EOF occurs after reading len
+ * characters from buf.
+ */
-/* tree */
-static
-void
-pdeglob(Io *f, char *s)
+io*
+opencore(char *s, int len)
{
- while(*s){
- if(*s==GLOB)
- s++;
- pchr(f, *s++);
- }
+ io *f = new(struct io);
+ char *buf = emalloc(len);
+ f->fd= -1 /*open("/dev/null", 0)*/;
+ f->bufp = f->strp = buf;
+ f->ebuf = buf+len;
+ Memcpy(buf, s, len);
+ return f;
}
void
-pcmd(Io *f, Tree *t)
+iorewind(io *io)
{
- if(!t)
- return;
-
- switch(t->type){
- default: pfmt(f, "bad<%d> %p %p %p", t->type, c0, c1, c2);
- break;
- case Tdol: pfmt(f, "$%t", c0);
- break;
- case Tquote: pfmt(f, "$\"%t", c0);
- break;
- case Tand: pfmt(f, "%t&", c0);
- break;
- case Tcarot: pfmt(f, "%t^%t", c0, c1);
- break;
- case Ttick: pfmt(f, "`%t", c0);
- break;
- case Tandand: pfmt(f, "%t && %t", c0, c1);
- break;
- case Tbang: pfmt(f, "! %t", c0);
- break;
- case Tbrace: pfmt(f, "{%t}", c0);
- break;
- case Tcount: pfmt(f, "$#%t", c0);
- break;
- case Tfunc: pfmt(f, "func %t %t", c0, c1);
- break;
- case Tif: (c2) ? pfmt(f, "if%t%t else %t", c0, c1, c2): pfmt(f, "if%t%t", c0, c1);
- break;
- case Toror: pfmt(f, "%t || %t", c0, c1);
- break;
- case Tpcmd: /* fallthrough */
- case Tparen: pfmt(f, "(%t)", c0);
- break;
- case Tsub: pfmt(f, "$%t(%t)", c0, c1);
- break;
- case Tsimple: pfmt(f, "%t", c0);
- break;
- case Tsubshell: pfmt(f, "@ %t", c0);
- break;
- case Tswitch: pfmt(f, "switch %t %t", c0, c1);
- break;
- case Tcase: pfmt(f, "case %t:\n%t", c0, c1);
- break;
- case Ttwiddle: pfmt(f, "~ %t %t", c0, c1);
- break;
- case Twhile: pfmt(f, "while %t%t", c0, c1);
- break;
- case Targs:
- if(c0==0)
- pfmt(f, "%t", c1);
- else if(c1==0)
- pfmt(f, "%t", c0);
- else
- pfmt(f, "%t %t", c0, c1);
- break;
- case Tsemi:
- if(c0) {
- if(c1)
- pfmt(f, "%t%c%t", c0, '\n', c1);
- else
- pfmt(f, "%t", c0);
- } else
- pfmt(f, "%t", c1);
- break;
- case Twords:
- if(c0)
- pfmt(f, "%t ", c0);
- pfmt(f, "%t", c1);
- break;
- case Tfor:
- pfmt(f, "for(%t", c0);
- if(c1)
- pfmt(f, " in %t", c1);
- pfmt(f, ")%t", c2);
- break;
- case Tword:
- if(t->quoted)
- pfmt(f, "%Q", t->str);
- else
- pdeglob(f, t->str);
- break;
- case Tdup:
- if(t->redir.type==Rdupfd)
- pfmt(f, ">[%d=%d]", t->redir.fd[1], t->redir.fd[0]); /* yes, fd1, then fd0; read lex.c */
- else
- pfmt(f, ">[%d=]", t->redir.fd[0]);
- pfmt(f, "%t", c1);
- break;
- case Tpipefd:
- case Tredir:
- switch(t->redir.type){
- case Rhere:
- pchr(f, '<');
- case Rread:
- case Rrdwr:
- pchr(f, '<');
- if(t->redir.type==Rrdwr)
- pchr(f, '>');
- if(t->redir.fd[0]!=0)
- pfmt(f, "[%d]", t->redir.fd[0]);
- break;
- case Rappend:
- pchr(f, '>');
- case Rwrite:
- pchr(f, '>');
- if(t->redir.fd[0]!=1)
- pfmt(f, "[%d]", t->redir.fd[0]);
- break;
- }
- pfmt(f, "%t", c0);
- if(c1)
- pfmt(f, " %t", c1);
- break;
- case Teq:
- pfmt(f, "%t=%t", c0, c1);
- if(c2)
- pfmt(f, " %t", c2);
- break;
- case Tpipe:
- pfmt(f, "%t|", c0);
- if(t->redir.fd[1]==0){
- if(t->redir.fd[0]!=1)
- pfmt(f, "[%d]", t->redir.fd[0]);
- }
- else pfmt(f, "[%d=%d]", t->redir.fd[0], t->redir.fd[1]);
- pfmt(f, "%t", c1);
- break;
+ if(io->fd==-1)
+ io->bufp = io->strp;
+ else{
+ io->bufp = io->ebuf = io->buf;
+ Seek(io->fd, 0L, 0);
}
}
-/* rc specific printf */
-static int pfmtlev;
-
void
-vpfmt(Io *f, char *fmt, va_list args)
+closeio(io *io)
{
- char err[124];
-
- pfmtlev++;
- for (; *fmt; fmt++)
- if (*fmt!='%')
- pchr(f, *fmt);
- else switch(*++fmt) {
- case '\0':
- break;
- case 'c':
- pchr(f, va_arg(args, int));
- break;
- case 'd':
- pdec(f, va_arg(args, int));
- break;
- case 'o':
- poct(f, va_arg(args, uint));
- break;
- case 'p':
- pptr(f, va_arg(args, void*));
- break;
- case 'Q':
- pquo(f, va_arg(args, char*));
- break;
- case 'q':
- pwrd(f, va_arg(args, char*));
- break;
- case 'r':
- pstr(f, strerror(errno));
- break;
- case 's':
- pstr(f, va_arg(args, char*));
- break;
- case 't':
- pcmd(f, va_arg(args, Tree*));
- break;
- case 'v':
- pval(f, va_arg(args, Word*));
- break;
- }
-
- if (--pfmtlev==0)
- flush(&f);
+ if(io->fd>=0)
+ close(io->fd);
+ if(io->strp)
+ efree(io->strp);
+ efree((char *)io);
}
-void
-pfmt(Io *f, char *fmt, ...)
+int
+emptybuf(io *f)
{
- va_list args;
- char err[124];
-
- va_start(args, fmt);
- vpfmt(f, fmt, args);
- va_end(args);
+ int n;
+ if(f->fd==-1 || (n = Read(f->fd, f->buf, NBUF))<=0) return EOF;
+ f->bufp = f->buf;
+ f->ebuf = f->buf+n;
+ return *f->bufp++&0xff;
}