1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
14:
15: 16: 17: 18: 19:
20:
21: #include "cmdsvc.h"
22:
23:
24: #define BS ('H'-'@')
25: #define CAN ('X'-'@')
26: #define CTLC ('C'-'@')
27: #define DEL (0x7f)
28: #define CR (0x0d)
29: #define LF (0x0a)
30: #define XOFF ('S'-'@')
31: #define XON ('Q'-'@')
32: #define ERASE ('K'-'@')
33: #define CAN2 ('U'-'@')
34: #define TAB ('I'-'@')
35: #define ESC ('['-'@')
36: #define CUR_UP ('P'-'@')
37: #define CUR_DWN ('N'-'@')
38: #define CUR_FWD ('F'-'@')
39: #define CUR_BWD ('B'-'@')
40:
41: #define HISTBUF_SZ 1024
42:
43: LOCAL UB hist[HISTBUF_SZ];
44: LOCAL W CTRL_C_IN;
45: LOCAL W XOFF_IN;
46: LOCAL const UB Digit[] = "0123456789ABCDEF";
47:
48: 49: 50: 51: 52: 53: 54:
55: EXPORT BOOL checkAbort( void )
56: {
57: if (CTRL_C_IN) {CTRL_C_IN = 0; return TRUE;}
58: return FALSE;
59: }
60:
61: 62: 63: 64: 65: 66: 67:
68: EXPORT W putChar( W c )
69: {
70: W ch;
71:
72: if (XOFF_IN || (ch = getSIO(0)) == XOFF) {
73: while ((ch = getSIO(1)) != XON && ch != CTLC);
74: XOFF_IN = 0;
75: }
76: if (ch == CTLC) {CTRL_C_IN++; return -1;}
77: if (c == LF) putSIO(CR);
78: putSIO(c);
79: return 0;
80: }
81:
82: 83: 84: 85: 86: 87: 88:
89: EXPORT W putString( const UB *str )
90: {
91: UB c;
92:
93: while ((c = *str++)) {
94: if (putChar(c) < 0) return -1;
95: }
96: return 0;
97: }
98:
99: 100: 101: 102: 103: 104: 105:
106: EXPORT W putHex2( UB val )
107: {
108: if (putChar(Digit[(val >> 4) & 0x0f]) < 0) return -1;
109: if (putChar(Digit[(val >> 0) & 0x0f]) < 0) return -1;
110: return 0;
111: }
112:
113: EXPORT W putHex4( UH val )
114: {
115: if (putHex2(val >> 8) < 0) return -1;
116: if (putHex2(val >> 0) < 0) return -1;
117: return 0;
118: }
119:
120: EXPORT W putHex8( UW val )
121: {
122: if (putHex2(val >> 24) < 0) return -1;
123: if (putHex2(val >> 16) < 0) return -1;
124: if (putHex2(val >> 8) < 0) return -1;
125: if (putHex2(val >> 0) < 0) return -1;
126: return 0;
127: }
128:
129: 130: 131: 132: 133: 134: 135:
136: EXPORT W putDec( UW val )
137: {
138: W i;
139: UB d[11];
140:
141: for (i = 0; i < sizeof(d); i++) {
142: d[i] = Digit[val % 10];
143: val /= 10;
144: if (!val) break;
145: }
146:
147: for (; i >= 0; i--) {
148: if (putChar(d[i]) < 0) return -1;
149: }
150:
151: return 0;
152: }
153:
154: 155: 156: 157: 158: 159:
160: EXPORT W getChar( BOOL wait )
161: {
162: W c;
163:
164: for (;;) {
165: if ((c = getSIO(0)) == XOFF) XOFF_IN = 1;
166: else if (c != -1 || !wait) break;
167: }
168: return c;
169: }
170:
171: 172: 173: 174: 175: 176:
177: EXPORT W getString( UB *str )
178: {
179: W i, c, c1;
180: W cp, ep, hp, esc;
181: W len;
182:
183: CTRL_C_IN = 0;
184: c = c1 = 0;
185: cp = ep = esc = 0;
186: hp = -1;
187:
188: while (ep < L_LINE - 2) {
189: if ((c = getSIO(0)) <= 0) continue;
190: len = 1;
191: if (c & 0x80) {
192: if (c1 == 0) {c1 = c; continue;}
193: c |= c1 << 8;
194: c1 = 0;
195: len = 2;
196: }
197: if (c == ESC) {esc = 1; continue;}
198:
199: if (esc) {
200: if (esc == 1) {
201: esc = (c == '[') ? 2 : 0;
202: continue;
203: }
204: esc = 0;
205: if (c == 'A') c = CUR_UP;
206: else if (c == 'B') c = CUR_DWN;
207: else if (c == 'C') c = CUR_FWD;
208: else if (c == 'D') c = CUR_BWD;
209: else continue;
210: }
211: if (c == CUR_FWD) {
212: if (cp < ep) {
213: if (str[cp] & 0x80) putSIO(str[cp++]);
214: putSIO(str[cp++]);
215: }
216: continue;
217: }
218: if (c == CUR_BWD) {
219: if (cp > 0) {
220: if (str[--cp] & 0x80) {putSIO(BS); cp--;}
221: putSIO(BS);
222: }
223: continue;
224: }
225: if (c == CUR_UP || c == CUR_DWN) {
226: if (c == CUR_DWN) {
227: if (hp <= 0) continue;
228: for (hp--; (--hp) > 0 && hist[hp];);
229: if (hp) hp++;
230: } else {
231: i = hp < 0 ? 0 : (strlen(&hist[hp]) + hp + 1);
232: if (hist[i] == '\0') continue;
233: hp = i;
234: }
235: for (; cp > 0; cp--) putSIO(BS);
236: for (i = strlen(&hist[hp]); cp < i; cp++)
237: putSIO(str[cp] = hist[hp + cp]);
238: c = ERASE;
239: }
240: if (c == BS || c == DEL) {
241: if (cp <= 0) continue;
242: len = (str[cp - 1] & 0x80) ? 2 : 1;
243: if (cp < ep) memcpy(&str[cp - len], &str[cp], ep - cp);
244: for (i = 0; i < len; i++)
245: {str[--ep] = ' '; putSIO(BS);}
246: cp -= len;
247: for (i = cp; i < ep + len; i++) putSIO(str[i]);
248: for (; i > cp; i--) putSIO(BS);
249: continue;
250: }
251: if (c == CAN || c == CAN2) {
252: for (; cp > 0; cp--) putSIO(BS);
253: c = ERASE;
254: }
255: if (c == ERASE) {
256: for (i = cp; i < ep; i++) putSIO(' ');
257: for (; i > cp; i--) putSIO(BS);
258: ep = cp;
259: continue;
260: }
261:
262: if (c == CR || c == LF) break;
263:
264: if (c == CTLC) {
265: CTRL_C_IN++;
266: break;
267: }
268:
269: if (c < ' ' && c != TAB) continue;
270:
271: if (cp < ep) memmove(&str[cp + len], &str[cp], ep - cp);
272: if (len == 2) {
273: str[cp + 1] = c & 0xff;
274: c = (c >> 8) & 0xff;
275: }
276: str[cp] = c;
277: for (ep += len, i = cp; i < ep; i++) putSIO(str[i]);
278: for (cp += len; i > cp; i--) putSIO(BS);
279: }
280: putSIO(CR);
281: putSIO(LF);
282: str[ep] = '\0';
283: if (c == CTLC) return -1;
284:
285: if (ep) {
286: i = ep + 1;
287: memmove(&hist[i], hist, HISTBUF_SZ - i);
288: memcpy(hist, str, i);
289: hist[HISTBUF_SZ - 2] = '\0';
290: hist[HISTBUF_SZ - 1] = '\0';
291: }
292: return ep;
293: }