Browse code

Split tty functions into tty.c

John Hawthorn authored on 04/08/2014 04:56:17
Showing 4 changed files

  • Makefile index fe54ee2..0e1aae8 100644
  • fzy.c index 9d294b0..dd25cde 100644
  • tty.c index 0000000..4f434b5
  • tty.h index 0000000..82ab0ac
... ...
@@ -16,7 +16,7 @@ fzytest: fzytest.o match.o
16 16
 test: fzytest
17 17
 	-./fzytest
18 18
 
19
-fzy: fzy.o match.o
19
+fzy: fzy.o match.o tty.o
20 20
 	$(CC) $(CCFLAGS) -o $@ $^
21 21
 
22 22
 %.o: %.c fzy.h
... ...
@@ -2,13 +2,10 @@
2 2
 #include <stdio.h>
3 3
 #include <string.h>
4 4
 #include <stdlib.h>
5
-#include <termios.h>
6
-#include <unistd.h>
7
-#include <sys/stat.h>
8
-#include <fcntl.h>
9 5
 #include <ctype.h>
10 6
 
11 7
 #include "fzy.h"
8
+#include "tty.h"
12 9
 
13 10
 #define INITIAL_CAPACITY 1
14 11
 int choices_capacity = 0;
... ...
@@ -83,58 +80,22 @@ void run_search(char *needle){
83 80
 	}
84 81
 
85 82
 	qsort(choices_sorted, choices_available, sizeof(size_t), cmpchoice);
86
-
87
-}
88
-
89
-int ttyin;
90
-FILE *ttyout;
91
-struct termios original_termios;
92
-
93
-void reset_tty(){
94
-	tcsetattr(ttyin, TCSANOW, &original_termios);
95
-}
96
-
97
-void init_tty(){
98
-	ttyin = open("/dev/tty", O_RDONLY);
99
-	ttyout = fopen("/dev/tty", "w");
100
-
101
-	tcgetattr(ttyin, &original_termios);
102
-
103
-	struct termios new_termios = original_termios;
104
-
105
-	new_termios.c_lflag &= ~(ICANON | ECHO);
106
-
107
-	tcsetattr(ttyin, TCSANOW, &new_termios);
108
-}
109
-
110
-char ttygetchar(){
111
-	char ch;
112
-	int size = read(ttyin, &ch, 1);
113
-	if(size < 0){
114
-		perror("error reading from tty");
115
-		exit(EXIT_FAILURE);
116
-	}else if(size == 0){
117
-		/* EOF */
118
-		exit(EXIT_FAILURE);
119
-	}else{
120
-		return ch;
121
-	}
122 83
 }
123 84
 
124 85
 int search_size;
125 86
 char search[4096] = {0};
126 87
 
