xref: /plan9/sys/src/cmd/htmlroff/t19.c (revision 426d2b71458df9b491ba6c167f699b3f1f7b0428)
1 #include "a.h"
2 
3 /*
4  * 19. Input/output file switching.
5  */
6 
7 /* .so - push new source file */
8 void
r_so(int argc,Rune ** argv)9 r_so(int argc, Rune **argv)
10 {
11 	USED(argc);
12 	pushinputfile(argv[1]);
13 }
14 
15 /* .nx - end this file, switch to arg */
16 void
r_nx(int argc,Rune ** argv)17 r_nx(int argc, Rune **argv)
18 {
19 	int n;
20 
21 	if(argc == 1){
22 		while(popinput())
23 			;
24 	}else{
25 		if(argc > 2)
26 			warn("too many arguments for .nx");
27 		while((n=popinput()) && n != 2)
28 			;
29 		pushinputfile(argv[1]);
30 	}
31 }
32 
33 /* .sy - system: run string */
34 void
r_sy(Rune * name)35 r_sy(Rune *name)
36 {
37 	USED(name);
38 	warn(".sy not implemented");
39 }
40 
41 /* .pi - pipe output to string */
42 void
r_pi(Rune * name)43 r_pi(Rune *name)
44 {
45 	USED(name);
46 	warn(".pi not implemented");
47 }
48 
49 /* .cf - copy contents of filename to output */
50 void
r_cf(int argc,Rune ** argv)51 r_cf(int argc, Rune **argv)
52 {
53 	int c;
54 	char *p;
55 	Biobuf *b;
56 
57 	USED(argc);
58 	p = esmprint("%S", argv[1]);
59 	if((b = Bopen(p, OREAD)) == nil){
60 		fprint(2, "%L: open %s: %r\n", p);
61 		free(p);
62 		return;
63 	}
64 	free(p);
65 
66 	while((c = Bgetrune(b)) >= 0)
67 		outrune(c);
68 	Bterm(b);
69 }
70 
71 void
r_inputpipe(Rune * name)72 r_inputpipe(Rune *name)
73 {
74 	Rune *cmd, *stop, *line;
75 	int n, pid, p[2], len;
76 	Waitmsg *w;
77 
78 	USED(name);
79 	if(pipe(p) < 0){
80 		warn("pipe: %r");
81 		return;
82 	}
83 	stop = copyarg();
84 	cmd = readline(CopyMode);
85 	pid = fork();
86 	switch(pid){
87 	case 0:
88 		if(p[0] != 0){
89 			dup(p[0], 0);
90 			close(p[0]);
91 		}
92 		close(p[1]);
93 		execl("/bin/rc", "rc", "-c", esmprint("%S", cmd), nil);
94 		warn("%Cdp %S: %r", dot, cmd);
95 		_exits(nil);
96 	case -1:
97 		warn("fork: %r");
98 	default:
99 		close(p[0]);
100 		len = runestrlen(stop);
101 		fprint(p[1], ".ps %d\n", getnr(L(".s")));
102 		fprint(p[1], ".vs %du\n", getnr(L(".v")));
103 		fprint(p[1], ".ft %d\n", getnr(L(".f")));
104 		fprint(p[1], ".ll 8i\n");
105 		fprint(p[1], ".pl 30i\n");
106 		while((line = readline(~0)) != nil){
107 			if(runestrncmp(line, stop, len) == 0
108 			&& (line[len]==' ' || line[len]==0 || line[len]=='\t'
109 				|| (line[len]=='\\' && line[len+1]=='}')))
110 				break;
111 			n = runestrlen(line);
112 			line[n] = '\n';
113 			fprint(p[1], "%.*S", n+1, line);
114 			free(line);
115 		}
116 		free(stop);
117 		close(p[1]);
118 		w = wait();
119 		if(w == nil){
120 			warn("wait: %r");
121 			return;
122 		}
123 		if(w->msg[0])
124 			sysfatal("%C%S %S: %s", dot, name, cmd, w->msg);
125 		free(cmd);
126 		free(w);
127 	}
128 }
129 
130 void
t19init(void)131 t19init(void)
132 {
133 	addreq(L("so"), r_so, 1);
134 	addreq(L("nx"), r_nx, -1);
135 	addraw(L("sy"), r_sy);
136 	addraw(L("inputpipe"), r_inputpipe);
137 	addraw(L("pi"), r_pi);
138 	addreq(L("cf"), r_cf, 1);
139 
140 	nr(L("$$"), getpid());
141 }
142 
143