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: }