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 /*      $OpenBSD: db_input.c,v 1.19 2020/10/15 03:14:00 deraadt Exp $   */
    2 /*      $NetBSD: db_input.c,v 1.7 1996/02/05 01:57:02 christos Exp $    */
    3 
    4 /*
    5  * Mach Operating System
    6  * Copyright (c) 1993,1992,1991,1990 Carnegie Mellon University
    7  * All Rights Reserved.
    8  *
    9  * Permission to use, copy, modify and distribute this software and its
   10  * documentation is hereby granted, provided that both the copyright
   11  * notice and this permission notice appear in all copies of the
   12  * software, derivative works or modified versions, and any portions
   13  * thereof, and that both notices appear in supporting documentation.
   14  *
   15  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   16  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   17  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   18  *
   19  * Carnegie Mellon requests users of this software to return to
   20  *
   21  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   22  *  School of Computer Science
   23  *  Carnegie Mellon University
   24  *  Pittsburgh PA 15213-3890
   25  *
   26  * any improvements or extensions that they make and grant Carnegie Mellon
   27  * the rights to redistribute these changes.
   28  *
   29  *      Author: David B. Golub, Carnegie Mellon University
   30  *      Date:   7/90
   31  */
   32 
   33 #include <sys/param.h>
   34 #include <sys/systm.h>
   35 
   36 #include <machine/db_machdep.h>
   37 
   38 #include <ddb/db_var.h>
   39 #include <ddb/db_output.h>
   40 #include <ddb/db_sym.h>
   41 #include <ddb/db_extern.h>
   42 
   43 #include <dev/cons.h>
   44 
   45 /*
   46  * Character input and editing.
   47  */
   48 
   49 void db_putstring(char *, int);
   50 void db_putnchars(int, int);
   51 void db_delete(int, int);
   52 void db_delete_line(void);
   53 int db_inputchar(int);
   54 
   55 /*
   56  * We don't track output position while editing input,
   57  * since input always ends with a new-line.  We just
   58  * reset the line position at the end.
   59  */
   60 char *  db_lbuf_start;  /* start of input line buffer */
   61 char *  db_lbuf_end;    /* end of input line buffer */
   62 char *  db_lc;          /* current character */
   63 char *  db_le;          /* one past last character */
   64 #if DB_HISTORY_SIZE != 0
   65 char    db_history[DB_HISTORY_SIZE];    /* start of history buffer */
   66 int     db_history_size = DB_HISTORY_SIZE;/* size of history buffer */
   67 char *  db_history_curr = db_history;   /* start of current line */
   68 char *  db_history_last = db_history;   /* start of last line */
   69 char *  db_history_prev = (char *) 0;   /* start of previous line */
   70 #endif
   71 
   72 
   73 #define CTRL(c)         ((c) & 0x1f)
   74 #define isspace(c)      ((c) == ' ' || (c) == '\t')
   75 #define BLANK           ' '
   76 #define BACKUP          '\b'
   77 
   78 void
   79 db_putstring(char *s, int count)
   80 {
   81         while (--count >= 0)
   82                 cnputc(*s++);
   83 }
   84 
   85 void
   86 db_putnchars(int c, 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(int n, int bwd)
   99 {
  100         char *p;
  101 
  102         if (bwd) {
  103                 db_lc -= n;
  104                 db_putnchars(BACKUP, n);
  105         }
  106         for (p = db_lc; p < db_le-n; p++) {
  107                 *p = *(p+n);
  108                 cnputc(*p);
  109         }
  110         db_putnchars(BLANK, n);
  111         db_putnchars(BACKUP, db_le - db_lc);
  112         db_le -= n;
  113 }
  114 
  115 void
  116 db_delete_line(void)
  117 {
  118         db_delete(db_le - db_lc, DEL_FWD);
  119         db_delete(db_lc - db_lbuf_start, DEL_BWD);
  120         db_le = db_lc = db_lbuf_start;
  121 }
  122 
  123 #if DB_HISTORY_SIZE != 0
  124 #define INC_DB_CURR() \
  125         do { \
  126                 db_history_curr++; \
  127                 if (db_history_curr > \
  128                         db_history + db_history_size - 1) \
  129                         db_history_curr = db_history; \
  130         } while (0)
  131 #define DEC_DB_CURR() \
  132         do { \
  133                 db_history_curr--; \
  134                 if (db_history_curr < db_history) \
  135                         db_history_curr = db_history + \
  136                         db_history_size - 1; \
  137         } while (0)
  138 #endif
  139 
  140 /* returns `1' at end-of-line */
  141 int
  142 db_inputchar(int c)
  143 {
  144         switch (c) {
  145         case CTRL('b'):
  146                 /* back up one character */
  147                 if (db_lc > db_lbuf_start) {
  148                         cnputc(BACKUP);
  149                         db_lc--;
  150                 }
  151                 break;
  152         case CTRL('f'):
  153                 /* forward one character */
  154                 if (db_lc < db_le) {
  155                         cnputc(*db_lc);
  156                         db_lc++;
  157                 }
  158                 break;
  159         case CTRL('a'):
  160                 /* beginning of line */
  161                 while (db_lc > db_lbuf_start) {
  162                         cnputc(BACKUP);
  163                         db_lc--;
  164                 }
  165                 break;
  166         case CTRL('e'):
  167                 /* end of line */
  168                 while (db_lc < db_le) {
  169                         cnputc(*db_lc);
  170                         db_lc++;
  171                 }
  172                 break;
  173         case CTRL('w'):
  174                 /* erase word back */
  175                 while (db_lc > db_lbuf_start && db_lc[-1] != BLANK)
  176                         db_delete(1, DEL_BWD);
  177                 break;
  178         case CTRL('h'):
  179         case 0177:
  180                 /* erase previous character */
  181                 if (db_lc > db_lbuf_start)
  182                         db_delete(1, DEL_BWD);
  183                 break;
  184         case CTRL('d'):
  185                 /* erase next character */
  186                 if (db_lc < db_le)
  187                         db_delete(1, DEL_FWD);
  188                 break;
  189         case CTRL('k'):
  190                 /* delete to end of line */
  191                 if (db_lc < db_le)
  192                         db_delete(db_le - db_lc, DEL_FWD);
  193                 break;
  194         case CTRL('u'):
  195                 /* delete line */
  196                 db_delete_line();
  197                 break;
  198         case CTRL('t'):
  199                 /* twiddle last 2 characters */
  200                 if (db_lc >= db_lbuf_start + 2) {
  201                         c = db_lc[-2];
  202                         db_lc[-2] = db_lc[-1];
  203                         db_lc[-1] = c;
  204                         cnputc(BACKUP);
  205                         cnputc(BACKUP);
  206                         cnputc(db_lc[-2]);
  207                         cnputc(db_lc[-1]);
  208                 }
  209                 break;
  210 #if DB_HISTORY_SIZE != 0
  211         case CTRL('p'):
  212                 DEC_DB_CURR();
  213                 while (db_history_curr != db_history_last) {
  214                         DEC_DB_CURR();
  215                         if (*db_history_curr == '\0')
  216                                 break;
  217                 }
  218                 db_delete_line();
  219                 if (db_history_curr == db_history_last) {
  220                         INC_DB_CURR();
  221                         db_le = db_lc = db_lbuf_start;
  222                 } else {
  223                         char *p;
  224                         INC_DB_CURR();
  225                         for (p = db_history_curr,
  226                             db_le = db_lbuf_start;*p; ) {
  227                                 *db_le++ = *p++;
  228                                 if (p == db_history + db_history_size)
  229                                         p = db_history;
  230                         }
  231                         db_lc = db_le;
  232                 }
  233                 db_putstring(db_lbuf_start, db_le - db_lbuf_start);
  234                 break;
  235         case CTRL('n'):
  236                 while (db_history_curr != db_history_last) {
  237                         if (*db_history_curr == '\0')
  238                                 break;
  239                         INC_DB_CURR();
  240                 }
  241                 if (db_history_curr != db_history_last) {
  242                         INC_DB_CURR();
  243                         db_delete_line();
  244                         if (db_history_curr != db_history_last) {
  245                                 char *p;
  246                                 for (p = db_history_curr,
  247                                      db_le = db_lbuf_start; *p;) {
  248                                         *db_le++ = *p++;
  249                                         if (p == db_history + db_history_size)
  250                                                 p = db_history;
  251                                 }
  252                                 db_lc = db_le;
  253                         }
  254                         db_putstring(db_lbuf_start, db_le - db_lbuf_start);
  255                 }
  256                 break;
  257 #endif
  258         case CTRL('r'):
  259                 db_putstring("^R\n", 3);
  260                 if (db_le > db_lbuf_start) {
  261                         db_putstring(db_lbuf_start, db_le - db_lbuf_start);
  262                         db_putnchars(BACKUP, db_le - db_lc);
  263                 }
  264                 break;
  265         case '\n':
  266         case '\r':
  267 #if DB_HISTORY_SIZE != 0
  268                 /*
  269                  * Check whether current line is the same
  270                  * as previous saved line.  If it is, don`t
  271                  * save it.
  272                  */
  273                 if (db_history_curr == db_history_prev) {
  274                         char *pp, *pc;
  275 
  276                         /*
  277                          * Is it the same?
  278                          */
  279                         for (pp = db_history_prev, pc = db_lbuf_start;
  280                             pc != db_le && *pp; ) {
  281                                 if (*pp != *pc)
  282                                         break;
  283                                 if (++pp == db_history + db_history_size)
  284                                         pp = db_history;
  285                                 pc++;
  286                         }
  287                         if (!*pp && pc == db_le) {
  288                                 /*
  289                                  * Repeated previous line. Don`t save.
  290                                  */
  291                                 db_history_curr = db_history_last;
  292                                 *db_le++ = c;
  293                                 return 1;
  294                         }
  295                 }
  296                 if (db_le != db_lbuf_start) {
  297                         char *p;
  298                         db_history_prev = db_history_last;
  299                         for (p = db_lbuf_start; p != db_le; p++) {
  300                                 *db_history_last++ = *p;
  301                                 if (db_history_last ==
  302                                     db_history + db_history_size)
  303                                         db_history_last = db_history;
  304                         }
  305                         *db_history_last++ = '\0';
  306                         if (db_history_last == db_history + db_history_size)
  307                                 db_history_last = db_history;
  308                 }
  309                 db_history_curr = db_history_last;
  310 #endif
  311                 *db_le++ = c;
  312                 return 1;
  313         default:
  314                 if (db_le == db_lbuf_end) {
  315                         cnputc('\007');
  316                 } else if (c >= ' ' && c <= '~') {
  317                         char *p;
  318 
  319                         for (p = db_le; p > db_lc; p--)
  320                                 *p = *(p-1);
  321                         *db_lc++ = c;
  322                         db_le++;
  323                         cnputc(c);
  324                         db_putstring(db_lc, db_le - db_lc);
  325                         db_putnchars(BACKUP, db_le - db_lc);
  326                 }
  327                 break;
  328         }
  329         return 0;
  330 }
  331 
  332 int
  333 db_readline(char *lstart, int lsize)
  334 {
  335         db_force_whitespace();  /* synch output position */
  336 
  337         db_lbuf_start = lstart;
  338         db_lbuf_end   = lstart + lsize - 1;
  339         db_lc = lstart;
  340         db_le = lstart;
  341 
  342         while (!db_inputchar(cngetc()))
  343                 continue;
  344 
  345         db_putchar('\n');       /* synch output position */
  346 
  347         *db_le = 0;
  348         return (db_le - db_lbuf_start);
  349 }

Cache object: fbe93c8f1bb84bfed4974d4d61affa72


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