LCOV - app.info - js/src/editline/editline.c

LCOV - code coverage report
| Current view: | directory - js/src/editline - editline.c (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 584 | 0 | 0.0 %
| Date: | 2012-04-07 | Functions: | 67 | 0 | 0.0 %

           1                 : /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
           2                 :  *
           3                 :  * ***** BEGIN LICENSE BLOCK *****
           4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           5                 :  *
           6                 :  * The contents of this file are subject to the Mozilla Public License Version
           7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           8                 :  * the License. You may obtain a copy of the License at
           9                 :  * http://www.mozilla.org/MPL/
          10                 :  *
          11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          13                 :  * for the specific language governing rights and limitations under the
          14                 :  * License.
          15                 :  *
          16                 :  * The Original Code is Mozilla Communicator client code, released
          17                 :  * March 31, 1998.
          18                 :  *
          19                 :  * The Initial Developer of the Original Code is
          20                 :  * Simmule Turner and Rich Salz.
          21                 :  * Portions created by the Initial Developer are Copyright (C) 1998
          22                 :  * the Initial Developer. All Rights Reserved.
          23                 :  *
          24                 :  * Contributor(s):
          25                 :  *
          26                 :  * Alternatively, the contents of this file may be used under the terms of
          27                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
          28                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          30                 :  * of those above. If you wish to allow use of your version of this file only
          31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          32                 :  * use your version of this file under the terms of the MPL, indicate your
          33                 :  * decision by deleting the provisions above and replace them with the notice
          34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          35                 :  * the provisions above, a recipient may use your version of this file under
          36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          37                 :  *
          38                 :  * ***** END LICENSE BLOCK ***** */
          39                 :
          40                 : /*
          41                 :  * Copyright 1992,1993 Simmule Turner and Rich Salz.  All rights reserved.
          42                 :  *
          43                 :  * This software is not subject to any license of the American Telephone
          44                 :  * and Telegraph Company or of the Regents of the University of California.
          45                 :  *
          46                 :  * Permission is granted to anyone to use this software for any purpose on
          47                 :  * any computer system, and to alter it and redistribute it freely, subject
          48                 :  * to the following restrictions:
          49                 :  * 1. The authors are not responsible for the consequences of use of this
          50                 :  *    software, no matter how awful, even if they arise from flaws in it.
          51                 :  * 2. The origin of this software must not be misrepresented, either by
          52                 :  *    explicit claim or by omission.  Since few users ever read sources,
          53                 :  *    credits must appear in the documentation.
          54                 :  * 3. Altered versions must be plainly marked as such, and must not be
          55                 :  *    misrepresented as being the original software.  Since few users
          56                 :  *    ever read sources, credits must appear in the documentation.
          57                 :  * 4. This notice may not be removed or altered.
          58                 :  */
          59                 :
          60                 :
          61                 : /*
          62                 : **  Main editing routines for editline library.
          63                 : */
          64                 : #include "editline.h"
          65                 : #include <signal.h>
          66                 : #include <ctype.h>
          67                 : #include <unistd.h>
          68                 :
          69                 : /*
          70                 : **  Manifest constants.
          71                 : */
          72                 : #define SCREEN_WIDTH    80
          73                 : #define SCREEN_ROWS     24
          74                 : #define NO_ARG          (-1)
          75                 : #define DEL             127
          76                 : #define CTL(x)          ((x) & 0x1F)
          77                 : #define ISCTL(x)        ((x) && (x) < ' ')
          78                 : #define UNCTL(x)        ((x) + 64)
          79                 : #define META(x)         ((x) | 0x80)
          80                 : #define ISMETA(x)       ((x) & 0x80)
          81                 : #define UNMETA(x)       ((x) & 0x7F)
          82                 : #if     !defined(HIST_SIZE)
          83                 : #define HIST_SIZE       20
          84                 : #endif  /* !defined(HIST_SIZE) */
          85                 :
          86                 : /*
          87                 : **  Command status codes.
          88                 : */
          89                 : typedef enum _STATUS {
          90                 :     CSdone, CSeof, CSmove, CSdispatch, CSstay, CSsignal
          91                 : } STATUS;
          92                 :
          93                 : /*
          94                 : **  The type of case-changing to perform.
          95                 : */
          96                 : typedef enum _CASE {
          97                 :     TOupper, TOlower
          98                 : } CASE;
          99                 :
         100                 : /*
         101                 : **  Key to command mapping.
         102                 : */
         103                 : typedef struct _KEYMAP {
         104                 :     CHAR        Key;
         105                 :     STATUS      (*Function)();
         106                 : } KEYMAP;
         107                 :
         108                 : /*
         109                 : **  Command history structure.
         110                 : */
         111                 : typedef struct _HISTORY {
         112                 :     int         Size;
         113                 :     int         Pos;
         114                 :     CHAR        *Lines[HIST_SIZE];
         115                 : } HISTORY;
         116                 :
         117                 : /*
         118                 : **  Globals.
         119                 : */
         120                 : unsigned        rl_eof;
         121                 : unsigned        rl_erase;
         122                 : unsigned        rl_intr;
         123                 : unsigned        rl_kill;
         124                 : unsigned        rl_quit;
         125                 :
         126                 : STATIC CHAR             NIL[] = "";
         127                 : STATIC CONST CHAR       *Input = NIL;
         128                 : STATIC CHAR             *Line;
         129                 : STATIC CONST char       *Prompt;
         130                 : STATIC CHAR             *Yanked;
         131                 : STATIC char             *Screen;
         132                 : STATIC char             NEWLINE[]= CRLF;
         133                 : STATIC HISTORY          H;
         134                 : STATIC int              Repeat;
         135                 : STATIC int              End;
         136                 : STATIC int              Mark;
         137                 : STATIC int              OldPoint;
         138                 : STATIC int              Point;
         139                 : STATIC int              PushBack;
         140                 : STATIC int              Pushed;
         141                 : STATIC int              Signal;
         142                 : FORWARD KEYMAP          Map[32];
         143                 : FORWARD KEYMAP          MetaMap[16];
         144                 : STATIC SIZE_T           Length;
         145                 : STATIC SIZE_T           ScreenCount;
         146                 : STATIC SIZE_T           ScreenSize;
         147                 : STATIC char             *backspace;
         148                 : STATIC int              TTYwidth;
         149                 : STATIC int              TTYrows;
         150                 :
         151                 : /* Display print 8-bit chars as `M-x' or as the actual 8-bit char? */
         152                 : int             rl_meta_chars = 0;
         153                 :
         154                 : /*
         155                 : **  Declarations.
         156                 : */
         157                 : STATIC CHAR     *editinput();
         158                 : #if     defined(USE_TERMCAP)
         159                 : #include <stdlib.h>
         160                 : #include <curses.h>
         161                 : #include <term.h>
         162                 : #endif  /* defined(USE_TERMCAP) */
         163                 :
         164                 : /*
         165                 : **  TTY input/output functions.
         166                 : */
         167                 :
         168                 : STATIC void
         169               0 : TTYflush()
         170                 : {
         171               0 :     if (ScreenCount) {
         172                 :         /* Dummy assignment avoids GCC warning on
         173                 :          * "attribute warn_unused_result" */
         174               0 :         ssize_t dummy = write(1, Screen, ScreenCount);
         175                 :         (void)dummy;
         176               0 :         ScreenCount = 0;
         177                 :     }
         178               0 : }
         179                 :
         180                 : STATIC void
         181               0 : TTYput(c)
         182                 :     CHAR        c;
         183                 : {
         184               0 :     Screen[ScreenCount] = c;
         185               0 :     if (++ScreenCount >= ScreenSize - 1) {
         186               0 :         ScreenSize += SCREEN_INC;
         187               0 :         RENEW(Screen, char, ScreenSize);
         188                 :     }
         189               0 : }
         190                 :
         191                 : STATIC void
         192               0 : TTYputs(p)
         193                 :     CONST CHAR  *p;
         194                 : {
         195               0 :     while (*p)
         196               0 :         TTYput(*p++);
         197               0 : }
         198                 :
         199                 : STATIC void
         200               0 : TTYshow(c)
         201                 :     CHAR        c;
         202                 : {
         203               0 :     if (c == DEL) {
         204               0 :         TTYput('^');
         205               0 :         TTYput('?');
         206                 :     }
         207               0 :     else if (ISCTL(c)) {
         208               0 :         TTYput('^');
         209               0 :         TTYput(UNCTL(c));
         210                 :     }
         211               0 :     else if (rl_meta_chars && ISMETA(c)) {
         212               0 :         TTYput('M');
         213               0 :         TTYput('-');
         214               0 :         TTYput(UNMETA(c));
         215                 :     }
         216                 :     else
         217               0 :         TTYput(c);
         218               0 : }
         219                 :
         220                 : STATIC void
         221               0 : TTYstring(p)
         222                 :     CHAR        *p;
         223                 : {
         224               0 :     while (*p)
         225               0 :         TTYshow(*p++);
         226               0 : }
         227                 :
         228                 : STATIC unsigned int
         229               0 : TTYget()
         230                 : {
         231                 :     CHAR        c;
         232                 :
         233               0 :     TTYflush();
         234               0 :     if (Pushed) {
         235               0 :         Pushed = 0;
         236               0 :         return PushBack;
         237                 :     }
         238               0 :     if (*Input)
         239               0 :         return *Input++;
         240               0 :     return read(0, &c, (SIZE_T)1) == 1 ? c : EOF;
         241                 : }
         242                 :
         243                 : #define TTYback()       (backspace ? TTYputs((CHAR *)backspace) : TTYput('\b'))
         244                 :
         245                 : STATIC void
         246               0 : TTYbackn(n)
         247                 :     int         n;
         248                 : {
         249               0 :     while (--n >= 0)
         250               0 :         TTYback();
         251               0 : }
         252                 :
         253                 : STATIC void
         254               0 : TTYinfo()
         255                 : {
         256                 :     static int          init;
         257                 : #if     defined(USE_TERMCAP)
         258                 :     char                *term;
         259                 :     char                buff[2048];
         260                 :     char                *bp, *p;
         261                 : #endif  /* defined(USE_TERMCAP) */
         262                 : #if     defined(TIOCGWINSZ)
         263                 :     struct winsize      W;
         264                 : #endif  /* defined(TIOCGWINSZ) */
         265                 :
         266               0 :     if (init) {
         267                 : #if     defined(TIOCGWINSZ)
         268                 :         /* Perhaps we got resized. */
         269                 :         if (ioctl(0, TIOCGWINSZ, &W) >= 0
         270                 :          && W.ws_col > 0 && W.ws_row > 0) {
         271                 :             TTYwidth = (int)W.ws_col;
         272                 :             TTYrows = (int)W.ws_row;
         273                 :         }
         274                 : #endif  /* defined(TIOCGWINSZ) */
         275               0 :         return;
         276                 :     }
         277               0 :     init++;
         278                 :
         279               0 :     TTYwidth = TTYrows = 0;
         280                 : #if     defined(USE_TERMCAP)
         281                 :     bp = &buff[0];
         282                 :     if ((term = getenv("TERM")) == NULL)
         283                 :         term = "dumb";
         284                 :     if (tgetent(buff, term) < 0) {
         285                 :        TTYwidth = SCREEN_WIDTH;
         286                 :        TTYrows = SCREEN_ROWS;
         287                 :        return;
         288                 :     }
         289                 :     p = tgetstr("le", &bp);
         290                 :     backspace = p ? strdup(p) : NULL;
         291                 :     TTYwidth = tgetnum("co");
         292                 :     TTYrows = tgetnum("li");
         293                 : #endif  /* defined(USE_TERMCAP) */
         294                 :
         295                 : #if     defined(TIOCGWINSZ)
         296                 :     if (ioctl(0, TIOCGWINSZ, &W) >= 0) {
         297                 :         TTYwidth = (int)W.ws_col;
         298                 :         TTYrows = (int)W.ws_row;
         299                 :     }
         300                 : #endif  /* defined(TIOCGWINSZ) */
         301                 :
         302               0 :     if (TTYwidth <= 0 || TTYrows <= 0) {
         303               0 :         TTYwidth = SCREEN_WIDTH;
         304               0 :         TTYrows = SCREEN_ROWS;
         305                 :     }
         306                 : }
         307                 :
         308                 :
         309                 : STATIC void
         310               0 : reposition()
         311                 : {
         312                 :     int         i;
         313                 :     CHAR        *p;
         314                 :
         315               0 :     TTYput('\r');
         316               0 :     TTYputs((CONST CHAR *)Prompt);
         317               0 :     for (i = Point, p = Line; --i >= 0; p++)
         318               0 :         TTYshow(*p);
         319               0 : }
         320                 :
         321                 : STATIC void
         322               0 : left(Change)
         323                 :     STATUS      Change;
         324                 : {
         325               0 :     TTYback();
         326               0 :     if (Point) {
         327               0 :         if (ISCTL(Line[Point - 1]))
         328               0 :             TTYback();
         329               0 :         else if (rl_meta_chars && ISMETA(Line[Point - 1])) {
         330               0 :             TTYback();
         331               0 :             TTYback();
         332                 :         }
         333                 :     }
         334               0 :     if (Change == CSmove)
         335               0 :         Point--;
         336               0 : }
         337                 :
         338                 : STATIC void
         339               0 : right(Change)
         340                 :     STATUS      Change;
         341                 : {
         342               0 :     TTYshow(Line[Point]);
         343               0 :     if (Change == CSmove)
         344               0 :         Point++;
         345               0 : }
         346                 :
         347                 : STATIC STATUS
         348               0 : ring_bell()
         349                 : {
         350               0 :     TTYput('\07');
         351               0 :     TTYflush();
         352               0 :     return CSstay;
         353                 : }
         354                 :
         355                 : STATIC STATUS
         356               0 : do_macro(c)
         357                 :     unsigned int        c;
         358                 : {
         359                 :     CHAR                name[4];
         360                 :
         361               0 :     name[0] = '_';
         362               0 :     name[1] = c;
         363               0 :     name[2] = '_';
         364               0 :     name[3] = '\0';
         365                 :
         366               0 :     if ((Input = (CHAR *)getenv((char *)name)) == NULL) {
         367               0 :         Input = NIL;
         368               0 :         return ring_bell();
         369                 :     }
         370               0 :     return CSstay;
         371                 : }
         372                 :
         373                 : STATIC STATUS
         374               0 : do_forward(move)
         375                 :     STATUS      move;
         376                 : {
         377                 :     int         i;
         378                 :     CHAR        *p;
         379                 :
         380               0 :     i = 0;
         381                 :     do {
         382               0 :         p = &Line[Point];
         383               0 :         for ( ; Point < End && (*p == ' ' || !isalnum(*p)); Point++, p++)
         384               0 :             if (move == CSmove)
         385               0 :                 right(CSstay);
         386                 :
         387               0 :         for (; Point < End && isalnum(*p); Point++, p++)
         388               0 :             if (move == CSmove)
         389               0 :                 right(CSstay);
         390                 :
         391               0 :         if (Point == End)
         392               0 :             break;
         393               0 :     } while (++i < Repeat);
         394                 :
         395               0 :     return CSstay;
         396                 : }
         397                 :
         398                 : STATIC STATUS
         399               0 : do_case(type)
         400                 :     CASE        type;
         401                 : {
         402                 :     int         i;
         403                 :     int         end;
         404                 :     int         count;
         405                 :     CHAR        *p;
         406                 :
         407               0 :     (void)do_forward(CSstay);
         408               0 :     if (OldPoint != Point) {
         409               0 :         if ((count = Point - OldPoint) < 0)
         410               0 :             count = -count;
         411               0 :         Point = OldPoint;
         412               0 :         if ((end = Point + count) > End)
         413               0 :             end = End;
         414               0 :         for (i = Point, p = &Line[i]; i < end; i++, p++) {
         415               0 :             if (type == TOupper) {
         416               0 :                 if (islower(*p))
         417               0 :                     *p = toupper(*p);
         418                 :             }
         419               0 :             else if (isupper(*p))
         420               0 :                 *p = tolower(*p);
         421               0 :             right(CSmove);
         422                 :         }
         423                 :     }
         424               0 :     return CSstay;
         425                 : }
         426                 :
         427                 : STATIC STATUS
         428               0 : case_down_word()
         429                 : {
         430               0 :     return do_case(TOlower);
         431                 : }
         432                 :
         433                 : STATIC STATUS
         434               0 : case_up_word()
         435                 : {
         436               0 :     return do_case(TOupper);
         437                 : }
         438                 :
         439                 : STATIC void
         440               0 : ceol()
         441                 : {
         442                 :     int         extras;
         443                 :     int         i;
         444                 :     CHAR        *p;
         445                 :
         446               0 :     for (extras = 0, i = Point, p = &Line[i]; i <= End; i++, p++) {
         447               0 :         TTYput(' ');
         448               0 :         if (ISCTL(*p)) {
         449               0 :             TTYput(' ');
         450               0 :             extras++;
         451                 :         }
         452               0 :         else if (rl_meta_chars && ISMETA(*p)) {
         453               0 :             TTYput(' ');
         454               0 :             TTYput(' ');
         455               0 :             extras += 2;
         456                 :         }
         457                 :     }
         458                 :
         459               0 :     for (i += extras; i > Point; i--)
         460               0 :         TTYback();
         461               0 : }
         462                 :
         463                 : STATIC void
         464               0 : clear_line()
         465                 : {
         466               0 :     Point = -strlen(Prompt);
         467               0 :     TTYput('\r');
         468               0 :     ceol();
         469               0 :     Point = 0;
         470               0 :     End = 0;
         471               0 :     Line[0] = '\0';
         472               0 : }
         473                 :
         474                 : STATIC STATUS
         475               0 : insert_string(p)
         476                 :     CHAR        *p;
         477                 : {
         478                 :     SIZE_T      len;
         479                 :     int         i;
         480                 :     CHAR        *new;
         481                 :     CHAR        *q;
         482                 :
         483               0 :     len = strlen((char *)p);
         484               0 :     if (End + len >= Length) {
         485               0 :         if ((new = NEW(CHAR, Length + len + MEM_INC)) == NULL)
         486               0 :             return CSstay;
         487               0 :         if (Length) {
         488               0 :             COPYFROMTO(new, Line, Length);
         489               0 :             DISPOSE(Line);
         490                 :         }
         491               0 :         Line = new;
         492               0 :         Length += len + MEM_INC;
         493                 :     }
         494                 :
         495               0 :     for (q = &Line[Point], i = End - Point; --i >= 0; )
         496               0 :         q[len + i] = q[i];
         497               0 :     COPYFROMTO(&Line[Point], p, len);
         498               0 :     End += len;
         499               0 :     Line[End] = '\0';
         500               0 :     TTYstring(&Line[Point]);
         501               0 :     Point += len;
         502                 :
         503               0 :     return Point == End ? CSstay : CSmove;
         504                 : }
         505                 :
         506                 : STATIC STATUS
         507               0 : redisplay()
         508                 : {
         509               0 :     TTYputs((CONST CHAR *)NEWLINE);
         510               0 :     TTYputs((CONST CHAR *)Prompt);
         511               0 :     TTYstring(Line);
         512               0 :     return CSmove;
         513                 : }
         514                 :
         515                 : STATIC STATUS
         516               0 : toggle_meta_mode()
         517                 : {
         518               0 :     rl_meta_chars = ! rl_meta_chars;
         519               0 :     return redisplay();
         520                 : }
         521                 :
         522                 :
         523                 : STATIC CHAR *
         524               0 : next_hist()
         525                 : {
         526               0 :     return H.Pos >= H.Size - 1 ? NULL : H.Lines[++H.Pos];
         527                 : }
         528                 :
         529                 : STATIC CHAR *
         530               0 : prev_hist()
         531                 : {
         532               0 :     return H.Pos == 0 ? NULL : H.Lines[--H.Pos];
         533                 : }
         534                 :
         535                 : STATIC STATUS
         536               0 : do_insert_hist(p)
         537                 :     CHAR        *p;
         538                 : {
         539               0 :     if (p == NULL)
         540               0 :         return ring_bell();
         541               0 :     Point = 0;
         542               0 :     reposition();
         543               0 :     ceol();
         544               0 :     End = 0;
         545               0 :     return insert_string(p);
         546                 : }
         547                 :
         548                 : STATIC STATUS
         549               0 : do_hist(move)
         550                 :     CHAR        *(*move)();
         551                 : {
         552                 :     CHAR        *p;
         553                 :     int         i;
         554                 :
         555               0 :     i = 0;
         556                 :     do {
         557               0 :         if ((p = (*move)()) == NULL)
         558               0 :             return ring_bell();
         559               0 :     } while (++i < Repeat);
         560               0 :     return do_insert_hist(p);
         561                 : }
         562                 :
         563                 : STATIC STATUS
         564               0 : h_next()
         565                 : {
         566               0 :     return do_hist(next_hist);
         567                 : }
         568                 :
         569                 : STATIC STATUS
         570               0 : h_prev()
         571                 : {
         572               0 :     return do_hist(prev_hist);
         573                 : }
         574                 :
         575                 : STATIC STATUS
         576               0 : h_first()
         577                 : {
         578               0 :     return do_insert_hist(H.Lines[H.Pos = 0]);
         579                 : }
         580                 :
         581                 : STATIC STATUS
         582               0 : h_last()
         583                 : {
         584               0 :     return do_insert_hist(H.Lines[H.Pos = H.Size - 1]);
         585                 : }
         586                 :
         587                 : /*
         588                 : **  Return zero if pat appears as a substring in text.
         589                 : */
         590                 : STATIC int
         591               0 : substrcmp(text, pat, len)
         592                 :     char        *text;
         593                 :     char        *pat;
         594                 :     int         len;
         595                 : {
         596                 :     char        c;
         597                 :
         598               0 :     if ((c = *pat) == '\0')
         599               0 :         return *text == '\0';
         600               0 :     for ( ; *text; text++)
         601               0 :         if (*text == c && strncmp(text, pat, len) == 0)
         602               0 :             return 0;
         603               0 :     return 1;
         604                 : }
         605                 :
         606                 : STATIC CHAR *
         607               0 : search_hist(search, move)
         608                 :     CHAR        *search;
         609                 :     CHAR        *(*move)();
         610                 : {
         611                 :     static CHAR *old_search;
         612                 :     int         len;
         613                 :     int         pos;
         614                 :     int         (*match)();
         615                 :     char        *pat;
         616                 :
         617                 :     /* Save or get remembered search pattern. */
         618               0 :     if (search && *search) {
         619               0 :         if (old_search)
         620               0 :             DISPOSE(old_search);
         621               0 :         old_search = (CHAR *)strdup((char *)search);
         622                 :     }
         623                 :     else {
         624               0 :         if (old_search == NULL || *old_search == '\0')
         625               0 :             return NULL;
         626               0 :         search = old_search;
         627                 :     }
         628                 :
         629                 :     /* Set up pattern-finder. */
         630               0 :     if (*search == '^') {
         631               0 :         match = strncmp;
         632               0 :         pat = (char *)(search + 1);
         633                 :     }
         634                 :     else {
         635               0 :         match = substrcmp;
         636               0 :         pat = (char *)search;
         637                 :     }
         638               0 :     len = strlen(pat);
         639                 :
         640               0 :     for (pos = H.Pos; (*move)() != NULL; )
         641               0 :         if ((*match)((char *)H.Lines[H.Pos], pat, len) == 0)
         642               0 :             return H.Lines[H.Pos];
         643               0 :     H.Pos = pos;
         644               0 :     return NULL;
         645                 : }
         646                 :
         647                 : STATIC STATUS
         648               0 : h_search()
         649                 : {
         650                 :     static int  Searching;
         651                 :     CONST char  *old_prompt;
         652                 :     CHAR        *(*move)();
         653                 :     CHAR        *p;
         654                 :
         655               0 :     if (Searching)
         656               0 :         return ring_bell();
         657               0 :     Searching = 1;
         658                 :
         659               0 :     clear_line();
         660               0 :     old_prompt = Prompt;
         661               0 :     Prompt = "Search: ";
         662               0 :     TTYputs((CONST CHAR *)Prompt);
         663               0 :     move = Repeat == NO_ARG ? prev_hist : next_hist;
         664               0 :     p = editinput();
         665               0 :     Prompt = old_prompt;
         666               0 :     Searching = 0;
         667               0 :     TTYputs((CONST CHAR *)Prompt);
         668               0 :     if (p == NULL && Signal > 0) {
         669               0 :         Signal = 0;
         670               0 :         clear_line();
         671               0 :         return redisplay();
         672                 :     }
         673               0 :     p = search_hist(p, move);
         674               0 :     clear_line();
         675               0 :     if (p == NULL) {
         676               0 :         (void)ring_bell();
         677               0 :         return redisplay();
         678                 :     }
         679               0 :     return do_insert_hist(p);
         680                 : }
         681                 :
         682                 : STATIC STATUS
         683               0 : fd_char()
         684                 : {
         685                 :     int         i;
         686                 :
         687               0 :     i = 0;
         688                 :     do {
         689               0 :         if (Point >= End)
         690               0 :             break;
         691               0 :         right(CSmove);
         692               0 :     } while (++i < Repeat);
         693               0 :     return CSstay;
         694                 : }
         695                 :
         696                 : STATIC void
         697               0 : save_yank(begin, i)
         698                 :     int         begin;
         699                 :     int         i;
         700                 : {
         701               0 :     if (Yanked) {
         702               0 :         DISPOSE(Yanked);
         703               0 :         Yanked = NULL;
         704                 :     }
         705                 :
         706               0 :     if (i < 1)
         707               0 :         return;
         708                 :
         709               0 :     if ((Yanked = NEW(CHAR, (SIZE_T)i + 1)) != NULL) {
         710               0 :         COPYFROMTO(Yanked, &Line[begin], i);
         711               0 :         Yanked[i] = '\0';
         712                 :     }
         713                 : }
         714                 :
         715                 : STATIC STATUS
         716               0 : delete_string(count)
         717                 :     int         count;
         718                 : {
         719                 :     int         i;
         720                 :     CHAR        *p;
         721                 :
         722               0 :     if (count <= 0 || End == Point)
         723               0 :         return ring_bell();
         724                 :
         725               0 :     if (count == 1 && Point == End - 1) {
         726                 :         /* Optimize common case of delete at end of line. */
         727               0 :         End--;
         728               0 :         p = &Line[Point];
         729               0 :         i = 1;
         730               0 :         TTYput(' ');
         731               0 :         if (ISCTL(*p)) {
         732               0 :             i = 2;
         733               0 :             TTYput(' ');
         734                 :         }
         735               0 :         else if (rl_meta_chars && ISMETA(*p)) {
         736               0 :             i = 3;
         737               0 :             TTYput(' ');
         738               0 :             TTYput(' ');
         739                 :         }
         740               0 :         TTYbackn(i);
         741               0 :         *p = '\0';
         742               0 :         return CSmove;
         743                 :     }
         744               0 :     if (Point + count > End && (count = End - Point) <= 0)
         745               0 :         return CSstay;
         746                 :
         747               0 :     if (count > 1)
         748               0 :         save_yank(Point, count);
         749                 :
         750               0 :     for (p = &Line[Point], i = End - (Point + count) + 1; --i >= 0; p++)
         751               0 :         p[0] = p[count];
         752               0 :     ceol();
         753               0 :     End -= count;
         754               0 :     TTYstring(&Line[Point]);
         755               0 :     return CSmove;
         756                 : }
         757                 :
         758                 : STATIC STATUS
         759               0 : bk_char()
         760                 : {
         761                 :     int         i;
         762                 :
         763               0 :     i = 0;
         764                 :     do {
         765               0 :         if (Point == 0)
         766               0 :             break;
         767               0 :         left(CSmove);
         768               0 :     } while (++i < Repeat);
         769                 :
         770               0 :     return CSstay;
         771                 : }
         772                 :
         773                 : STATIC STATUS
         774               0 : bk_del_char()
         775                 : {
         776                 :     int         i;
         777                 :
         778               0 :     i = 0;
         779                 :     do {
         780               0 :         if (Point == 0)
         781               0 :             break;
         782               0 :         left(CSmove);
         783               0 :     } while (++i < Repeat);
         784                 :
         785               0 :     return delete_string(i);
         786                 : }
         787                 :
         788                 : STATIC STATUS
         789               0 : kill_line()
         790                 : {
         791                 :     int         i;
         792                 :
         793               0 :     if (Repeat != NO_ARG) {
         794               0 :         if (Repeat < Point) {
         795               0 :             i = Point;
         796               0 :             Point = Repeat;
         797               0 :             reposition();
         798               0 :             (void)delete_string(i - Point);
         799                 :         }
         800               0 :         else if (Repeat > Point) {
         801               0 :             right(CSmove);
         802               0 :             (void)delete_string(Repeat - Point - 1);
         803                 :         }
         804               0 :         return CSmove;
         805                 :     }
         806                 :
         807               0 :     save_yank(Point, End - Point);
         808               0 :     Line[Point] = '\0';
         809               0 :     ceol();
         810               0 :     End = Point;
         811               0 :     return CSstay;
         812                 : }
         813                 :
         814                 : STATIC STATUS
         815               0 : insert_char(c)
         816                 :     int         c;
         817                 : {
         818                 :     STATUS      s;
         819                 :     CHAR        buff[2];
         820                 :     CHAR        *p;
         821                 :     CHAR        *q;
         822                 :     int         i;
         823                 :
         824               0 :     if (Repeat == NO_ARG || Repeat < 2) {
         825               0 :         buff[0] = c;
         826               0 :         buff[1] = '\0';
         827               0 :         return insert_string(buff);
         828                 :     }
         829                 :
         830               0 :     if ((p = NEW(CHAR, Repeat + 1)) == NULL)
         831               0 :         return CSstay;
         832               0 :     for (i = Repeat, q = p; --i >= 0; )
         833               0 :         *q++ = c;
         834               0 :     *q = '\0';
         835               0 :     Repeat = 0;
         836               0 :     s = insert_string(p);
         837               0 :     DISPOSE(p);
         838               0 :     return s;
         839                 : }
         840                 :
         841                 : STATIC STATUS
         842               0 : meta()
         843                 : {
         844                 :     unsigned int        c;
         845                 :     KEYMAP              *kp;
         846                 :
         847               0 :     if ((int)(c = TTYget()) == EOF)
         848               0 :         return CSeof;
         849                 : #if     defined(ANSI_ARROWS)
         850                 :     /* Also include VT-100 arrows. */
         851               0 :     if (c == '[' || c == 'O')
         852               0 :         switch (c = TTYget()) {
         853               0 :         default:        return ring_bell();
         854               0 :         case EOF:       return CSeof;
         855               0 :         case 'A':       return h_prev();
         856               0 :         case 'B':       return h_next();
         857               0 :         case 'C':       return fd_char();
         858               0 :         case 'D':       return bk_char();
         859                 :         }
         860                 : #endif  /* defined(ANSI_ARROWS) */
         861                 :
         862               0 :     if (isdigit(c)) {
         863               0 :         for (Repeat = c - '0'; (int)(c = TTYget()) != EOF && isdigit(c); )
         864               0 :             Repeat = Repeat * 10 + c - '0';
         865               0 :         Pushed = 1;
         866               0 :         PushBack = c;
         867               0 :         return CSstay;
         868                 :     }
         869                 :
         870               0 :     if (isupper(c))
         871               0 :         return do_macro(c);
         872               0 :     for (OldPoint = Point, kp = MetaMap; kp->Function; kp++)
         873               0 :         if (kp->Key == c)
         874               0 :             return (*kp->Function)();
         875                 :
         876               0 :     return ring_bell();
         877                 : }
         878                 :
         879                 : STATIC STATUS
         880               0 : emacs(c)
         881                 :     unsigned int        c;
         882                 : {
         883                 :     STATUS              s;
         884                 :     KEYMAP              *kp;
         885                 :
         886               0 :     if (rl_meta_chars && ISMETA(c)) {
         887               0 :         Pushed = 1;
         888               0 :         PushBack = UNMETA(c);
         889               0 :         return meta();
         890                 :     }
         891               0 :     for (kp = Map; kp->Function; kp++)
         892               0 :         if (kp->Key == c)
         893               0 :             break;
         894               0 :     s = kp->Function ? (*kp->Function)() : insert_char((int)c);
         895               0 :     if (!Pushed)
         896                 :         /* No pushback means no repeat count; hacky, but true. */
         897               0 :         Repeat = NO_ARG;
         898               0 :     return s;
         899                 : }
         900                 :
         901                 : STATIC STATUS
         902               0 : TTYspecial(c)
         903                 :     unsigned int        c;
         904                 : {
         905               0 :     if (ISMETA(c))
         906               0 :         return CSdispatch;
         907                 :
         908               0 :     if (c == rl_erase || (int)c == DEL)
         909               0 :         return bk_del_char();
         910               0 :     if (c == rl_kill) {
         911               0 :         if (Point != 0) {
         912               0 :             Point = 0;
         913               0 :             reposition();
         914                 :         }
         915               0 :         Repeat = NO_ARG;
         916               0 :         return kill_line();
         917                 :     }
         918               0 :     if (c == rl_eof && Point == 0 && End == 0)
         919               0 :         return CSeof;
         920               0 :     if (c == rl_intr) {
         921               0 :         Signal = SIGINT;
         922               0 :         return CSsignal;
         923                 :     }
         924               0 :     if (c == rl_quit) {
         925               0 :         Signal = SIGQUIT;
         926               0 :         return CSeof;
         927                 :     }
         928                 :
         929               0 :     return CSdispatch;
         930                 : }
         931                 :
         932                 : STATIC CHAR *
         933               0 : editinput()
         934                 : {
         935                 :     unsigned int        c;
         936                 :
         937               0 :     Repeat = NO_ARG;
         938               0 :     OldPoint = Point = Mark = End = 0;
         939               0 :     Line[0] = '\0';
         940                 :
         941               0 :     Signal = -1;
         942               0 :     while ((int)(c = TTYget()) != EOF)
         943               0 :         switch (TTYspecial(c)) {
         944                 :         case CSdone:
         945               0 :             return Line;
         946                 :         case CSeof:
         947               0 :             return NULL;
         948                 :         case CSsignal:
         949               0 :             return (CHAR *)"";
         950                 :         case CSmove:
         951               0 :             reposition();
         952               0 :             break;
         953                 :         case CSdispatch:
         954               0 :             switch (emacs(c)) {
         955                 :             case CSdone:
         956               0 :                 return Line;
         957                 :             case CSeof:
         958               0 :                 return NULL;
         959                 :             case CSsignal:
         960               0 :                 return (CHAR *)"";
         961                 :             case CSmove:
         962               0 :                 reposition();
         963               0 :                 break;
         964                 :             case CSdispatch:
         965                 :             case CSstay:
         966               0 :                 break;
         967                 :             }
         968               0 :             break;
         969                 :         case CSstay:
         970               0 :             break;
         971                 :         }
         972               0 :     if (strlen((char *)Line))
         973               0 :         return Line;
         974               0 :     free(Line);
         975               0 :     return NULL;
         976                 : }
         977                 :
         978                 : STATIC void
         979               0 : hist_add(p)
         980                 :     CHAR        *p;
         981                 : {
         982                 :     int         i;
         983                 :
         984               0 :     if ((p = (CHAR *)strdup((char *)p)) == NULL)
         985               0 :         return;
         986               0 :     if (H.Size < HIST_SIZE)
         987               0 :         H.Lines[H.Size++] = p;
         988                 :     else {
         989               0 :         DISPOSE(H.Lines[0]);
         990               0 :         for (i = 0; i < HIST_SIZE - 1; i++)
         991               0 :             H.Lines[i] = H.Lines[i + 1];
         992               0 :         H.Lines[i] = p;
         993                 :     }
         994               0 :     H.Pos = H.Size - 1;
         995                 : }
         996                 :
         997                 : /*
         998                 : **  For compatibility with FSF readline.
         999                 : */
        1000                 : /* ARGSUSED0 */
        1001                 : void
        1002               0 : rl_reset_terminal(p)
        1003                 :     char        *p;
        1004                 : {
        1005                 :     (void)p;
        1006               0 : }
        1007                 :
        1008                 : void
        1009               0 : rl_initialize()
        1010                 : {
        1011               0 : }
        1012                 :
        1013                 : char *
        1014               0 : readline(prompt)
        1015                 :     CONST char  *prompt;
        1016                 : {
        1017                 :     CHAR        *line;
        1018                 :     int         s;
        1019                 :
        1020               0 :     if (Line == NULL) {
        1021               0 :         Length = MEM_INC;
        1022               0 :         if ((Line = NEW(CHAR, Length)) == NULL)
        1023               0 :             return NULL;
        1024                 :     }
        1025                 :
        1026               0 :     TTYinfo();
        1027               0 :     rl_ttyset(0);
        1028               0 :     hist_add(NIL);
        1029               0 :     ScreenSize = SCREEN_INC;
        1030               0 :     Screen = NEW(char, ScreenSize);
        1031               0 :     Prompt = prompt ? prompt : (char *)NIL;
        1032               0 :     TTYputs((CONST CHAR *)Prompt);
        1033               0 :     if ((line = editinput()) != NULL) {
        1034               0 :         line = (CHAR *)strdup((char *)line);
        1035               0 :         TTYputs((CHAR *)NEWLINE);
        1036               0 :         TTYflush();
        1037                 :     }
        1038               0 :     rl_ttyset(1);
        1039               0 :     DISPOSE(Screen);
        1040               0 :     DISPOSE(H.Lines[--H.Size]);
        1041               0 :     if (Signal > 0) {
        1042               0 :         s = Signal;
        1043               0 :         Signal = 0;
        1044               0 :         (void)kill(getpid(), s);
        1045                 :     }
        1046               0 :     return (char *)line;
        1047                 : }
        1048                 :
        1049                 : void
        1050               0 : add_history(p)
        1051                 :     char        *p;
        1052                 : {
        1053               0 :     if (p == NULL || *p == '\0')
        1054               0 :         return;
        1055                 :
        1056                 : #if     defined(UNIQUE_HISTORY)
        1057               0 :     if (H.Size && strcmp(p, (char *)H.Lines[H.Size - 1]) == 0)
        1058               0 :         return;
        1059                 : #endif  /* defined(UNIQUE_HISTORY) */
        1060               0 :     hist_add((CHAR *)p);
        1061                 : }
        1062                 :
        1063                 :
        1064                 : STATIC STATUS
        1065               0 : beg_line()
        1066                 : {
        1067               0 :     if (Point) {
        1068               0 :         Point = 0;
        1069               0 :         return CSmove;
        1070                 :     }
        1071               0 :     return CSstay;
        1072                 : }
        1073                 :
        1074                 : STATIC STATUS
        1075               0 : del_char()
        1076                 : {
        1077               0 :     return delete_string(Repeat == NO_ARG ? 1 : Repeat);
        1078                 : }
        1079                 :
        1080                 : STATIC STATUS
        1081               0 : end_line()
        1082                 : {
        1083               0 :     if (Point != End) {
        1084               0 :         Point = End;
        1085               0 :         return CSmove;
        1086                 :     }
        1087               0 :     return CSstay;
        1088                 : }
        1089                 :
        1090                 : STATIC STATUS
        1091               0 : accept_line()
        1092                 : {
        1093               0 :     Line[End] = '\0';
        1094               0 :     return CSdone;
        1095                 : }
        1096                 :
        1097                 : STATIC STATUS
        1098               0 : transpose()
        1099                 : {
        1100                 :     CHAR        c;
        1101                 :
        1102               0 :     if (Point) {
        1103               0 :         if (Point == End)
        1104               0 :             left(CSmove);
        1105               0 :         c = Line[Point - 1];
        1106               0 :         left(CSstay);
        1107               0 :         Line[Point - 1] = Line[Point];
        1108               0 :         TTYshow(Line[Point - 1]);
        1109               0 :         Line[Point++] = c;
        1110               0 :         TTYshow(c);
        1111                 :     }
        1112               0 :     return CSstay;
        1113                 : }
        1114                 :
        1115                 : STATIC STATUS
        1116               0 : quote()
        1117                 : {
        1118                 :     unsigned int        c;
        1119                 :
        1120               0 :     return (int)(c = TTYget()) == EOF ? CSeof : insert_char((int)c);
        1121                 : }
        1122                 :
        1123                 : STATIC STATUS
        1124               0 : wipe()
        1125                 : {
        1126                 :     int         i;
        1127                 :
        1128               0 :     if (Mark > End)
        1129               0 :         return ring_bell();
        1130                 :
        1131               0 :     if (Point > Mark) {
        1132               0 :         i = Point;
        1133               0 :         Point = Mark;
        1134               0 :         Mark = i;
        1135               0 :         reposition();
        1136                 :     }
        1137                 :
        1138               0 :     return delete_string(Mark - Point);
        1139                 : }
        1140                 :
        1141                 : STATIC STATUS
        1142               0 : mk_set()
        1143                 : {
        1144               0 :     Mark = Point;
        1145               0 :     return CSstay;
        1146                 : }
        1147                 :
        1148                 : STATIC STATUS
        1149               0 : exchange()
        1150                 : {
        1151                 :     unsigned int        c;
        1152                 :
        1153               0 :     if ((c = TTYget()) != CTL('X'))
        1154               0 :         return (int)c == EOF ? CSeof : ring_bell();
        1155                 :
        1156               0 :     if ((int)(c = Mark) <= End) {
        1157               0 :         Mark = Point;
        1158               0 :         Point = c;
        1159               0 :         return CSmove;
        1160                 :     }
        1161               0 :     return CSstay;
        1162                 : }
        1163                 :
        1164                 : STATIC STATUS
        1165               0 : yank()
        1166                 : {
        1167               0 :     if (Yanked && *Yanked)
        1168               0 :         return insert_string(Yanked);
        1169               0 :     return CSstay;
        1170                 : }
        1171                 :
        1172                 : STATIC STATUS
        1173               0 : copy_region()
        1174                 : {
        1175               0 :     if (Mark > End)
        1176               0 :         return ring_bell();
        1177                 :
        1178               0 :     if (Point > Mark)
        1179               0 :         save_yank(Mark, Point - Mark);
        1180                 :     else
        1181               0 :         save_yank(Point, Mark - Point);
        1182                 :
        1183               0 :     return CSstay;
        1184                 : }
        1185                 :
        1186                 : STATIC STATUS
        1187               0 : move_to_char()
        1188                 : {
        1189                 :     unsigned int        c;
        1190                 :     int                 i;
        1191                 :     CHAR                *p;
        1192                 :
        1193               0 :     if ((int)(c = TTYget()) == EOF)
        1194               0 :         return CSeof;
        1195               0 :     for (i = Point + 1, p = &Line[i]; i < End; i++, p++)
        1196               0 :         if (*p == c) {
        1197               0 :             Point = i;
        1198               0 :             return CSmove;
        1199                 :         }
        1200               0 :     return CSstay;
        1201                 : }
        1202                 :
        1203                 : STATIC STATUS
        1204               0 : fd_word()
        1205                 : {
        1206               0 :     return do_forward(CSmove);
        1207                 : }
        1208                 :
        1209                 : STATIC STATUS
        1210               0 : fd_kill_word()
        1211                 : {
        1212                 :     int         i;
        1213                 :
        1214               0 :     (void)do_forward(CSstay);
        1215               0 :     if (OldPoint != Point) {
        1216               0 :         i = Point - OldPoint;
        1217               0 :         Point = OldPoint;
        1218               0 :         return delete_string(i);
        1219                 :     }
        1220               0 :     return CSstay;
        1221                 : }
        1222                 :
        1223                 : STATIC STATUS
        1224               0 : bk_word()
        1225                 : {
        1226                 :     int         i;
        1227                 :     CHAR        *p;
        1228                 :
        1229               0 :     i = 0;
        1230                 :     do {
        1231               0 :         for (p = &Line[Point]; p > Line && !isalnum(p[-1]); p--)
        1232               0 :             left(CSmove);
        1233                 :
        1234               0 :         for (; p > Line && p[-1] != ' ' && isalnum(p[-1]); p--)
        1235               0 :             left(CSmove);
        1236                 :
        1237               0 :         if (Point == 0)
        1238               0 :             break;
        1239               0 :     } while (++i < Repeat);
        1240                 :
        1241               0 :     return CSstay;
        1242                 : }
        1243                 :
        1244                 : STATIC STATUS
        1245               0 : bk_kill_word()
        1246                 : {
        1247               0 :     (void)bk_word();
        1248               0 :     if (OldPoint != Point)
        1249               0 :         return delete_string(OldPoint - Point);
        1250               0 :     return CSstay;
        1251                 : }
        1252                 :
        1253                 : STATIC int
        1254               0 : argify(line, avp)
        1255                 :     CHAR        *line;
        1256                 :     CHAR        ***avp;
        1257                 : {
        1258                 :     CHAR        *c;
        1259                 :     CHAR        **p;
        1260                 :     CHAR        **new;
        1261                 :     int         ac;
        1262                 :     int         i;
        1263                 :
        1264               0 :     i = MEM_INC;
        1265               0 :     if ((*avp = p = NEW(CHAR*, i))== NULL)
        1266               0 :          return 0;
        1267                 :
        1268               0 :     for (c = line; isspace(*c); c++)
        1269               0 :         continue;
        1270               0 :     if (*c == '\n' || *c == '\0')
        1271               0 :         return 0;
        1272                 :
        1273               0 :     for (ac = 0, p[ac++] = c; *c && *c != '\n'; ) {
        1274               0 :         if (isspace(*c)) {
        1275               0 :             *c++ = '\0';
        1276               0 :             if (*c && *c != '\n') {
        1277               0 :                 if (ac + 1 == i) {
        1278               0 :                     new = NEW(CHAR*, i + MEM_INC);
        1279               0 :                     if (new == NULL) {
        1280               0 :                         p[ac] = NULL;
        1281               0 :                         return ac;
        1282                 :                     }
        1283               0 :                     COPYFROMTO(new, p, i * sizeof (char **));
        1284               0 :                     i += MEM_INC;
        1285               0 :                     DISPOSE(p);
        1286               0 :                     *avp = p = new;
        1287                 :                 }
        1288               0 :                 p[ac++] = c;
        1289                 :             }
        1290                 :         }
        1291                 :         else
        1292               0 :             c++;
        1293                 :     }
        1294               0 :     *c = '\0';
        1295               0 :     p[ac] = NULL;
        1296               0 :     return ac;
        1297                 : }
        1298                 :
        1299                 : STATIC STATUS
        1300               0 : last_argument()
        1301                 : {
        1302                 :     CHAR        **av;
        1303                 :     CHAR        *p;
        1304                 :     STATUS      s;
        1305                 :     int         ac;
        1306                 :
        1307               0 :     if (H.Size == 1 || (p = H.Lines[H.Size - 2]) == NULL)
        1308               0 :         return ring_bell();
        1309                 :
        1310               0 :     if ((p = (CHAR *)strdup((char *)p)) == NULL)
        1311               0 :         return CSstay;
        1312               0 :     ac = argify(p, &av);
        1313                 :
        1314               0 :     if (Repeat != NO_ARG)
        1315               0 :         s = Repeat < ac ? insert_string(av[Repeat]) : ring_bell();
        1316                 :     else
        1317               0 :         s = ac ? insert_string(av[ac - 1]) : CSstay;
        1318                 :
        1319               0 :     if (ac)
        1320               0 :         DISPOSE(av);
        1321               0 :     DISPOSE(p);
        1322               0 :     return s;
        1323                 : }
        1324                 :
        1325                 : STATIC KEYMAP   Map[32] = {
        1326                 :     {   CTL('@'),       ring_bell       },
        1327                 :     {   CTL('A'),       beg_line        },
        1328                 :     {   CTL('B'),       bk_char         },
        1329                 :     {   CTL('D'),       del_char        },
        1330                 :     {   CTL('E'),       end_line        },
        1331                 :     {   CTL('F'),       fd_char         },
        1332                 :     {   CTL('G'),       ring_bell       },
        1333                 :     {   CTL('H'),       bk_del_char     },
        1334                 :     {   CTL('J'),       accept_line     },
        1335                 :     {   CTL('K'),       kill_line       },
        1336                 :     {   CTL('L'),       redisplay       },
        1337                 :     {   CTL('M'),       accept_line     },
        1338                 :     {   CTL('N'),       h_next          },
        1339                 :     {   CTL('O'),       ring_bell       },
        1340                 :     {   CTL('P'),       h_prev          },
        1341                 :     {   CTL('Q'),       ring_bell       },
        1342                 :     {   CTL('R'),       h_search        },
        1343                 :     {   CTL('S'),       ring_bell       },
        1344                 :     {   CTL('T'),       transpose       },
        1345                 :     {   CTL('U'),       ring_bell       },
        1346                 :     {   CTL('V'),       quote           },
        1347                 :     {   CTL('W'),       wipe            },
        1348                 :     {   CTL('X'),       exchange        },
        1349                 :     {   CTL('Y'),       yank            },
        1350                 :     {   CTL('Z'),       ring_bell       },
        1351                 :     {   CTL('['),       meta            },
        1352                 :     {   CTL(']'),       move_to_char    },
        1353                 :     {   CTL('^'),       ring_bell       },
        1354                 :     {   CTL('_'),       ring_bell       },
        1355                 :     {   0,              NULL            }
        1356                 : };
        1357                 :
        1358                 : STATIC KEYMAP   MetaMap[16]= {
        1359                 :     {   CTL('H'),       bk_kill_word    },
        1360                 :     {   DEL,            bk_kill_word    },
        1361                 :     {   ' ',            mk_set          },
        1362                 :     {   '.',            last_argument   },
        1363                 :     {   '<',         h_first         },
        1364                 :     {   '>',         h_last          },
        1365                 :     {   'b',            bk_word         },
        1366                 :     {   'd',            fd_kill_word    },
        1367                 :     {   'f',            fd_word         },
        1368                 :     {   'l',            case_down_word  },
        1369                 :     {   'm',            toggle_meta_mode },
        1370                 :     {   'u',            case_up_word    },
        1371                 :     {   'y',            yank            },
        1372                 :     {   'w',            copy_region     },
        1373                 :     {   0,              NULL            }
        1374                 : };
        1375                 :

Generated by: LCOV version 1.7