Xinqi Bao's Git
1 /* See LICENSE file for copyright and license details. */
7 #if !(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600)
17 #define LENGTH(x) (sizeof(x) / sizeof((x)[0]))
18 #define MAX(a,b) (((a) > (b)) ? (a) : (b))
19 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
22 unsigned char data
[BUFSIZ
];
28 unsigned char data
[BUFSIZ
];
33 static void buffer(char c
);
34 static void cmd(const char *cmdstr
, ...);
35 static int getch(ReadBuffer
*buf
);
36 static void getpty(void);
37 static void movea(int x
, int y
);
38 static void mover(int x
, int y
);
39 static void parsecmd(void);
40 static void parseesc(void);
41 static void scroll(int l
);
42 static void shell(void);
43 static void sigchld(int n
);
44 static char unbuffer(void);
45 static void ungetch(ReadBuffer
*buf
, int c
);
47 static int cols
= 80, lines
= 25;
48 static int cx
= 0, cy
= 0;
51 static _Bool bold
, digit
, qmark
;
53 static RingBuffer buf
;
54 static ReadBuffer cmdbuf
, ptmbuf
;
58 if(buf
.n
< LENGTH(buf
.data
))
61 buf
.s
= (buf
.s
+ 1) % LENGTH(buf
.data
);
62 buf
.data
[buf
.e
++] = c
;
63 buf
.e
%= LENGTH(buf
.data
);
67 cmd(const char *cmdstr
, ...) {
73 vfprintf(stdout
, cmdstr
, ap
);
78 getch(ReadBuffer
*buf
) {
79 if(buf
->i
++ >= buf
->n
) {
80 buf
->n
= read(buf
->fd
, buf
->data
, BUFSIZ
);
82 err(EXIT_FAILURE
, "cannot read");
85 return buf
->data
[buf
->i
];
94 cmd("seek(%d,%d)", x
, y
);
99 movea(cx
+ x
, cy
+ y
);
111 memset(arg
, 0, LENGTH(arg
));
116 for(j
= 0; j
< LENGTH(arg
);) {
126 errx(EXIT_FAILURE
, "syntax error");
143 mover(0, j
? arg
[0] : 1);
146 mover(0, j
? -arg
[0] : -1);
149 mover(j
? arg
[0] : 1, 0);
152 mover(j
? -arg
[0] : -1, 0);
155 /* movel(j ? arg[0] : 1); */
158 /* movel(j ? -arg[0] : -1); */
162 movea(j
? arg
[0] : 1, cy
);
166 movea(arg
[1] ? arg
[1] : 1, arg
[0] ? arg
[0] : 1);
168 /* insline(j ? arg[0] : 1); */
171 /* delline(j ? arg[0] : 1); */
176 scroll(j
? arg
[0] : 1);
179 scroll(j
? -arg
[0] : -1);
182 movea(cx
, j
? arg
[0] : 1);
185 for(i
= 0; i
< j
; i
++) {
186 if(arg
[i
] >= 30 && arg
[i
] <= 37)
187 cmd("#%d", arg
[i
] - 30);
188 if(arg
[i
] >= 40 && arg
[i
] <= 47)
189 cmd("|%d", arg
[i
] - 40);
190 /* xterm bright colors */
191 if(arg
[i
] >= 90 && arg
[i
] <= 97)
192 cmd("#%d", arg
[i
] - 90);
193 if(arg
[i
] >= 100 && arg
[i
] <= 107)
194 cmd("|%d", arg
[i
] - 100);
217 cmd("seek(%d,%d)", cx
, cy
+ l
);
224 #if defined(_GNU_SOURCE)
226 #elif _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
227 ptm
= posix_openpt(O_RDWR
);
229 ptm
= open("/dev/ptmx", O_RDWR
);
231 if(openpty(&ptm
, &pts
, NULL
, NULL
, NULL
) == -1)
232 err(EXIT_FAILURE
, "cannot open pty");
234 #if defined(_XOPEN_SOURCE)
236 if(grantpt(ptm
) == -1)
237 err(EXIT_FAILURE
, "cannot grant access to pty");
238 if(unlockpt(ptm
) == -1)
239 err(EXIT_FAILURE
, "cannot unlock pty");
240 ptsdev
= ptsname(ptm
);
242 err(EXIT_FAILURE
, "slave pty name undefined");
243 pts
= open(ptsdev
, O_RDWR
);
245 err(EXIT_FAILURE
, "cannot open slave pty");
248 err(EXIT_FAILURE
, "cannot open pty");
254 static char *shell
= NULL
;
256 if(!shell
&& !(shell
= getenv("SHELL")))
261 err(EXIT_FAILURE
, "cannot fork");
264 dup2(pts
, STDIN_FILENO
);
265 dup2(pts
, STDOUT_FILENO
);
266 dup2(pts
, STDERR_FILENO
);
268 putenv("TERM=vt102");
273 signal(SIGCHLD
, sigchld
);
281 if(waitpid(pid
, &ret
, 0) == -1)
282 err(EXIT_FAILURE
, "waiting for child failed");
284 exit(WEXITSTATUS(ret
));
293 c
= buf
.data
[buf
.s
++];
294 buf
.s
%= LENGTH(buf
.data
);
300 ungetch(ReadBuffer
*buf
, int c
) {
301 if(buf
->i
+ 1 >= buf
->n
)
302 errx(EXIT_FAILURE
, "buffer full");
303 buf
->data
[buf
->i
++] = c
;
307 main(int argc
, char *argv
[]) {
310 if(argc
== 2 && !strcmp("-v", argv
[1]))
311 errx(EXIT_SUCCESS
, "std-"VERSION
", © 2008 Matthias-Christian Ott");
313 errx(EXIT_FAILURE
, "usage: std [-v]");
316 cmdbuf
.fd
= STDIN_FILENO
;
319 FD_SET(STDIN_FILENO
, &rfds
);
322 if(select(ptm
+ 1, &rfds
, NULL
, NULL
, NULL
) == -1)
323 err(EXIT_FAILURE
, "cannot select");
324 if(FD_ISSET(STDIN_FILENO
, &rfds
))
334 } while(cmdbuf
.i
< cmdbuf
.n
);
335 if(FD_ISSET(ptm
, &rfds
)) {
345 } while(ptmbuf
.i
< ptmbuf
.n
);