gonzui


Format: Advanced Search

tkernel_2/monitor/cmdsvc/src/console.cbare sourcepermlink (0.04 seconds)

Search this content:

    1: /*
    2:  *----------------------------------------------------------------------
    3:  *    T-Kernel 2.0 Software Package
    4:  *
    5:  *    Copyright 2011 by Ken Sakamura.
    6:  *    This software is distributed under the latest version of T-License 2.x.
    7:  *----------------------------------------------------------------------
    8:  *
    9:  *    Released by T-Engine Forum(http://www.t-engine.org/) at 2011/05/17.
   10:  *    Modified by TRON Forum(http://www.tron.org/) at 2015/06/01.
   11:  *
   12:  *----------------------------------------------------------------------
   13:  */
   14: 
   15: /*
   16:  *      console.c
   17:  *
   18:  *       console I/O
   19:  */
   20: 
   21: #include "cmdsvc.h"
   22: 
   23: // control characters
   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'-'@')                // or ESC [ A
   37: #define CUR_DWN ('N'-'@')               // or        ESC [ B
   38: #define CUR_FWD ('F'-'@')               // or        ESC [ C
   39: #define CUR_BWD ('B'-'@')               // or        ESC [ D
   40: 
   41: #define HISTBUF_SZ      1024         // history buffer size
   42: 
   43: LOCAL   UB        hist[HISTBUF_SZ];      // history buffer
   44: LOCAL   W CTRL_C_IN;              // CTRL-C input flag
   45: LOCAL   W XOFF_IN;                // XOFF input flag
   46: LOCAL   const UB  Digit[] = "0123456789ABCDEF";
   47: 
   48: /*
   49:  * detect CTRL-C
   50:  *       check if there is a history of control-C input to the console
   51:  *       history is cleared
   52:  *       return value      TRUE  : CTRL-C input exists
   53:  *                         FALSE : CTRL-C input is absent
   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:  * console output (one character)
   63:  *       XON/XOFF flow control
   64:  *       check for CTRL-C input
   65:  *       return value       0 : normal
   66:  *                         -1 : CTRL-C input exists
   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:  * console output (character string)
   84:  *       XON/XOFF flow control
   85:  *       check for CTRL-C input
   86:  *       return value       0 : normal
   87:  *                         -1 : CTRL-C input exists
   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:  * console output (hexadecimal: 2, 4, or 8 columns)
  101:  *       XON/XOFF flow control
  102:  *       check for CTRL-C input
  103:  *       return value       0 : normal
  104:  *                         -1 : CTRL-C input exists
  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:  * console output (decimal: 10 columns/zero-suppress supported)
  131:  *       XON/XOFF flow control
  132:  *       check for CTRL-C input
  133:  *       return value       0 : normal
  134:  *                         -1 : CTRL-C input exists
  135:  */
  136: EXPORT W putDec( UW val )
  137: {
  138:         W      i;
  139:         UB     d[11];      // required columns for displaying 32-bit maximum cardinal(4,294,967,295) +1
  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:  * console input (one character)
  156:  *       if wait = TRUE, wait for input if FALSE, do not wait.
  157:  *       return value       >= 0 : character
  158:  *                            -1 : no input
  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:  * consle input (character string)
  173:  *       line input with editing
  174:  *       return value      >= 0 : number of input characters
  175:  *                           -1 : CTRL-C was detected
  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) {               // EUC 2 bytes characters
  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) {    // ESC sequence
  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) {    // history is recalled
  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);            // echo back
  281:         putSIO(LF);
  282:         str[ep] = '\0';
  283:         if (c == CTLC) return -1;
  284: 
  285:         if (ep) {              // add to history buffer
  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: }