The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/ddb/db_input.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Mach Operating System
    3  * Copyright (c) 1991,1990 Carnegie Mellon University
    4  * All Rights Reserved.
    5  *
    6  * Permission to use, copy, modify and distribute this software and its
    7  * documentation is hereby granted, provided that both the copyright
    8  * notice and this permission notice appear in all copies of the
    9  * software, derivative works or modified versions, and any portions
   10  * thereof, and that both notices appear in supporting documentation.
   11  *
   12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
   13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   15  *
   16  * Carnegie Mellon requests users of this software to return to
   17  *
   18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   19  *  School of Computer Science
   20  *  Carnegie Mellon University
   21  *  Pittsburgh PA 15213-3890
   22  *
   23  * any improvements or extensions that they make and grant Carnegie the
   24  * rights to redistribute these changes.
   25  *
   26  * $FreeBSD: src/sys/ddb/db_input.c,v 1.15.2.4 1999/09/05 08:08:46 peter Exp $
   27  */
   28 
   29 /*
   30  *      Author: David B. Golub, Carnegie Mellon University
   31  *      Date:   7/90
   32  */
   33 
   34 #include <sys/param.h>
   35 #include <sys/malloc.h>
   36 #include <sys/systm.h>
   37 
   38 #include <machine/cons.h>
   39 
   40 #include <ddb/ddb.h>
   41 #include <ddb/db_output.h>
   42 
   43 /*
   44  * Character input and editing.
   45  */
   46 
   47 /*
   48  * We don't track output position while editing input,
   49  * since input always ends with a new-line.  We just
   50  * reset the line position at the end.
   51  */
   52 static char *   db_lbuf_start;  /* start of input line buffer */
   53 static char *   db_lbuf_end;    /* end of input line buffer */
   54 static char *   db_lc;          /* current character */
   55 static char *   db_le;          /* one past last character */
   56 
   57 /*
   58  * Simple input line history support.
   59  */
   60 static char *   db_lhistory;
   61 static char     db_lhistory_buffer[2048];
   62 static int      db_lhistlsize, db_lhistidx, db_lhistcur;
   63 static int      db_lhist_nlines;
   64 
   65 #define CTRL(c)         ((c) & 0x1f)
   66 #define isspace(c)      ((c) == ' ' || (c) == '\t')
   67 #define BLANK           ' '
   68 #define BACKUP          '\b'
   69 
   70 static int      cnmaygetc __P((void));
   71 static void     db_delete __P((int n, int bwd));
   72 static int      db_inputchar __P((int c));
   73 static void     db_putnchars __P((int c, int count));
   74 static void     db_putstring __P((char *s, int count));
   75 
   76 void
   77 db_putstring(s, count)
   78         char    *s;
   79         int     count;
   80 {
   81         while (--count >= 0)
   82             cnputc(*s++);
   83 }
   84 
   85 void
   86 db_putnchars(c, count)
   87         int     c;
   88         int     count;
   89 {
   90         while (--count >= 0)
   91             cnputc(c);
   92 }
   93 
   94 /*
   95  * Delete N characters, forward or backward
   96  */
   97 #define DEL_FWD         0
   98 #define DEL_BWD         1
   99 void
  100 db_delete(n, bwd)
  101         int     n;
  102         int     bwd;
  103 {
  104         register char *p;
  105 
  106         if (bwd) {
  107             db_lc -= n;
  108             db_putnchars(BACKUP, n);
  109         }
  110         for (p = db_lc; p < db_le-n; p++) {
  111             *p = *(p+n);
  112             cnputc(*p);
  113         }
  114         db_putnchars(BLANK, n);
  115         db_putnchars(BACKUP, db_le - db_lc);
  116         db_le -= n;
  117 }
  118 
  119 /* returns TRUE at end-of-line */
  120 int
  121 db_inputchar(c)
  122         int     c;
  123 {
  124         static int escstate;
  125 
  126         if (escstate == 1) {
  127                 /* ESC seen, look for [ or O */
  128                 if (c == '[' || c == 'O')
  129                         escstate++;
  130                 else
  131                         escstate = 0; /* re-init state machine */
  132                 return (0);
  133         } else if (escstate == 2) {
  134                 escstate = 0;
  135                 /*
  136                  * If a valid cursor key has been found, translate
  137                  * into an emacs-style control key, and fall through.
  138                  * Otherwise, drop off.
  139                  */
  140                 switch (c) {
  141                 case 'A':       /* up */
  142                         c = CTRL('p');
  143                         break;
  144                 case 'B':       /* down */
  145                         c = CTRL('n');
  146                         break;
  147                 case 'C':       /* right */
  148                         c = CTRL('f');
  149                         break;
  150                 case 'D':       /* left */
  151                         c = CTRL('b');
  152                         break;
  153                 default:
  154                         return (0);
  155                 }
  156         }
  157 
  158         switch (c) {
  159             case CTRL('['):
  160                 escstate = 1;
  161                 break;
  162 #if __i386__ && __FreeBSD__
  163             case 591:           /* syscons's idea of an arrow key... */
  164 #endif
  165             case CTRL('b'):
  166                 /* back up one character */
  167                 if (db_lc > db_lbuf_start) {
  168                     cnputc(BACKUP);
  169                     db_lc--;
  170                 }
  171                 break;
  172 #if __i386__ && __FreeBSD__
  173             case 593:           /* syscons's idea of an arrow key... */
  174 #endif
  175             case CTRL('f'):
  176                 /* forward one character */
  177                 if (db_lc < db_le) {
  178                     cnputc(*db_lc);
  179                     db_lc++;
  180                 }
  181                 break;
  182             case CTRL('a'):
  183                 /* beginning of line */
  184                 while (db_lc > db_lbuf_start) {
  185                     cnputc(BACKUP);
  186                     db_lc--;
  187                 }
  188                 break;
  189             case CTRL('e'):
  190                 /* end of line */
  191                 while (db_lc < db_le) {
  192                     cnputc(*db_lc);
  193                     db_lc++;
  194                 }
  195                 break;
  196             case CTRL('h'):
  197             case 0177:
  198                 /* erase previous character */
  199                 if (db_lc > db_lbuf_start)
  200                     db_delete(1, DEL_BWD);
  201                 break;
  202             case CTRL('d'):
  203                 /* erase next character */
  204                 if (db_lc < db_le)
  205                     db_delete(1, DEL_FWD);
  206                 break;
  207             case CTRL('k'):
  208                 /* delete to end of line */
  209                 if (db_lc < db_le)
  210                     db_delete(db_le - db_lc, DEL_FWD);
  211                 break;
  212             case CTRL('t'):
  213                 /* twiddle last 2 characters */
  214                 if (db_lc >= db_lbuf_start + 2) {
  215                     c = db_lc[-2];
  216                     db_lc[-2] = db_lc[-1];
  217                     db_lc[-1] = c;
  218                     cnputc(BACKUP);
  219                     cnputc(BACKUP);
  220                     cnputc(db_lc[-2]);
  221                     cnputc(db_lc[-1]);
  222                 }
  223                 break;
  224             case CTRL('r'):
  225                 db_putstring("^R\n", 3);
  226             redraw:
  227                 if (db_le > db_lbuf_start) {
  228                     db_putstring(db_lbuf_start, db_le - db_lbuf_start);
  229                     db_putnchars(BACKUP, db_le - db_lc);
  230                 }
  231                 break;
  232 #if __i386__ && __FreeBSD__
  233             case 588:           /* syscons's idea of an arrow key... */
  234 #endif
  235             case CTRL('p'):
  236                 /* Make previous history line the active one. */
  237                 if (db_lhistcur >= 0) {
  238                     bcopy(db_lhistory + db_lhistcur * db_lhistlsize,
  239                           db_lbuf_start, db_lhistlsize);
  240                     db_lhistcur--;
  241                     goto hist_redraw;
  242                 }
  243                 break;
  244 #if __i386__ && __FreeBSD__
  245             case 596:           /* syscons's idea of an arrow key... */
  246 #endif
  247             case CTRL('n'):
  248                 /* Make next history line the active one. */
  249                 if (db_lhistcur < db_lhistidx - 1) {
  250                     db_lhistcur += 2;
  251                     bcopy(db_lhistory + db_lhistcur * db_lhistlsize,
  252                           db_lbuf_start, db_lhistlsize);
  253                 } else {
  254                     /*
  255                      * ^N through tail of history, reset the
  256                      * buffer to zero length.
  257                      */
  258                     *db_lbuf_start = '\0';
  259                     db_lhistcur = db_lhistidx;
  260                 }
  261 
  262             hist_redraw:
  263                 db_putnchars(BACKUP, db_le - db_lbuf_start);
  264                 db_putnchars(BLANK, db_le - db_lbuf_start);
  265                 db_putnchars(BACKUP, db_le - db_lbuf_start);
  266                 db_le = index(db_lbuf_start, '\0');
  267                 if (db_le[-1] == '\r' || db_le[-1] == '\n')
  268                     *--db_le = '\0';
  269                 db_lc = db_le;
  270                 goto redraw;
  271 
  272             case -1:
  273                 /*
  274                  * eek! the console returned eof.
  275                  * probably that means we HAVE no console.. we should try bail
  276                  * XXX
  277                  */
  278                 c = '\r';
  279             case '\n':
  280             case '\r':
  281                 *db_le++ = c;
  282                 return (1);
  283             default:
  284                 if (db_le == db_lbuf_end) {
  285                     cnputc('\007');
  286                 }
  287                 else if (c >= ' ' && c <= '~') {
  288                     register char *p;
  289 
  290                     for (p = db_le; p > db_lc; p--)
  291                         *p = *(p-1);
  292                     *db_lc++ = c;
  293                     db_le++;
  294                     cnputc(c);
  295                     db_putstring(db_lc, db_le - db_lc);
  296                     db_putnchars(BACKUP, db_le - db_lc);
  297                 }
  298                 break;
  299         }
  300         return (0);
  301 }
  302 
  303 int
  304 cnmaygetc()
  305 {
  306         return (-1);
  307 }
  308 
  309 int
  310 db_readline(lstart, lsize)
  311         char *  lstart;
  312         int     lsize;
  313 {
  314         if (db_lhistory && lsize != db_lhistlsize) {
  315                 /* Should not happen, but to be sane, throw history away. */
  316                 db_lhistory = NULL;
  317         }
  318         if (db_lhistory == NULL) {
  319                 /* Initialize input line history. */
  320                 db_lhistory = db_lhistory_buffer;
  321                 db_lhist_nlines = (sizeof db_lhistory_buffer) / lsize;
  322                 db_lhistlsize = lsize;
  323                 db_lhistidx = -1;
  324         }
  325         db_lhistcur = db_lhistidx;
  326 
  327         db_force_whitespace();  /* synch output position */
  328 
  329         db_lbuf_start = lstart;
  330         db_lbuf_end   = lstart + lsize;
  331         db_lc = lstart;
  332         db_le = lstart;
  333 
  334         while (!db_inputchar(cngetc()))
  335             continue;
  336 
  337         db_printf("\n");        /* synch output position */
  338         *db_le = 0;
  339 
  340         if (db_lhistory && (db_le - db_lbuf_start > 1)) {
  341             /* Maintain input line history for non-empty lines. */
  342             if (++db_lhistidx == db_lhist_nlines) {
  343                 /* Rotate history. */
  344                 ovbcopy(db_lhistory + db_lhistlsize, db_lhistory,
  345                         db_lhistlsize * (db_lhist_nlines - 1));
  346                 db_lhistidx--;
  347             }
  348             bcopy(lstart, db_lhistory + (db_lhistidx * db_lhistlsize),
  349                   db_lhistlsize);
  350         }
  351 
  352         return (db_le - db_lbuf_start);
  353 }
  354 
  355 void
  356 db_check_interrupt()
  357 {
  358         register int    c;
  359 
  360         c = cnmaygetc();
  361         switch (c) {
  362             case -1:            /* no character */
  363                 return;
  364 
  365             case CTRL('c'):
  366                 db_error((char *)0);
  367                 /*NOTREACHED*/
  368 
  369             case CTRL('s'):
  370                 do {
  371                     c = cnmaygetc();
  372                     if (c == CTRL('c'))
  373                         db_error((char *)0);
  374                 } while (c != CTRL('q'));
  375                 break;
  376 
  377             default:
  378                 /* drop on floor */
  379                 break;
  380         }
  381 }
  382 
  383 /* called from kdb_trap in db_interface.c */
  384 void
  385 cnpollc (flag)
  386         int flag;
  387 {
  388 }

Cache object: 5fec888fc094ad6c1fecb4e86bc90a32


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.