Plan 9's rc.
not a clear win over byron's, but at least it has the right syntax.
This commit is contained in:
parent
5993a8f275
commit
f08fdedcee
24 changed files with 4688 additions and 0 deletions
179
src/cmd/rc/io.c
Normal file
179
src/cmd/rc/io.c
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
#include "rc.h"
|
||||
#include "exec.h"
|
||||
#include "io.h"
|
||||
#include "fns.h"
|
||||
int pfmtnest=0;
|
||||
void pfmt(io *f, char *fmt, ...){
|
||||
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': phex(f, (long)va_arg(ap, char *)); break; /*unportable*/
|
||||
case 'Q': pquo(f, va_arg(ap, char *)); break;
|
||||
case 'q': pwrd(f, va_arg(ap, char *)); break;
|
||||
case 'r': errstr(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);
|
||||
}
|
||||
void pchr(io *b, int c)
|
||||
{
|
||||
if(b->bufp==b->ebuf) fullbuf(b, c);
|
||||
else *b->bufp++=c;
|
||||
}
|
||||
int rchr(io *b)
|
||||
{
|
||||
if(b->bufp==b->ebuf) return emptybuf(b);
|
||||
return *b->bufp++ & 0xFF;
|
||||
}
|
||||
|
||||
void pquo(io *f, char *s)
|
||||
{
|
||||
pchr(f, '\'');
|
||||
for(;*s;s++)
|
||||
if(*s=='\'') pfmt(f, "''");
|
||||
else pchr(f, *s);
|
||||
pchr(f, '\'');
|
||||
}
|
||||
void pwrd(io *f, char *s)
|
||||
{
|
||||
char *t;
|
||||
for(t=s;*t;t++) if(!wordchr(*t)) break;
|
||||
if(t==s || *t) pquo(f, s);
|
||||
else pstr(f, s);
|
||||
}
|
||||
void phex(io *f, long p)
|
||||
{
|
||||
int n;
|
||||
for(n=28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]);
|
||||
}
|
||||
void pstr(io *f, char *s)
|
||||
{
|
||||
if(s==0) s="(null)";
|
||||
while(*s) pchr(f, *s++);
|
||||
}
|
||||
void pdec(io *f, long 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, ulong n)
|
||||
{
|
||||
if(n>7) poct(f, n>>3);
|
||||
pchr(f, (n&7)+'0');
|
||||
}
|
||||
void pval(io *f, word *a)
|
||||
{
|
||||
if(a){
|
||||
while(a->next && a->next->word){
|
||||
pwrd(f, a->word);
|
||||
pchr(f, ' ');
|
||||
a=a->next;
|
||||
}
|
||||
pwrd(f, a->word);
|
||||
}
|
||||
}
|
||||
int fullbuf(io *f, int c)
|
||||
{
|
||||
flush(f);
|
||||
return *f->bufp++=c;
|
||||
}
|
||||
void flush(io *f)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
io *openfd(int fd){
|
||||
io *f=new(struct io);
|
||||
f->fd=fd;
|
||||
f->bufp=f->ebuf=f->buf;
|
||||
f->strp=0;
|
||||
return f;
|
||||
}
|
||||
io *openstr(void){
|
||||
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.
|
||||
*/
|
||||
io *opencore(char *s, int len)
|
||||
{
|
||||
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 rewind(io *io)
|
||||
{
|
||||
if(io->fd==-1) io->bufp=io->strp;
|
||||
else{
|
||||
io->bufp=io->ebuf=io->buf;
|
||||
Seek(io->fd, 0L, 0);
|
||||
}
|
||||
}
|
||||
void closeio(io *io)
|
||||
{
|
||||
if(io->fd>=0) close(io->fd);
|
||||
if(io->strp) efree(io->strp);
|
||||
efree((char *)io);
|
||||
}
|
||||
int emptybuf(io *f)
|
||||
{
|
||||
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;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue