Line data Source code
1 : /********************************************************************\
2 :
3 : Name: cmdedit.c
4 : Created by: Stefan Ritt
5 :
6 : Contents: Command-line editor for ODBEdit
7 :
8 : $Id:$
9 :
10 : \********************************************************************/
11 :
12 : #include "midas.h"
13 : #include "msystem.h"
14 :
15 : #ifdef OS_MSDOS
16 : #define MAX_HISTORY 10
17 : #else
18 : #define MAX_HISTORY 50
19 : #endif
20 :
21 : #define LINE_LENGTH 256
22 :
23 : char history[MAX_HISTORY][LINE_LENGTH];
24 : INT his_index = 0;
25 :
26 : #ifdef OS_VMS
27 :
28 : INT cmd_edit(const char *prompt, char *cmd, INT(*dir) (char *, INT *), INT(*idle) ())
29 : {
30 : printf(prompt);
31 : ss_gets(cmd, 256);
32 :
33 : return strlen(cmd);
34 : }
35 :
36 : #else
37 :
38 0 : INT cmd_edit(const char *prompt, char *cmd, INT(*dir) (char *, INT *), INT(*idle) ())
39 : {
40 : char line[LINE_LENGTH];
41 : INT i, j, k, c, hi;
42 : INT status;
43 0 : DWORD last_time = 0;
44 0 : BOOL escape_flag = 0;
45 :
46 0 : if (ss_getchar(0) == -1) {
47 : /* normal input if ss_getchar not supported */
48 0 : fputs(prompt, stdout);
49 0 : ss_gets(cmd, 256);
50 0 : return strlen(cmd);
51 : }
52 :
53 0 : fputs(prompt, stdout);
54 0 : fflush(stdout);
55 :
56 0 : hi = his_index;
57 0 : memset(line, 0, LINE_LENGTH);
58 0 : memset(history[hi], 0, LINE_LENGTH);
59 0 : strcpy(line, cmd);
60 0 : fputs(line, stdout);
61 0 : i = strlen(cmd);
62 0 : fflush(stdout);
63 :
64 : do {
65 0 : c = ss_getchar(0);
66 :
67 0 : if (c == 27)
68 0 : escape_flag = TRUE;
69 :
70 0 : if (c >= ' ' && c < CH_EXT && escape_flag) {
71 0 : escape_flag = FALSE;
72 0 : if (c == 'p')
73 0 : c = 6;
74 : }
75 :
76 : /* normal input */
77 0 : if (c >= ' ' && c < CH_EXT) {
78 0 : if (strlen(line) < LINE_LENGTH - 1) {
79 0 : for (j = strlen(line); j >= i; j--)
80 0 : line[j + 1] = line[j];
81 0 : if (i < LINE_LENGTH - 1) {
82 0 : line[i++] = c;
83 0 : fputc(c, stdout);
84 : }
85 0 : for (j = i; j < (INT) strlen(line); j++)
86 0 : fputc(line[j], stdout);
87 0 : for (j = i; j < (INT) strlen(line); j++)
88 0 : fputc('\b', stdout);
89 : }
90 : }
91 :
92 : /* BS */
93 0 : if (c == CH_BS && i > 0) {
94 0 : i--;
95 0 : fputc('\b', stdout);
96 0 : for (j = i; j <= (INT) strlen(line); j++) {
97 0 : line[j] = line[j + 1];
98 0 : if (line[j])
99 0 : fputc(line[j], stdout);
100 : else
101 0 : fputc(' ', stdout);
102 : }
103 0 : for (k = 0; k < j - i; k++)
104 0 : fputc('\b', stdout);
105 : }
106 :
107 : /* DELETE/Ctrl-D */
108 0 : if (c == CH_DELETE || c == 4) {
109 0 : for (j = i; j <= (INT) strlen(line); j++) {
110 0 : line[j] = line[j + 1];
111 0 : if (line[j])
112 0 : fputc(line[j], stdout);
113 : else
114 0 : fputc(' ', stdout);
115 : }
116 0 : for (k = 0; k < j - i; k++)
117 0 : fputc('\b', stdout);
118 : }
119 :
120 : /* Erase line: CTRL-W, CTRL-U */
121 0 : if (c == 23 || c == 21) {
122 0 : i = strlen(line);
123 0 : memset(line, 0, sizeof(line));
124 0 : printf("\r%s", prompt);
125 0 : for (j = 0; j < i; j++)
126 0 : fputc(' ', stdout);
127 0 : for (j = 0; j < i; j++)
128 0 : fputc('\b', stdout);
129 0 : i = 0;
130 : }
131 :
132 : /* Erase line from cursor: CTRL-K */
133 0 : if (c == 11) {
134 0 : for (j = i; j < (INT) strlen(line); j++)
135 0 : fputc(' ', stdout);
136 0 : for (j = i; j < (INT) strlen(line); j++)
137 0 : fputc('\b', stdout);
138 0 : for (j = strlen(line); j >= i; j--)
139 0 : line[j] = 0;
140 : }
141 :
142 : /* left arrow, CTRL-B */
143 0 : if ((c == CH_LEFT || c == 2) && i > 0) {
144 0 : i--;
145 0 : fputc('\b', stdout);
146 : }
147 :
148 : /* right arrow, CTRL-F */
149 0 : if ((c == CH_RIGHT || c == 6) && i < (INT) strlen(line))
150 0 : fputc(line[i++], stdout);
151 :
152 : /* HOME, CTRL-A */
153 0 : if ((c == CH_HOME || c == 1) && i > 0) {
154 0 : for (j = 0; j < i; j++)
155 0 : fputc('\b', stdout);
156 0 : i = 0;
157 : }
158 :
159 : /* END, CTRL-E */
160 0 : if ((c == CH_END || c == 5) && i < (INT) strlen(line)) {
161 0 : for (j = i; j < (INT) strlen(line); j++)
162 0 : fputc(line[i++], stdout);
163 0 : i = strlen(line);
164 : }
165 :
166 : /* up arrow / CTRL-P */
167 0 : if (c == CH_UP || c == 16) {
168 0 : if (history[(hi + MAX_HISTORY - 1) % MAX_HISTORY][0]) {
169 0 : hi = (hi + MAX_HISTORY - 1) % MAX_HISTORY;
170 0 : i = strlen(line);
171 0 : fputc('\r', stdout);
172 0 : fputs(prompt, stdout);
173 0 : for (j = 0; j < i; j++)
174 0 : fputc(' ', stdout);
175 0 : for (j = 0; j < i; j++)
176 0 : fputc('\b', stdout);
177 0 : memcpy(line, history[hi], 256);
178 0 : i = strlen(line);
179 0 : for (j = 0; j < i; j++)
180 0 : fputc(line[j], stdout);
181 : }
182 : }
183 :
184 : /* down arrow / CTRL-N */
185 0 : if (c == CH_DOWN || c == 14) {
186 0 : if (history[hi][0]) {
187 0 : hi = (hi + 1) % MAX_HISTORY;
188 0 : i = strlen(line);
189 0 : fputc('\r', stdout);
190 0 : fputs(prompt, stdout);
191 0 : for (j = 0; j < i; j++)
192 0 : fputc(' ', stdout);
193 0 : for (j = 0; j < i; j++)
194 0 : fputc('\b', stdout);
195 0 : memcpy(line, history[hi], 256);
196 0 : i = strlen(line);
197 0 : for (j = 0; j < i; j++)
198 0 : fputc(line[j], stdout);
199 : }
200 : }
201 :
202 : /* CTRL-F */
203 0 : if (c == 6) {
204 0 : for (j = (hi + MAX_HISTORY - 1) % MAX_HISTORY; j != hi;
205 0 : j = (j + MAX_HISTORY - 1) % MAX_HISTORY)
206 0 : if (history[j][0] && strncmp(line, history[j], i) == 0) {
207 0 : memcpy(line, history[j], 256);
208 0 : fputs(line + i, stdout);
209 0 : i = strlen(line);
210 0 : break;
211 : }
212 0 : if (j == hi)
213 0 : fputc(7, stdout);
214 : }
215 :
216 : /* tab */
217 0 : if (c == 9 && dir != NULL) {
218 0 : status = dir(line, &i);
219 :
220 : /* redraw line */
221 0 : fputc('\r', stdout);
222 0 : fputs(prompt, stdout);
223 0 : fputs(line, stdout);
224 :
225 0 : for (j = 0; j < (INT) strlen(line) - i; j++)
226 0 : fputc('\b', stdout);
227 : }
228 :
229 0 : if (c != 0) {
230 0 : last_time = ss_millitime();
231 0 : fflush(stdout);
232 : }
233 :
234 0 : if ((ss_millitime() - last_time > 300) && idle != NULL) {
235 0 : status = idle();
236 :
237 0 : if (status) {
238 0 : fputc('\r', stdout);
239 0 : fputs(prompt, stdout);
240 0 : fputs(line, stdout);
241 :
242 0 : for (j = 0; j < (INT) strlen(line) - i; j++)
243 0 : fputc('\b', stdout);
244 :
245 0 : fflush(stdout);
246 : }
247 : }
248 :
249 0 : } while (c != CH_CR && c != CH_LF);
250 :
251 0 : strcpy(cmd, line);
252 :
253 0 : if (dir != NULL)
254 0 : if (strcmp(cmd, history[(his_index + MAX_HISTORY - 1) % MAX_HISTORY]) != 0 &&
255 0 : cmd[0]) {
256 0 : strcpy(history[his_index], cmd);
257 0 : his_index = (his_index + 1) % MAX_HISTORY;
258 : }
259 :
260 : /* reset terminal */
261 0 : ss_getchar(1);
262 :
263 0 : fputc('\n', stdout);
264 :
265 0 : return strlen(line);
266 : }
267 :
268 : #endif
|