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$
   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/systm.h>
   36 
   37 #include <machine/cons.h>
   38 
   39 #include <ddb/ddb.h>
   40 #include <ddb/db_output.h>
   41 
   42 /*
   43  * Character input and editing.
   44  */
   45 
   46 /*
   47  * We don't track output position while editing input,
   48  * since input always ends with a new-line.  We just
   49  * reset the line position at the end.
   50  */
   51 static char *   db_lbuf_start;  /* start of input line buffer */
   52 static char *   db_lbuf_end;    /* end of input line buffer */
   53 static char *   db_lc;          /* current character */
   54 static char *   db_le;          /* one past last character */
   55 
   56 /*
   57  * Simple input line history support.
   58  */
   59 static char     db_lhistory[2048];
   60 static int      db_lhistlsize, db_lhistidx, db_lhistcur;
   61 static int      db_lhist_nlines;
   62 
   63 #define CTRL(c)         ((c) & 0x1f)
   64 #define isspace(c)      ((c) == ' ' || (c) == '\t')
   65 #define BLANK           ' '
   66 #define BACKUP          '\b'
   67 
   68 static int      cnmaygetc __P((void));
   69 static void     db_delete __P((int n, int bwd));
   70 static int      db_inputchar __P((int c));
   71 static void     db_putnchars __P((int c, int count));
   72 static void     db_putstring __P((char *s, int count));
   73 
   74 void
   75 db_putstring(s, count)
   76         char    *s;
   77         int     count;
   78 {
   79         while (--count >= 0)
   80             cnputc(*s++);
   81 }
   82 
   83 void
   84 db_putnchars(c, count)
   85         int     c;
   86         int     count;
   87 {
   88         while (--count >= 0)
   89             cnputc(c);
   90 }
   91 
   92 /*
   93  * Delete N characters, forward or backward
   94  */
   95 #define DEL_FWD         0
   96 #define DEL_BWD         1
   97 void
   98 db_delete(n, bwd)
   99         int     n;
  100         int     bwd;
  101 {
  102         register char *p;
  103 
  104         if (bwd) {
  105             db_lc -= n;
  106             db_putnchars(BACKUP, n);
  107         }
  108         for (p = db_lc; p < db_le-n; p++) {
  109             *p = *(p+n);
  110             cnputc(*p);
  111         }
  112         db_putnchars(BLANK, n);
  113         db_putnchars(BACKUP, db_le - db_lc);
  114         db_le -= n;
  115 }
  116 
  117 /* returns TRUE at end-of-line */
  118 int
  119 db_inputchar(c)
  120         int     c;
  121 {
  122         static int escstate;
  123 
  124         if (escstate == 1) {
  125                 /* ESC seen, look for [ or O */
  126                 if (c == '[' || c == 'O')
  127                         escstate++;
  128                 else
  129                         escstate = 0; /* re-init state machine */
  130                 return (0);
  131         } else if (escstate == 2) {
  132                 escstate = 0;
  133                 /*
  134                  * If a valid cursor key has been found, translate
  135                  * into an emacs-style control key, and fall through.
  136                  * Otherwise, drop off.
  137                  */
  138                 switch (c) {
  139                 case 'A':       /* up */
  140                         c = CTRL('p');
  141                         break;
  142                 case 'B':       /* down */
  143                         c = CTRL('n');
  144                         break;
  145                 case 'C':       /* right */
  146                         c = CTRL('f');
  147                         break;
  148                 case 'D':       /* left */
  149                         c = CTRL('b');
  150                         break;
  151                 default:
  152                         return (0);
  153                 }
  154         }
  155 
  156         switch (c) {
  157             case CTRL('['):
  158                 escstate = 1;
  159                 break;
  160             case CTRL('b'):
  161                 /* back up one character */
  162                 if (db_lc > db_lbuf_start) {
  163                     cnputc(BACKUP);
  164                     db_lc--;
  165                 }
  166                 break;
  167             case CTRL('f'):
  168                 /* forward one character */
  169                 if (db_lc < db_le) {
  170                     cnputc(*db_lc);
  171                     db_lc++;
  172                 }
  173                 break;
  174             case CTRL('a'):
  175                 /* beginning of line */
  176                 while (db_lc > db_lbuf_start) {
  177                     cnputc(BACKUP);
  178                     db_lc--;
  179                 }
  180                 break;
  181             case CTRL('e'):
  182                 /* end of line */
  183                 while (db_lc < db_le) {
  184                     cnputc(*db_lc);
  185                     db_lc++;
  186                 }
  187                 break;
  188             case CTRL('h'):
  189             case 0177:
  190                 /* erase previous character */
  191                 if (db_lc > db_lbuf_start)
  192                     db_delete(1, DEL_BWD);
  193                 break;
  194             case CTRL('d'):
  195                 /* erase next character */
  196                 if (db_lc < db_le)
  197                     db_delete(1, DEL_FWD);
  198                 break;
  199             case CTRL('k'):
  200                 /* delete to end of line */
  201                 if (db_lc < db_le)
  202                     db_delete(db_le - db_lc, DEL_FWD);
  203                 break;
  204             case CTRL('t'):
  205                 /* twiddle last 2 characters */
  206                 if (db_lc >= db_lbuf_start + 2) {
  207                     c = db_lc[-2];
  208                     db_lc[-2] = db_lc[-1];
  209                     db_lc[-1] = c;
  210                     cnputc(BACKUP);
  211                     cnputc(BACKUP);
  212                     cnputc(db_lc[-2]);
  213                     cnputc(db_lc[-1]);
  214                 }
  215                 break;
  216             case CTRL('r'):
  217                 db_putstring("^R\n", 3);
  218             redraw:
  219                 if (db_le > db_lbuf_start) {
  220                     db_putstring(db_lbuf_start, db_le - db_lbuf_start);
  221                     db_putnchars(BACKUP, db_le - db_lc);
  222                 }
  223                 break;
  224             case CTRL('p'):
  225                 /* Make previous history line the active one. */
  226                 if (db_lhistcur >= 0) {
  227                     bcopy(db_lhistory + db_lhistcur * db_lhistlsize,
  228                           db_lbuf_start, db_lhistlsize);
  229                     db_lhistcur--;
  230                     goto hist_redraw;
  231                 }
  232                 break;
  233             case CTRL('n'):
  234                 /* Make next history line the active one. */
  235                 if (db_lhistcur < db_lhistidx - 1) {
  236                     db_lhistcur += 2;
  237                     bcopy(db_lhistory + db_lhistcur * db_lhistlsize,
  238                           db_lbuf_start, db_lhistlsize);
  239                 } else {
  240                     /*
  241                      * ^N through tail of history, reset the
  242                      * buffer to zero length.
  243                      */
  244                     *db_lbuf_start = '\0';
  245                     db_lhistcur = db_lhistidx;
  246                 }
  247 
  248             hist_redraw:
  249                 db_putnchars(BACKUP, db_le - db_lbuf_start);
  250                 db_putnchars(BLANK, db_le - db_lbuf_start);
  251                 db_putnchars(BACKUP, db_le - db_lbuf_start);
  252                 db_le = index(db_lbuf_start, '\0');
  253                 if (db_le[-1] == '\r' || db_le[-1] == '\n')
  254                     *--db_le = '\0';
  255                 db_lc = db_le;
  256                 goto redraw;
  257 
  258             case -1:
  259                 /*
  260                  * eek! the console returned eof.
  261                  * probably that means we HAVE no console.. we should try bail
  262                  * XXX
  263                  */
  264                 c = '\r';
  265             case '\n':
  266             case '\r':
  267                 *db_le++ = c;
  268                 return (1);
  269             default:
  270                 if (db_le == db_lbuf_end) {
  271                     cnputc('\007');
  272                 }
  273                 else if (c >= ' ' && c <= '~') {
  274                     register char *p;
  275 
  276                     for (p = db_le; p > db_lc; p--)
  277                         *p = *(p-1);
  278                     *db_lc++ = c;
  279                     db_le++;
  280                     cnputc(c);
  281                     db_putstring(db_lc, db_le - db_lc);
  282                     db_putnchars(BACKUP, db_le - db_lc);
  283                 }
  284                 break;
  285         }
  286         return (0);
  287 }
  288 
  289 int
  290 cnmaygetc()
  291 {
  292         return (-1);
  293 }
  294 
  295 int
  296 db_readline(lstart, lsize)
  297         char *  lstart;
  298         int     lsize;
  299 {
  300         if (lsize != db_lhistlsize) {
  301                 /*
  302                  * (Re)initialize input line history.  Throw away any
  303                  * existing history.
  304                  */
  305                 db_lhist_nlines = sizeof(db_lhistory) / lsize;
  306                 db_lhistlsize = lsize;
  307                 db_lhistidx = -1;
  308         }
  309         db_lhistcur = db_lhistidx;
  310 
  311         db_force_whitespace();  /* synch output position */
  312 
  313         db_lbuf_start = lstart;
  314         db_lbuf_end   = lstart + lsize;
  315         db_lc = lstart;
  316         db_le = lstart;
  317 
  318         while (!db_inputchar(cngetc()))
  319             continue;
  320 
  321         db_printf("\n");        /* synch output position */
  322         *db_le = 0;
  323 
  324         if (db_le - db_lbuf_start > 1) {
  325             /* Maintain input line history for non-empty lines. */
  326             if (++db_lhistidx == db_lhist_nlines) {
  327                 /* Rotate history. */
  328                 ovbcopy(db_lhistory + db_lhistlsize, db_lhistory,
  329                         db_lhistlsize * (db_lhist_nlines - 1));
  330                 db_lhistidx--;
  331             }
  332             bcopy(lstart, db_lhistory + db_lhistidx * db_lhistlsize,
  333                   db_lhistlsize);
  334         }
  335 
  336         return (db_le - db_lbuf_start);
  337 }
  338 
  339 void
  340 db_check_interrupt()
  341 {
  342         register int    c;
  343 
  344         c = cnmaygetc();
  345         switch (c) {
  346             case -1:            /* no character */
  347                 return;
  348 
  349             case CTRL('c'):
  350                 db_error((char *)0);
  351                 /*NOTREACHED*/
  352 
  353             case CTRL('s'):
  354                 do {
  355                     c = cnmaygetc();
  356                     if (c == CTRL('c'))
  357                         db_error((char *)0);
  358                 } while (c != CTRL('q'));
  359                 break;
  360 
  361             default:
  362                 /* drop on floor */
  363                 break;
  364         }
  365 }
  366 
  367 /* called from kdb_trap in db_interface.c */
  368 void
  369 cnpollc (flag)
  370         int flag;
  371 {
  372 }

Cache object: 96ea72c71650e2e67fd3afa835979c72


[ 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.