common.c

Go to the documentation of this file.
00001 /* $NetBSD: common.c,v 1.11 2002/03/18 16:00:51 christos Exp $ */
00002 
00003 /*-
00004  * Copyright (c) 1992, 1993
00005  * The Regents of the University of California.  All rights reserved.
00006  *
00007  * This code is derived from software contributed to Berkeley by
00008  * Christos Zoulas of Cornell University.
00009  *
00010  * Redistribution and use in source and binary forms, with or without
00011  * modification, are permitted provided that the following conditions
00012  * are met:
00013  * 1. Redistributions of source code must retain the above copyright
00014  *    notice, this list of conditions and the following disclaimer.
00015  * 2. Redistributions in binary form must reproduce the above copyright
00016  *    notice, this list of conditions and the following disclaimer in the
00017  *    documentation and/or other materials provided with the distribution.
00018  * 3. All advertising materials mentioning features or use of this software
00019  *    must display the following acknowledgement:
00020  * This product includes software developed by the University of
00021  * California, Berkeley and its contributors.
00022  * 4. Neither the name of the University nor the names of its contributors
00023  *    may be used to endorse or promote products derived from this software
00024  *    without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00027  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00029  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00030  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00031  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00032  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00033  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00034  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00035  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00036  * SUCH DAMAGE.
00037  */
00038 
00039 #include "config.h"
00040 #if !defined(lint) && !defined(SCCSID)
00041 #if 0
00042 static char sccsid[] = "@(#)common.c   8.1 (Berkeley) 6/4/93";
00043 #else
00044 __RCSID("$NetBSD: common.c,v 1.11 2002/03/18 16:00:51 christos Exp $");
00045 #endif
00046 #endif /* not lint && not SCCSID */
00047 
00048 /*
00049  * common.c: Common Editor functions
00050  */
00051 #include "el.h"
00052 
00053 /* ed_end_of_file():
00054  * Indicate end of file
00055  * [^D]
00056  */
00057 protected el_action_t
00058 /*ARGSUSED*/
00059 ed_end_of_file(EditLine *el, int c)
00060 {
00061 
00062    re_goto_bottom(el);
00063    *el->el_line.lastchar = '\0';
00064    return (CC_EOF);
00065 }
00066 
00067 
00068 /* ed_insert():
00069  * Add character to the line
00070  * Insert a character [bound to all insert keys]
00071  */
00072 protected el_action_t
00073 ed_insert(EditLine *el, int c)
00074 {
00075    int i;
00076 
00077    if (c == '\0')
00078       return (CC_ERROR);
00079 
00080    if (el->el_line.lastchar + el->el_state.argument >=
00081        el->el_line.limit) {
00082       /* end of buffer space, try to allocate more */
00083       if (!ch_enlargebufs(el, (size_t) el->el_state.argument))
00084          return CC_ERROR;  /* error allocating more */
00085    }
00086 
00087    if (el->el_state.argument == 1) {
00088       if (el->el_state.inputmode != MODE_INSERT) {
00089          el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] =
00090              *el->el_line.cursor;
00091          el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] =
00092              '\0';
00093          c_delafter(el, 1);
00094       }
00095       c_insert(el, 1);
00096 
00097       *el->el_line.cursor++ = c;
00098       el->el_state.doingarg = 0; /* just in case */
00099       re_fastaddc(el);     /* fast refresh for one char. */
00100    } else {
00101       if (el->el_state.inputmode != MODE_INSERT) {
00102          for (i = 0; i < el->el_state.argument; i++)
00103             el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] =
00104                 el->el_line.cursor[i];
00105 
00106          el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] =
00107              '\0';
00108          c_delafter(el, el->el_state.argument);
00109       }
00110       c_insert(el, el->el_state.argument);
00111 
00112       while (el->el_state.argument--)
00113          *el->el_line.cursor++ = c;
00114       re_refresh(el);
00115    }
00116 
00117    if (el->el_state.inputmode == MODE_REPLACE_1)
00118       (void) vi_command_mode(el, 0);
00119 
00120    return (CC_NORM);
00121 }
00122 
00123 
00124 /* ed_delete_prev_word():
00125  * Delete from beginning of current word to cursor
00126  * [M-^?] [^W]
00127  */
00128 protected el_action_t
00129 /*ARGSUSED*/
00130 ed_delete_prev_word(EditLine *el, int c)
00131 {
00132    char *cp, *p, *kp;
00133 
00134    if (el->el_line.cursor == el->el_line.buffer)
00135       return (CC_ERROR);
00136 
00137    cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
00138        el->el_state.argument, ce__isword);
00139 
00140    for (p = cp, kp = el->el_chared.c_kill.buf; p < el->el_line.cursor; p++)
00141       *kp++ = *p;
00142    el->el_chared.c_kill.last = kp;
00143 
00144    c_delbefore(el, el->el_line.cursor - cp); /* delete before dot */
00145    el->el_line.cursor = cp;
00146    if (el->el_line.cursor < el->el_line.buffer)
00147       el->el_line.cursor = el->el_line.buffer; /* bounds check */
00148    return (CC_REFRESH);
00149 }
00150 
00151 
00152 /* ed_delete_next_char():
00153  * Delete character under cursor
00154  * [^D] [x]
00155  */
00156 protected el_action_t
00157 /*ARGSUSED*/
00158 ed_delete_next_char(EditLine *el, int c)
00159 {
00160 #ifdef notdef        /* XXX */
00161 #define  EL el->el_line
00162    (void) fprintf(el->el_errlfile,
00163        "\nD(b: %x(%s)  c: %x(%s) last: %x(%s) limit: %x(%s)\n",
00164        EL.buffer, EL.buffer, EL.cursor, EL.cursor, EL.lastchar,
00165        EL.lastchar, EL.limit, EL.limit);
00166 #endif
00167    if (el->el_line.cursor == el->el_line.lastchar) {
00168          /* if I'm at the end */
00169       if (el->el_map.type == MAP_VI) {
00170          if (el->el_line.cursor == el->el_line.buffer) {
00171             /* if I'm also at the beginning */
00172 #ifdef KSHVI
00173             return (CC_ERROR);
00174 #else
00175             term_overwrite(el, STReof, 4);
00176                /* then do a EOF */
00177             term__flush();
00178             return (CC_EOF);
00179 #endif
00180          } else {
00181 #ifdef KSHVI
00182             el->el_line.cursor--;
00183 #else
00184             return (CC_ERROR);
00185 #endif
00186          }
00187       } else {
00188          if (el->el_line.cursor != el->el_line.buffer)
00189             el->el_line.cursor--;
00190          else
00191             return (CC_ERROR);
00192       }
00193    }
00194    c_delafter(el, el->el_state.argument); /* delete after dot */
00195    if (el->el_line.cursor >= el->el_line.lastchar &&
00196        el->el_line.cursor > el->el_line.buffer)
00197          /* bounds check */
00198       el->el_line.cursor = el->el_line.lastchar - 1;
00199    return (CC_REFRESH);
00200 }
00201 
00202 
00203 /* ed_kill_line():
00204  * Cut to the end of line
00205  * [^K] [^K]
00206  */
00207 protected el_action_t
00208 /*ARGSUSED*/
00209 ed_kill_line(EditLine *el, int c)
00210 {
00211    char *kp, *cp;
00212 
00213    cp = el->el_line.cursor;
00214    kp = el->el_chared.c_kill.buf;
00215    while (cp < el->el_line.lastchar)
00216       *kp++ = *cp++; /* copy it */
00217    el->el_chared.c_kill.last = kp;
00218          /* zap! -- delete to end */
00219    el->el_line.lastchar = el->el_line.cursor;
00220    return (CC_REFRESH);
00221 }
00222 
00223 
00224 /* ed_move_to_end():
00225  * Move cursor to the end of line
00226  * [^E] [^E]
00227  */
00228 protected el_action_t
00229 /*ARGSUSED*/
00230 ed_move_to_end(EditLine *el, int c)
00231 {
00232 
00233    el->el_line.cursor = el->el_line.lastchar;
00234    if (el->el_map.type == MAP_VI) {
00235 #ifdef VI_MOVE
00236       el->el_line.cursor--;
00237 #endif
00238       if (el->el_chared.c_vcmd.action & DELETE) {
00239          cv_delfini(el);
00240          return (CC_REFRESH);
00241       }
00242    }
00243    return (CC_CURSOR);
00244 }
00245 
00246 
00247 /* ed_move_to_beg():
00248  * Move cursor to the beginning of line
00249  * [^A] [^A]
00250  */
00251 protected el_action_t
00252 /*ARGSUSED*/
00253 ed_move_to_beg(EditLine *el, int c)
00254 {
00255 
00256    el->el_line.cursor = el->el_line.buffer;
00257 
00258    if (el->el_map.type == MAP_VI) {
00259          /* We want FIRST non space character */
00260       while (isspace((unsigned char) *el->el_line.cursor))
00261          el->el_line.cursor++;
00262       if (el->el_chared.c_vcmd.action & DELETE) {
00263          cv_delfini(el);
00264          return (CC_REFRESH);
00265       }
00266    }
00267    return (CC_CURSOR);
00268 }
00269 
00270 
00271 /* ed_transpose_chars():
00272  * Exchange the character to the left of the cursor with the one under it
00273  * [^T] [^T]
00274  */
00275 protected el_action_t
00276 ed_transpose_chars(EditLine *el, int c)
00277 {
00278 
00279    if (el->el_line.cursor < el->el_line.lastchar) {
00280       if (el->el_line.lastchar <= &el->el_line.buffer[1])
00281          return (CC_ERROR);
00282       else
00283          el->el_line.cursor++;
00284    }
00285    if (el->el_line.cursor > &el->el_line.buffer[1]) {
00286       /* must have at least two chars entered */
00287       c = el->el_line.cursor[-2];
00288       el->el_line.cursor[-2] = el->el_line.cursor[-1];
00289       el->el_line.cursor[-1] = c;
00290       return (CC_REFRESH);
00291    } else
00292       return (CC_ERROR);
00293 }
00294 
00295 
00296 /* ed_next_char():
00297  * Move to the right one character
00298  * [^F] [^F]
00299  */
00300 protected el_action_t
00301 /*ARGSUSED*/
00302 ed_next_char(EditLine *el, int c)
00303 {
00304 
00305    if (el->el_line.cursor >= el->el_line.lastchar)
00306       return (CC_ERROR);
00307 
00308    el->el_line.cursor += el->el_state.argument;
00309    if (el->el_line.cursor > el->el_line.lastchar)
00310       el->el_line.cursor = el->el_line.lastchar;
00311 
00312    if (el->el_map.type == MAP_VI)
00313       if (el->el_chared.c_vcmd.action & DELETE) {
00314          cv_delfini(el);
00315          return (CC_REFRESH);
00316       }
00317    return (CC_CURSOR);
00318 }
00319 
00320 
00321 /* ed_prev_word():
00322  * Move to the beginning of the current word
00323  * [M-b] [b]
00324  */
00325 protected el_action_t
00326 /*ARGSUSED*/
00327 ed_prev_word(EditLine *el, int c)
00328 {
00329 
00330    if (el->el_line.cursor == el->el_line.buffer)
00331       return (CC_ERROR);
00332 
00333    el->el_line.cursor = c__prev_word(el->el_line.cursor,
00334        el->el_line.buffer,
00335        el->el_state.argument,
00336        ce__isword);
00337 
00338    if (el->el_map.type == MAP_VI)
00339       if (el->el_chared.c_vcmd.action & DELETE) {
00340          cv_delfini(el);
00341          return (CC_REFRESH);
00342       }
00343    return (CC_CURSOR);
00344 }
00345 
00346 
00347 /* ed_prev_char():
00348  * Move to the left one character
00349  * [^B] [^B]
00350  */
00351 protected el_action_t
00352 /*ARGSUSED*/
00353 ed_prev_char(EditLine *el, int c)
00354 {
00355 
00356    if (el->el_line.cursor > el->el_line.buffer) {
00357       el->el_line.cursor -= el->el_state.argument;
00358       if (el->el_line.cursor < el->el_line.buffer)
00359          el->el_line.cursor = el->el_line.buffer;
00360 
00361       if (el->el_map.type == MAP_VI)
00362          if (el->el_chared.c_vcmd.action & DELETE) {
00363             cv_delfini(el);
00364             return (CC_REFRESH);
00365          }
00366       return (CC_CURSOR);
00367    } else
00368       return (CC_ERROR);
00369 }
00370 
00371 
00372 /* ed_quoted_insert():
00373  * Add the next character typed verbatim
00374  * [^V] [^V]
00375  */
00376 protected el_action_t
00377 ed_quoted_insert(EditLine *el, int c)
00378 {
00379    int num;
00380    char tc;
00381 
00382    tty_quotemode(el);
00383    num = el_getc(el, &tc);
00384    c = (unsigned char) tc;
00385    tty_noquotemode(el);
00386    if (num == 1)
00387       return (ed_insert(el, c));
00388    else
00389       return (ed_end_of_file(el, 0));
00390 }
00391 
00392 
00393 /* ed_digit():
00394  * Adds to argument or enters a digit
00395  */
00396 protected el_action_t
00397 ed_digit(EditLine *el, int c)
00398 {
00399 
00400    if (!isdigit(c))
00401       return (CC_ERROR);
00402 
00403    if (el->el_state.doingarg) {
00404          /* if doing an arg, add this in... */
00405       if (el->el_state.lastcmd == EM_UNIVERSAL_ARGUMENT)
00406          el->el_state.argument = c - '0';
00407       else {
00408          if (el->el_state.argument > 1000000)
00409             return (CC_ERROR);
00410          el->el_state.argument =
00411              (el->el_state.argument * 10) + (c - '0');
00412       }
00413       return (CC_ARGHACK);
00414    } else {
00415       if (el->el_line.lastchar + 1 >= el->el_line.limit) {
00416          if (!ch_enlargebufs(el, 1))
00417             return (CC_ERROR);
00418       }
00419 
00420       if (el->el_state.inputmode != MODE_INSERT) {
00421          el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] =
00422              *el->el_line.cursor;
00423          el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] =
00424              '\0';
00425          c_delafter(el, 1);
00426       }
00427       c_insert(el, 1);
00428       *el->el_line.cursor++ = c;
00429       el->el_state.doingarg = 0;
00430       re_fastaddc(el);
00431    }
00432    return (CC_NORM);
00433 }
00434 
00435 
00436 /* ed_argument_digit():
00437  * Digit that starts argument
00438  * For ESC-n
00439  */
00440 protected el_action_t
00441 ed_argument_digit(EditLine *el, int c)
00442 {
00443 
00444    if (!isdigit(c))
00445       return (CC_ERROR);
00446 
00447    if (el->el_state.doingarg) {
00448       if (el->el_state.argument > 1000000)
00449          return (CC_ERROR);
00450       el->el_state.argument = (el->el_state.argument * 10) +
00451           (c - '0');
00452    } else {    /* else starting an argument */
00453       el->el_state.argument = c - '0';
00454       el->el_state.doingarg = 1;
00455    }
00456    return (CC_ARGHACK);
00457 }
00458 
00459 
00460 /* ed_unassigned():
00461  * Indicates unbound character
00462  * Bound to keys that are not assigned
00463  */
00464 protected el_action_t
00465 /*ARGSUSED*/
00466 ed_unassigned(EditLine *el, int c)
00467 {
00468 
00469    term_beep(el);
00470    term__flush();
00471    return (CC_NORM);
00472 }
00473 
00474 
00475 /**
00476  ** TTY key handling.
00477  **/
00478 
00479 /* ed_tty_sigint():
00480  * Tty interrupt character
00481  * [^C]
00482  */
00483 protected el_action_t
00484 /*ARGSUSED*/
00485 ed_tty_sigint(EditLine *el, int c)
00486 {
00487 
00488    return (CC_NORM);
00489 }
00490 
00491 
00492 /* ed_tty_dsusp():
00493  * Tty delayed suspend character
00494  * [^Y]
00495  */
00496 protected el_action_t
00497 /*ARGSUSED*/
00498 ed_tty_dsusp(EditLine *el, int c)
00499 {
00500 
00501    return (CC_NORM);
00502 }
00503 
00504 
00505 /* ed_tty_flush_output():
00506  * Tty flush output characters
00507  * [^O]
00508  */
00509 protected el_action_t
00510 /*ARGSUSED*/
00511 ed_tty_flush_output(EditLine *el, int c)
00512 {
00513 
00514    return (CC_NORM);
00515 }
00516 
00517 
00518 /* ed_tty_sigquit():
00519  * Tty quit character
00520  * [^\]
00521  */
00522 protected el_action_t
00523 /*ARGSUSED*/
00524 ed_tty_sigquit(EditLine *el, int c)
00525 {
00526 
00527    return (CC_NORM);
00528 }
00529 
00530 
00531 /* ed_tty_sigtstp():
00532  * Tty suspend character
00533  * [^Z]
00534  */
00535 protected el_action_t
00536 /*ARGSUSED*/
00537 ed_tty_sigtstp(EditLine *el, int c)
00538 {
00539 
00540    return (CC_NORM);
00541 }
00542 
00543 
00544 /* ed_tty_stop_output():
00545  * Tty disallow output characters
00546  * [^S]
00547  */
00548 protected el_action_t
00549 /*ARGSUSED*/
00550 ed_tty_stop_output(EditLine *el, int c)
00551 {
00552 
00553    return (CC_NORM);
00554 }
00555 
00556 
00557 /* ed_tty_start_output():
00558  * Tty allow output characters
00559  * [^Q]
00560  */
00561 protected el_action_t
00562 /*ARGSUSED*/
00563 ed_tty_start_output(EditLine *el, int c)
00564 {
00565 
00566    return (CC_NORM);
00567 }
00568 
00569 
00570 /* ed_newline():
00571  * Execute command
00572  * [^J]
00573  */
00574 protected el_action_t
00575 /*ARGSUSED*/
00576 ed_newline(EditLine *el, int c)
00577 {
00578 
00579    re_goto_bottom(el);
00580    *el->el_line.lastchar++ = '\n';
00581    *el->el_line.lastchar = '\0';
00582    if (el->el_map.type == MAP_VI)
00583       el->el_chared.c_vcmd.ins = el->el_line.buffer;
00584    return (CC_NEWLINE);
00585 }
00586 
00587 
00588 /* ed_delete_prev_char():
00589  * Delete the character to the left of the cursor
00590  * [^?]
00591  */
00592 protected el_action_t
00593 /*ARGSUSED*/
00594 ed_delete_prev_char(EditLine *el, int c)
00595 {
00596 
00597    if (el->el_line.cursor <= el->el_line.buffer)
00598       return (CC_ERROR);
00599 
00600    c_delbefore(el, el->el_state.argument);
00601    el->el_line.cursor -= el->el_state.argument;
00602    if (el->el_line.cursor < el->el_line.buffer)
00603       el->el_line.cursor = el->el_line.buffer;
00604    return (CC_REFRESH);
00605 }
00606 
00607 
00608 /* ed_clear_screen():
00609  * Clear screen leaving current line at the top
00610  * [^L]
00611  */
00612 protected el_action_t
00613 /*ARGSUSED*/
00614 ed_clear_screen(EditLine *el, int c)
00615 {
00616 
00617    term_clear_screen(el);  /* clear the whole real screen */
00618    re_clear_display(el);   /* reset everything */
00619    return (CC_REFRESH);
00620 }
00621 
00622 
00623 /* ed_redisplay():
00624  * Redisplay everything
00625  * ^R
00626  */
00627 protected el_action_t
00628 /*ARGSUSED*/
00629 ed_redisplay(EditLine *el, int c)
00630 {
00631 
00632    return (CC_REDISPLAY);
00633 }
00634 
00635 
00636 /* ed_start_over():
00637  * Erase current line and start from scratch
00638  * [^G]
00639  */
00640 protected el_action_t
00641 /*ARGSUSED*/
00642 ed_start_over(EditLine *el, int c)
00643 {
00644 
00645    ch_reset(el);
00646    return (CC_REFRESH);
00647 }
00648 
00649 
00650 /* ed_sequence_lead_in():
00651  * First character in a bound sequence
00652  * Placeholder for external keys
00653  */
00654 protected el_action_t
00655 /*ARGSUSED*/
00656 ed_sequence_lead_in(EditLine *el, int c)
00657 {
00658 
00659    return (CC_NORM);
00660 }
00661 
00662 
00663 /* ed_prev_history():
00664  * Move to the previous history line
00665  * [^P] [k]
00666  */
00667 protected el_action_t
00668 /*ARGSUSED*/
00669 ed_prev_history(EditLine *el, int c)
00670 {
00671    char beep = 0;
00672 
00673    el->el_chared.c_undo.action = NOP;
00674    *el->el_line.lastchar = '\0';    /* just in case */
00675 
00676    if (el->el_history.eventno == 0) {  /* save the current buffer
00677                    * away */
00678       (void) strncpy(el->el_history.buf, el->el_line.buffer,
00679           EL_BUFSIZ - 1);
00680       el->el_history.last = el->el_history.buf +
00681           (el->el_line.lastchar - el->el_line.buffer);
00682    }
00683    el->el_history.eventno += el->el_state.argument;
00684 
00685    if (hist_get(el) == CC_ERROR) {
00686       beep = 1;
00687       /* el->el_history.eventno was fixed by first call */
00688       (void) hist_get(el);
00689    }
00690    re_refresh(el);
00691    if (beep)
00692       return (CC_ERROR);
00693    else
00694       return (CC_NORM); /* was CC_UP_HIST */
00695 }
00696 
00697 
00698 /* ed_next_history():
00699  * Move to the next history line
00700  * [^N] [j]
00701  */
00702 protected el_action_t
00703 /*ARGSUSED*/
00704 ed_next_history(EditLine *el, int c)
00705 {
00706 
00707    el->el_chared.c_undo.action = NOP;
00708    *el->el_line.lastchar = '\0'; /* just in case */
00709 
00710    el->el_history.eventno -= el->el_state.argument;
00711 
00712    if (el->el_history.eventno < 0) {
00713       el->el_history.eventno = 0;
00714       return (CC_ERROR);/* make it beep */
00715    }
00716    return (hist_get(el));
00717 }
00718 
00719 
00720 /* ed_search_prev_history():
00721  * Search previous in history for a line matching the current
00722  * next search history [M-P] [K]
00723  */
00724 protected el_action_t
00725 /*ARGSUSED*/
00726 ed_search_prev_history(EditLine *el, int c)
00727 {
00728    const char *hp;
00729    int h;
00730    bool_t found = 0;
00731 
00732    el->el_chared.c_vcmd.action = NOP;
00733    el->el_chared.c_undo.action = NOP;
00734    *el->el_line.lastchar = '\0'; /* just in case */
00735    if (el->el_history.eventno < 0) {
00736 #ifdef DEBUG_EDIT
00737       (void) fprintf(el->el_errfile,
00738           "e_prev_search_hist(): eventno < 0;\n");
00739 #endif
00740       el->el_history.eventno = 0;
00741       return (CC_ERROR);
00742    }
00743    if (el->el_history.eventno == 0) {
00744       (void) strncpy(el->el_history.buf, el->el_line.buffer,
00745           EL_BUFSIZ - 1);
00746       el->el_history.last = el->el_history.buf +
00747           (el->el_line.lastchar - el->el_line.buffer);
00748    }
00749    if (el->el_history.ref == NULL)
00750       return (CC_ERROR);
00751 
00752    hp = HIST_FIRST(el);
00753    if (hp == NULL)
00754       return (CC_ERROR);
00755 
00756    c_setpat(el);     /* Set search pattern !! */
00757 
00758    for (h = 1; h <= el->el_history.eventno; h++)
00759       hp = HIST_NEXT(el);
00760 
00761    while (hp != NULL) {
00762 #ifdef SDEBUG
00763       (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
00764 #endif
00765       if ((strncmp(hp, el->el_line.buffer, (size_t)
00766              (el->el_line.lastchar - el->el_line.buffer)) ||
00767          hp[el->el_line.lastchar - el->el_line.buffer]) &&
00768           c_hmatch(el, hp)) {
00769          found++;
00770          break;
00771       }
00772       h++;
00773       hp = HIST_NEXT(el);
00774    }
00775 
00776    if (!found) {
00777 #ifdef SDEBUG
00778       (void) fprintf(el->el_errfile, "not found\n");
00779 #endif
00780       return (CC_ERROR);
00781    }
00782    el->el_history.eventno = h;
00783 
00784    return (hist_get(el));
00785 }
00786 
00787 
00788 /* ed_search_next_history():
00789  * Search next in history for a line matching the current
00790  * [M-N] [J]
00791  */
00792 protected el_action_t
00793 /*ARGSUSED*/
00794 ed_search_next_history(EditLine *el, int c)
00795 {
00796    const char *hp;
00797    int h;
00798    bool_t found = 0;
00799 
00800    el->el_chared.c_vcmd.action = NOP;
00801    el->el_chared.c_undo.action = NOP;
00802    *el->el_line.lastchar = '\0'; /* just in case */
00803 
00804    if (el->el_history.eventno == 0)
00805       return (CC_ERROR);
00806 
00807    if (el->el_history.ref == NULL)
00808       return (CC_ERROR);
00809 
00810    hp = HIST_FIRST(el);
00811    if (hp == NULL)
00812       return (CC_ERROR);
00813 
00814    c_setpat(el);     /* Set search pattern !! */
00815 
00816    for (h = 1; h < el->el_history.eventno && hp; h++) {
00817 #ifdef SDEBUG
00818       (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
00819 #endif
00820       if ((strncmp(hp, el->el_line.buffer, (size_t)
00821              (el->el_line.lastchar - el->el_line.buffer)) ||
00822          hp[el->el_line.lastchar - el->el_line.buffer]) &&
00823           c_hmatch(el, hp))
00824          found = h;
00825       hp = HIST_NEXT(el);
00826    }
00827 
00828    if (!found) {     /* is it the current history number? */
00829       if (!c_hmatch(el, el->el_history.buf)) {
00830 #ifdef SDEBUG
00831          (void) fprintf(el->el_errfile, "not found\n");
00832 #endif
00833          return (CC_ERROR);
00834       }
00835    }
00836    el->el_history.eventno = found;
00837 
00838    return (hist_get(el));
00839 }
00840 
00841 
00842 /* ed_prev_line():
00843  * Move up one line
00844  * Could be [k] [^p]
00845  */
00846 protected el_action_t
00847 /*ARGSUSED*/
00848 ed_prev_line(EditLine *el, int c)
00849 {
00850    char *ptr;
00851    int nchars = c_hpos(el);
00852 
00853    /*
00854          * Move to the line requested
00855          */
00856    if (*(ptr = el->el_line.cursor) == '\n')
00857       ptr--;
00858 
00859    for (; ptr >= el->el_line.buffer; ptr--)
00860       if (*ptr == '\n' && --el->el_state.argument <= 0)
00861          break;
00862 
00863    if (el->el_state.argument > 0)
00864       return (CC_ERROR);
00865 
00866    /*
00867          * Move to the beginning of the line
00868          */
00869    for (ptr--; ptr >= el->el_line.buffer && *ptr != '\n'; ptr--)
00870       continue;
00871 
00872    /*
00873          * Move to the character requested
00874          */
00875    for (ptr++;
00876        nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
00877        ptr++)
00878       continue;
00879 
00880    el->el_line.cursor = ptr;
00881    return (CC_CURSOR);
00882 }
00883 
00884 
00885 /* ed_next_line():
00886  * Move down one line
00887  * Could be [j] [^n]
00888  */
00889 protected el_action_t
00890 /*ARGSUSED*/
00891 ed_next_line(EditLine *el, int c)
00892 {
00893    char *ptr;
00894    int nchars = c_hpos(el);
00895 
00896    /*
00897          * Move to the line requested
00898          */
00899    for (ptr = el->el_line.cursor; ptr < el->el_line.lastchar; ptr++)
00900       if (*ptr == '\n' && --el->el_state.argument <= 0)
00901          break;
00902 
00903    if (el->el_state.argument > 0)
00904       return (CC_ERROR);
00905 
00906    /*
00907          * Move to the character requested
00908          */
00909    for (ptr++;
00910        nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
00911        ptr++)
00912       continue;
00913 
00914    el->el_line.cursor = ptr;
00915    return (CC_CURSOR);
00916 }
00917 
00918 
00919 /* ed_command():
00920  * Editline extended command
00921  * [M-X] [:]
00922  */
00923 protected el_action_t
00924 /*ARGSUSED*/
00925 ed_command(EditLine *el, int c)
00926 {
00927    char tmpbuf[EL_BUFSIZ];
00928    int tmplen;
00929 
00930    el->el_line.buffer[0] = '\0';
00931    el->el_line.lastchar = el->el_line.buffer;
00932    el->el_line.cursor = el->el_line.buffer;
00933 
00934    c_insert(el, 3);  /* prompt + ": " */
00935    *el->el_line.cursor++ = '\n';
00936    *el->el_line.cursor++ = ':';
00937    *el->el_line.cursor++ = ' ';
00938    re_refresh(el);
00939 
00940    tmplen = c_gets(el, tmpbuf);
00941    tmpbuf[tmplen] = '\0';
00942 
00943    el->el_line.buffer[0] = '\0';
00944    el->el_line.lastchar = el->el_line.buffer;
00945    el->el_line.cursor = el->el_line.buffer;
00946 
00947    if (parse_line(el, tmpbuf) == -1)
00948       return (CC_ERROR);
00949    else
00950       return (CC_REFRESH);
00951 }

Generated on Thu Apr 16 06:27:30 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6