6 #include <linux/ctype.h>
9 * cmdline-editing related codes from vivi.
10 * Author: Janghoon Lyu <nandy@mizi.com>
13 #define putnstr(str,n) do { \
14 printf ("%.*s", n, str); \
17 #define MAX_CMDBUF_SIZE 256
19 #define CTL_BACKSPACE ('\b')
22 #define CREAD_HIST_CHAR ('!')
24 #define getcmd_putch(ch) putchar(ch)
25 #define getcmd_getch() getc()
26 #define getcmd_cbeep() getcmd_putch('\a')
29 #define HIST_SIZE MAX_CMDBUF_SIZE
31 static int hist_max
= 0;
32 static int hist_add_idx
= 0;
33 static int hist_cur
= -1;
34 static unsigned hist_num
= 0;
36 static char* hist_list
[HIST_MAX
];
37 static char hist_lines
[HIST_MAX
][HIST_SIZE
];
39 #define add_idx_minus_one() ((hist_add_idx == 0) ? hist_max : hist_add_idx-1)
41 static int hist_init(void)
50 for (i
= 0; i
< HIST_MAX
; i
++) {
51 hist_list
[i
] = hist_lines
[i
];
52 hist_list
[i
][0] = '\0';
57 postcore_initcall(hist_init
);
59 static void cread_add_to_hist(char *line
)
61 strcpy(hist_list
[hist_add_idx
], line
);
63 if (++hist_add_idx
>= HIST_MAX
)
66 if (hist_add_idx
> hist_max
)
67 hist_max
= hist_add_idx
;
72 static char* hist_prev(void)
84 if (hist_cur
== hist_add_idx
) {
88 ret
= hist_list
[hist_cur
];
93 static char* hist_next(void)
100 if (hist_cur
== hist_add_idx
)
103 if (++hist_cur
> hist_max
)
106 if (hist_cur
== hist_add_idx
) {
109 ret
= hist_list
[hist_cur
];
114 #define BEGINNING_OF_LINE() { \
116 getcmd_putch(CTL_BACKSPACE); \
121 #define ERASE_TO_EOL() { \
122 if (num < eol_num) { \
124 for (tmp = num; tmp < eol_num; tmp++) \
126 while (tmp-- > num) \
127 getcmd_putch(CTL_BACKSPACE); \
132 #define REFRESH_TO_EOL() { \
133 if (num < eol_num) { \
134 wlen = eol_num - num; \
135 putnstr(buf + num, wlen); \
140 static void cread_add_char(char ichar
, int insert
, unsigned long *num
,
141 unsigned long *eol_num
, char *buf
, unsigned long len
)
146 if (insert
|| *num
== *eol_num
) {
147 if (*eol_num
> len
- 1) {
155 wlen
= *eol_num
- *num
;
157 memmove(&buf
[*num
+1], &buf
[*num
], wlen
-1);
161 putnstr(buf
+ *num
, wlen
);
164 getcmd_putch(CTL_BACKSPACE
);
167 /* echo the character */
170 putnstr(buf
+ *num
, wlen
);
175 int readline(const char *prompt
, char *buf
, int len
)
177 unsigned long num
= 0;
178 unsigned long eol_num
= 0;
184 #ifdef CONFIG_AUTO_COMPLETE
197 if ((ichar
== '\n') || (ichar
== '\r')) {
204 #ifdef CONFIG_AUTO_COMPLETE
209 reprint
= complete(buf
, &completestr
);
213 printf("%s%s", prompt
, buf
);
216 for (i
= 0; i
< eol_num
- num
; i
++)
217 getcmd_putch(CTL_BACKSPACE
);
221 while (completestr
[i
])
222 cread_add_char(completestr
[i
++], insert
, &num
,
230 case CTL_CH('c'): /* ^C - break */
231 *buf
= 0; /* discard input */
235 getcmd_putch(buf
[num
]);
241 getcmd_putch(CTL_BACKSPACE
);
247 wlen
= eol_num
- num
- 1;
249 memmove(&buf
[num
], &buf
[num
+1], wlen
);
250 putnstr(buf
+ num
, wlen
);
255 getcmd_putch(CTL_BACKSPACE
);
260 case KEY_ERASE_TO_EOL
:
263 case KEY_REFRESH_TO_EOL
:
278 wlen
= eol_num
- num
;
280 memmove(buf
+ num
, buf
+ num
+ 1, wlen
);
281 getcmd_putch(CTL_BACKSPACE
);
282 putnstr(buf
+ num
, wlen
);
285 getcmd_putch(CTL_BACKSPACE
);
292 wlen
= eol_num
- num
;
293 memmove(buf
+ num
, buf
+ num
+ 1, wlen
);
294 putnstr(buf
+ num
, wlen
- 1);
297 getcmd_putch(CTL_BACKSPACE
);
317 /* nuke the current line */
321 /* erase to end of line */
324 /* copy new line into place and display */
326 eol_num
= strlen(buf
);
331 if (isascii(ichar
) && isprint(ichar
))
332 cread_add_char(ichar
, insert
, &num
, &eol_num
, buf
, len
);
337 buf
[eol_num
] = '\0'; /* lose the newline */
339 if (buf
[0] && buf
[0] != CREAD_HIST_CHAR
)
340 cread_add_to_hist(buf
);
341 hist_cur
= hist_add_idx
;
343 return rc
< 0 ? rc
: len
;