127
-void clear(){
128
-	fprintf(ttyout, "%c%c0G", 0x1b, '[');
88
+void clear(tty_t *tty){
89
+	fprintf(tty->fout, "%c%c0G", 0x1b, '[');
129 90
 	int line = 0;
130 91
 	while(line++ < 10 + 1){
131
-		fprintf(ttyout, "%c%cK\n", 0x1b, '[');
92
+		fprintf(tty->fout, "%c%cK\n", 0x1b, '[');
132 93
 	}
133
-	fprintf(ttyout, "%c%c%iA", 0x1b, '[', line-1);
134
-	fprintf(ttyout, "%c%c0G", 0x1b, '[');
94
+	fprintf(tty->fout, "%c%c%iA", 0x1b, '[', line-1);
95
+	fprintf(tty->fout, "%c%c0G", 0x1b, '[');
135 96
 }
136 97
 
137
-void draw_match(const char *choice, int selected){
98
+void draw_match(tty_t *tty, const char *choice, int selected){
138 99
 	int n = strlen(search);
139 100
 	size_t positions[n + 1];
140 101
 	for(int i = 0; i < n + 1; i++)
... ...
@@ -144,36 +105,36 @@ void draw_match(const char *choice, int selected){
144 105
 
145 106
 	for(size_t i = 0, p = 0; choice[i] != '\0'; i++){
146 107
 		if(positions[p] == i){
147
-			fprintf(ttyout, "%c%c33m", 0x1b, '[');
108
+			fprintf(tty->fout, "%c%c33m", 0x1b, '[');
148 109
 			p++;
149 110
 		}else{
150
-			fprintf(ttyout, "%c%c39;49m", 0x1b, '[');
111
+			fprintf(tty->fout, "%c%c39;49m", 0x1b, '[');
151 112
 		}
152
-		fprintf(ttyout, "%c", choice[i]);
113
+		fprintf(tty->fout, "%c", choice[i]);
153 114
 	}
154
-	fprintf(ttyout, "\n");
155
-	fprintf(ttyout, "%c%c0m", 0x1b, '[');
115
+	fprintf(tty->fout, "\n");
116
+	fprintf(tty->fout, "%c%c0m", 0x1b, '[');
156 117
 }
157 118
 
158
-void draw(){
119
+void draw(tty_t *tty){
159 120
 	int line = 0;
160 121
 	const char *prompt = "> ";
161
-	clear();
162
-	fprintf(ttyout, "%s%s\n", prompt, search);
122
+	clear(tty);
123
+	fprintf(tty->fout, "%s%s\n", prompt, search);
163 124
 	for(size_t i = 0; line < 10 && i < choices_available; i++){
164 125
 		if(i == current_selection)
165
-			fprintf(ttyout, "%c%c7m", 0x1b, '[');
166
-		draw_match(choices[choices_sorted[i]], i == current_selection);
126
+			fprintf(tty->fout, "%c%c7m", 0x1b, '[');
127
+		draw_match(tty, choices[choices_sorted[i]], i == current_selection);
167 128
 		line++;
168 129
 	}
169
-	fprintf(ttyout, "%c%c%iA", 0x1b, '[', line + 1);
170
-	fprintf(ttyout, "%c%c%ziG", 0x1b, '[', strlen(prompt) + strlen(search) + 1);
171
-	fflush(ttyout);
130
+	fprintf(tty->fout, "%c%c%iA", 0x1b, '[', line + 1);
131
+	fprintf(tty->fout, "%c%c%ziG", 0x1b, '[', strlen(prompt) + strlen(search) + 1);
132
+	fflush(tty->fout);
172 133
 }
173 134
 
174
-void emit(){
135
+void emit(tty_t *tty){
175 136
 	/* ttyout should be flushed before outputting on stdout */
176
-	fclose(ttyout);
137
+	fclose(tty->fout);
177 138
 
178 139
 	if(choices_available){
179 140
 		/* output the selected result */
... ...
@@ -186,12 +147,12 @@ void emit(){
186 147
 	exit(EXIT_SUCCESS);
187 148
 }
188 149
 
189
-void run(){
150
+void run(tty_t *tty){
190 151
 	run_search(search);
191 152
 	char ch;
192 153
 	do {
193
-		draw();
194
-		ch = ttygetchar();
154
+		draw(tty);
155
+		ch = tty_getchar(tty);
195 156
 		if(isprint(ch)){
196 157
 			/* FIXME: overflow */
197 158
 			search[search_size++] = ch;
... ...
@@ -213,13 +174,11 @@ void run(){
213 174
 			run_search(search);
214 175
 		}else if(ch == 14){ /* C-N */
215 176
 			current_selection = (current_selection + 1) % 10;
216
-			draw();
217 177
 		}else if(ch == 16){ /* C-P */
218 178
 			current_selection = (current_selection + 9) % 10;
219
-			draw();
220 179
 		}else if(ch == 10){ /* Enter */
221
-			clear();
222
-			emit();
180
+			clear(tty);
181
+			emit(tty);
223 182
 		}
224 183
 	}while(1);
225 184
 }
... ...
@@ -236,14 +195,14 @@ int main(int argc, char *argv[]){
236 195
 	}else if(argc != 1){
237 196
 		usage(argv[0]);
238 197
 	}
239
-	atexit(reset_tty);
240
-	init_tty(reset_tty);
198
+	tty_t tty;
199
+	tty_init(&tty);
241 200
 
242 201
 	resize_choices(INITIAL_CAPACITY);
243 202
 	read_choices();
244 203
 
245
-	clear();
246
-	run();
204
+	clear(&tty);
205
+	run(&tty);
247 206
 
248 207
 	return 0;
249 208
 }
250 209
new file mode 100644
... ...
@@ -0,0 +1,38 @@
1
+#include <stdio.h>
2
+#include <unistd.h>
3
+#include <fcntl.h>
4
+#include <stdlib.h>
5
+
6
+#include "tty.h"
7
+
8
+void tty_reset(tty_t *tty){
9
+	tcsetattr(tty->fdin, TCSANOW, &tty->original_termios);
10
+}
11
+
12
+void tty_init(tty_t *tty){
13
+	tty->fdin = open("/dev/tty", O_RDONLY);
14
+	tty->fout = fopen("/dev/tty", "w");
15
+
16
+	tcgetattr(tty->fdin, &tty->original_termios);
17
+
18
+	struct termios new_termios = tty->original_termios;
19
+
20
+	new_termios.c_lflag &= ~(ICANON | ECHO);
21
+
22
+	tcsetattr(tty->fdin, TCSANOW, &new_termios);
23
+}
24
+
25
+char tty_getchar(tty_t *tty){
26
+	char ch;
27
+	int size = read(tty->fdin, &ch, 1);
28
+	if(size < 0){
29
+		perror("error reading from tty");
30
+		exit(EXIT_FAILURE);
31
+	}else if(size == 0){
32
+		/* EOF */
33
+		exit(EXIT_FAILURE);
34
+	}else{
35
+		return ch;
36
+	}
37
+}
38
+
0 39
new file mode 100644
... ...
@@ -0,0 +1,16 @@
1
+#ifndef TTY_H
2
+#define TTY_H TTY_H
3
+
4
+#include <termios.h>
5
+
6
+typedef struct{
7
+	int fdin;
8
+	FILE *fout;
9
+	struct termios original_termios;
10
+} tty_t;
11
+
12
+void tty_reset(tty_t *tty);
13
+void tty_init(tty_t *tty);
14
+char tty_getchar(tty_t *tty);
15
+
16
+#endif