| #include "a.h" |
| |
| /* |
| * 19. Input/output file switching. |
| */ |
| |
| /* .so - push new source file */ |
| void |
| r_so(int argc, Rune **argv) |
| { |
| USED(argc); |
| pushinputfile(erunesmprint("%s", unsharp(esmprint("%S", argv[1])))); |
| } |
| |
| /* .nx - end this file, switch to arg */ |
| void |
| r_nx(int argc, Rune **argv) |
| { |
| int n; |
| |
| if(argc == 1){ |
| while(popinput()) |
| ; |
| }else{ |
| if(argc > 2) |
| warn("too many arguments for .nx"); |
| while((n=popinput()) && n != 2) |
| ; |
| pushinputfile(argv[1]); |
| } |
| } |
| |
| /* .sy - system: run string */ |
| void |
| r_sy(Rune *name) |
| { |
| USED(name); |
| warn(".sy not implemented"); |
| } |
| |
| /* .pi - pipe output to string */ |
| void |
| r_pi(Rune *name) |
| { |
| USED(name); |
| warn(".pi not implemented"); |
| } |
| |
| /* .cf - copy contents of filename to output */ |
| void |
| r_cf(int argc, Rune **argv) |
| { |
| int c; |
| char *p; |
| Biobuf *b; |
| |
| USED(argc); |
| p = esmprint("%S", argv[1]); |
| if((b = Bopen(p, OREAD)) == nil){ |
| fprint(2, "%L: open %s: %r\n", p); |
| free(p); |
| return; |
| } |
| free(p); |
| |
| while((c = Bgetrune(b)) >= 0) |
| outrune(c); |
| Bterm(b); |
| } |
| |
| void |
| r_inputpipe(Rune *name) |
| { |
| Rune *cmd, *stop, *line; |
| int n, pid, p[2], len; |
| Waitmsg *w; |
| |
| USED(name); |
| if(pipe(p) < 0){ |
| warn("pipe: %r"); |
| return; |
| } |
| stop = copyarg(); |
| cmd = readline(CopyMode); |
| pid = fork(); |
| switch(pid){ |
| case 0: |
| if(p[0] != 0){ |
| dup(p[0], 0); |
| close(p[0]); |
| } |
| close(p[1]); |
| execl(unsharp("#9/bin/rc"), "rc", "-c", esmprint("%S", cmd), nil); |
| warn("%Cdp %S: %r", dot, cmd); |
| _exits(nil); |
| case -1: |
| warn("fork: %r"); |
| default: |
| close(p[0]); |
| len = runestrlen(stop); |
| fprint(p[1], ".ps %d\n", getnr(L(".s"))); |
| fprint(p[1], ".vs %du\n", getnr(L(".v"))); |
| fprint(p[1], ".ft %d\n", getnr(L(".f"))); |
| fprint(p[1], ".ll 8i\n"); |
| fprint(p[1], ".pl 30i\n"); |
| while((line = readline(~0)) != nil){ |
| if(runestrncmp(line, stop, len) == 0 |
| && (line[len]==' ' || line[len]==0 || line[len]=='\t' |
| || (line[len]=='\\' && line[len+1]=='}'))) |
| break; |
| n = runestrlen(line); |
| line[n] = '\n'; |
| fprint(p[1], "%.*S", n+1, line); |
| free(line); |
| } |
| free(stop); |
| close(p[1]); |
| w = wait(); |
| if(w == nil){ |
| warn("wait: %r"); |
| return; |
| } |
| if(w->msg[0]) |
| sysfatal("%C%S %S: %s", dot, name, cmd, w->msg); |
| free(cmd); |
| free(w); |
| } |
| } |
| |
| void |
| t19init(void) |
| { |
| addreq(L("so"), r_so, 1); |
| addreq(L("nx"), r_nx, -1); |
| addraw(L("sy"), r_sy); |
| addraw(L("inputpipe"), r_inputpipe); |
| addraw(L("pi"), r_pi); |
| addreq(L("cf"), r_cf, 1); |
| |
| nr(L("$$"), getpid()); |
| } |
| |