StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
get_line.cxx
1 #include <termios.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <signal.h>
5 #include <stdio.h>
6 #include <string.h>
7 
8 
9 static struct termios save_termios;
10 static int ttysavefd = -1;
11 static enum { CBREAK, RESET } ttystate = RESET;
12 
13 #define HISTORY_SIZE 100
14 char history[HISTORY_SIZE][255];
15 
16 int tty_cbreak(int fd)
17 {
18  struct termios buf;
19  if(tcgetattr(fd, & save_termios) < 0)
20  return -1;
21 
22  buf = save_termios;
23 
24  buf.c_lflag &= ~(ECHO | ICANON);
25  buf.c_cc[VMIN] = 1;
26  buf.c_cc[VTIME] = 0;
27 
28  if(tcsetattr(fd, TCSAFLUSH, &buf) < 0)
29  return -1;
30 
31  ttysavefd = fd;
32  ttystate = CBREAK;
33  return 0;
34 }
35 
36 int tty_reset(int fd)
37 {
38  if(ttystate != CBREAK) return 0;
39  if(tcsetattr(fd, TCSAFLUSH, &save_termios) < 0)
40  return -1;
41  ttystate = RESET;
42  return 0;
43 }
44 
45 // static void sig_catch(int);
46 
47 // static void sig_catch(int signo)
48 // {
49 // printf("Signal caught\n");
50 // tty_reset(STDIN_FILENO);
51 // exit(0);
52 // }
53 
54 static int c_line = 0;
55 
56 void get_line(char *buff)
57 {
58 // memset(history,0,sizeof(history));
59 
60 // if(signal(SIGINT, sig_catch) == SIG_ERR)
61 // {
62 // printf("Error\n");
63 // exit(0);
64 // }
65 // if(signal(SIGQUIT, sig_catch) == SIG_ERR)
66 // {
67 // printf("Error 1\n");
68 // exit(0);
69 // }
70 // if(signal(SIGTERM, sig_catch) == SIG_ERR)
71 // {
72 // printf("Error 2\n");
73 // exit(0);
74 // }
75 
76  if(tty_cbreak(STDIN_FILENO) < 0)
77  {
78  //printf("Error 3\n");
79  exit(0);
80  }
81 
82  int h_line;
83  int c_char = 0;
84  int l_char = 0;
85  int t;
86  int i;
87  char c;
88 
89  h_line = c_line;
90  c_char = 0;
91  l_char = 0;
92  memset(history[c_line],0,sizeof(history[c_line]));
93 
94  while( (i = read(STDIN_FILENO, &c, 1)) == 1)
95  {
96  c &= 0xff;
97  switch(c)
98  {
99  case 0xa: // Return
100  putchar(0xa);
101  fflush(stdout);
102  break;
103  case 0x8: // BACK
104  case 0x7f: // DEL
105  // Change the history
106  if(c_char == 0) break;
107  for(t=c_char;t<=l_char;t++)
108  {
109  history[c_line][t-1] = history[c_line][t];
110  }
111  history[c_line][l_char] = '\0';
112  l_char--;
113  c_char--;
114 
115  // Print
116  putchar(0x8);
117  for(t=c_char;t<l_char;t++)
118  {
119  putchar(history[c_line][t]);
120  }
121  putchar(' ');
122  for(t=c_char;t<l_char+1;t++)
123  putchar(0x8);
124 
125  fflush(stdout);
126  break;
127 
128  case 0x1b:
129  {
130  i = read(STDIN_FILENO, &c, 1);
131  i = read(STDIN_FILENO, &c, 1);
132  if(c == 0x43) // right arrow
133  {
134  if(c_char < l_char)
135  {
136  c_char++;
137  putchar(0x1b);
138  putchar(0x5b);
139  putchar(0x43);
140  }
141  }
142  else if(c==0x44) // left arrow
143  {
144  if(c_char > 0)
145  {
146  c_char--;
147  putchar(0x1b);
148  putchar(0x5b);
149  putchar(0x44);
150  }
151  }
152  else if(c==0x41) // up arrow
153  {
154  h_line--;
155  if(h_line < 0) h_line = HISTORY_SIZE-1;
156 
157  for(t=c_char;t>0;t--)
158  {
159  putchar(0x8);
160  }
161  for(t=0;t<l_char;t++)
162  {
163  putchar(' ');
164  }
165  for(t=l_char;t>0;t--)
166  {
167  putchar(0x8);
168  }
169  l_char = 0;
170  c_char = 0;
171  memset(history[c_line],0,sizeof(history[c_line]));
172  while(history[h_line][c_char])
173  {
174  putchar(history[h_line][c_char]);
175  history[c_line][c_char] = history[h_line][c_char];
176  c_char++;
177  }
178  l_char = c_char;
179  }
180  else if(c==0x42) // down arrow
181  {
182  h_line++;
183  if(h_line >= HISTORY_SIZE) h_line = 0;
184  for(t=c_char;t>0;t--)
185  {
186  putchar(0x8);
187  }
188  for(t=0;t<l_char;t++)
189  {
190  putchar(' ');
191  }
192  for(t=l_char;t>0;t--)
193  {
194  putchar(0x8);
195  }
196  l_char = 0;
197  c_char = 0;
198  memset(history[c_line],0,sizeof(history[c_line]));
199  while(history[h_line][c_char])
200  {
201  putchar(history[h_line][c_char]);
202  history[c_line][c_char] = history[h_line][c_char];
203  c_char++;
204  }
205  l_char = c_char;
206  }
207  fflush(stdout);
208  break;
209  }
210 
211  default:
212  // Change history
213  for(t=l_char;t>c_char;t--)
214  {
215  history[c_line][t] = history[c_line][t-1];
216  }
217  history[c_line][c_char] = c;
218  l_char++;
219  c_char++;
220 
221  // Print
222  for(t=c_char-1;t<l_char;t++)
223  {
224  putchar(history[c_line][t]);
225  }
226  for(t=c_char;t<l_char;t++)
227  {
228  putchar(0x8);
229  }
230  fflush(stdout);
231  break;
232  }
233 
234  if(c == 0xa) break;
235  }
236 
237  // printf("line[%d]: %s\n",c_line,history[c_line]);
238  strcpy(buff,history[c_line]);
239 
240  c_line++;
241  if(c_line >= HISTORY_SIZE) c_line = 0;
242 
243  tty_reset(STDIN_FILENO);
244 }
245 
246 char one_line_buff[255];
247 
248 void get_one_line(char *buff)
249 {
250  fflush(stdout);
251  if(tty_cbreak(STDIN_FILENO) < 0)
252  {
253  //printf("Error 3\n");
254  exit(0);
255  }
256 
257  int c_char = 0;
258  int l_char = 0;
259  int t;
260  int i;
261  char c;
262 
263  c_char = 0;
264  l_char = 0;
265  memset(one_line_buff,0,sizeof(one_line_buff));
266 
267  while( (i = read(STDIN_FILENO, &c, 1)) == 1)
268  {
269  c &= 0xff;
270  switch(c)
271  {
272  case 0xa: // Return
273  putchar(0xa);
274  fflush(stdout);
275  break;
276  case 0x8: // BACK
277  case 0x7f: // DEL
278  // Change the history
279  if(c_char == 0) break;
280  for(t=c_char;t<=l_char;t++)
281  {
282  one_line_buff[t-1] = one_line_buff[t];
283  }
284  one_line_buff[l_char] = '\0';
285  l_char--;
286  c_char--;
287 
288  // Print
289  putchar(0x8);
290  for(t=c_char;t<l_char;t++)
291  {
292  putchar(one_line_buff[t]);
293  }
294  putchar(' ');
295  for(t=c_char;t<l_char+1;t++)
296  putchar(0x8);
297 
298  fflush(stdout);
299  break;
300 
301  case 0x1b:
302  {
303  i = read(STDIN_FILENO, &c, 1);
304  i = read(STDIN_FILENO, &c, 1);
305  if(c == 0x43) // right arrow
306  {
307  if(c_char < l_char)
308  {
309  c_char++;
310  putchar(0x1b);
311  putchar(0x5b);
312  putchar(0x43);
313  }
314  }
315  else if(c==0x44) // left arrow
316  {
317  if(c_char > 0)
318  {
319  c_char--;
320  putchar(0x1b);
321  putchar(0x5b);
322  putchar(0x44);
323  }
324  }
325  fflush(stdout);
326  break;
327  }
328 
329  default:
330  // Change history
331  for(t=l_char;t>c_char;t--)
332  {
333  one_line_buff[t] = one_line_buff[t-1];
334  }
335  one_line_buff[c_char] = c;
336  l_char++;
337  c_char++;
338 
339  // Print
340  for(t=c_char-1;t<l_char;t++)
341  {
342  putchar(one_line_buff[t]);
343  }
344  for(t=c_char;t<l_char;t++)
345  {
346  putchar(0x8);
347  }
348  fflush(stdout);
349  break;
350  }
351 
352  if(c == 0xa) break;
353  }
354 
355  // printf("line[%d]: %s\n",c_line,history[c_line]);
356  strcpy(buff,one_line_buff);
357 
358  tty_reset(STDIN_FILENO);
359 }