File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / readline / macro.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Wed Jul 30 08:16:45 2014 UTC (9 years, 10 months ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    1: /* macro.c -- keyboard macros for readline. */
    2: 
    3: /* Copyright (C) 1994-2009 Free Software Foundation, Inc.
    4: 
    5:    This file is part of the GNU Readline Library (Readline), a library
    6:    for reading lines of text with interactive input and history editing.      
    7: 
    8:    Readline is free software: you can redistribute it and/or modify
    9:    it under the terms of the GNU General Public License as published by
   10:    the Free Software Foundation, either version 3 of the License, or
   11:    (at your option) any later version.
   12: 
   13:    Readline is distributed in the hope that it will be useful,
   14:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   15:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16:    GNU General Public License for more details.
   17: 
   18:    You should have received a copy of the GNU General Public License
   19:    along with Readline.  If not, see <http://www.gnu.org/licenses/>.
   20: */
   21: 
   22: #define READLINE_LIBRARY
   23: 
   24: #if defined (HAVE_CONFIG_H)
   25: #  include <config.h>
   26: #endif
   27: 
   28: #include <sys/types.h>
   29: 
   30: #if defined (HAVE_UNISTD_H)
   31: #  include <unistd.h>           /* for _POSIX_VERSION */
   32: #endif /* HAVE_UNISTD_H */
   33: 
   34: #if defined (HAVE_STDLIB_H)
   35: #  include <stdlib.h>
   36: #else
   37: #  include "ansi_stdlib.h"
   38: #endif /* HAVE_STDLIB_H */
   39: 
   40: #include <stdio.h>
   41: 
   42: /* System-specific feature definitions and include files. */
   43: #include "rldefs.h"
   44: 
   45: /* Some standard library routines. */
   46: #include "readline.h"
   47: #include "history.h"
   48: 
   49: #include "rlprivate.h"
   50: #include "xmalloc.h"
   51: 
   52: /* **************************************************************** */
   53: /*								    */
   54: /*			Hacking Keyboard Macros 		    */
   55: /*								    */
   56: /* **************************************************************** */
   57: 
   58: /* The currently executing macro string.  If this is non-zero,
   59:    then it is a malloc ()'ed string where input is coming from. */
   60: char *rl_executing_macro = (char *)NULL;
   61: 
   62: /* The offset in the above string to the next character to be read. */
   63: static int executing_macro_index;
   64: 
   65: /* The current macro string being built.  Characters get stuffed
   66:    in here by add_macro_char (). */
   67: static char *current_macro = (char *)NULL;
   68: 
   69: /* The size of the buffer allocated to current_macro. */
   70: static int current_macro_size;
   71: 
   72: /* The index at which characters are being added to current_macro. */
   73: static int current_macro_index;
   74: 
   75: /* A structure used to save nested macro strings.
   76:    It is a linked list of string/index for each saved macro. */
   77: struct saved_macro {
   78:   struct saved_macro *next;
   79:   char *string;
   80:   int sindex;
   81: };
   82: 
   83: /* The list of saved macros. */
   84: static struct saved_macro *macro_list = (struct saved_macro *)NULL;
   85: 
   86: /* Set up to read subsequent input from STRING.
   87:    STRING is free ()'ed when we are done with it. */
   88: void
   89: _rl_with_macro_input (string)
   90:      char *string;
   91: {
   92:   _rl_push_executing_macro ();
   93:   rl_executing_macro = string;
   94:   executing_macro_index = 0;
   95:   RL_SETSTATE(RL_STATE_MACROINPUT);
   96: }
   97: 
   98: /* Return the next character available from a macro, or 0 if
   99:    there are no macro characters. */
  100: int
  101: _rl_next_macro_key ()
  102: {
  103:   int c;
  104: 
  105:   if (rl_executing_macro == 0)
  106:     return (0);
  107: 
  108:   if (rl_executing_macro[executing_macro_index] == 0)
  109:     {
  110:       _rl_pop_executing_macro ();
  111:       return (_rl_next_macro_key ());
  112:     }
  113: 
  114: #if defined (READLINE_CALLBACKS)
  115:   c = rl_executing_macro[executing_macro_index++];
  116:   if (RL_ISSTATE (RL_STATE_CALLBACK) && RL_ISSTATE (RL_STATE_READCMD|RL_STATE_MOREINPUT) && rl_executing_macro[executing_macro_index] == 0)
  117:       _rl_pop_executing_macro ();
  118:   return c;
  119: #else
  120:   return (rl_executing_macro[executing_macro_index++]);
  121: #endif
  122: }
  123: 
  124: int
  125: _rl_prev_macro_key ()
  126: {
  127:   if (rl_executing_macro == 0)
  128:     return (0);
  129: 
  130:   if (executing_macro_index == 0)
  131:     return (0);
  132: 
  133:   executing_macro_index--;
  134:   return (rl_executing_macro[executing_macro_index]);
  135: }
  136: 
  137: /* Save the currently executing macro on a stack of saved macros. */
  138: void
  139: _rl_push_executing_macro ()
  140: {
  141:   struct saved_macro *saver;
  142: 
  143:   saver = (struct saved_macro *)xmalloc (sizeof (struct saved_macro));
  144:   saver->next = macro_list;
  145:   saver->sindex = executing_macro_index;
  146:   saver->string = rl_executing_macro;
  147: 
  148:   macro_list = saver;
  149: }
  150: 
  151: /* Discard the current macro, replacing it with the one
  152:    on the top of the stack of saved macros. */
  153: void
  154: _rl_pop_executing_macro ()
  155: {
  156:   struct saved_macro *macro;
  157: 
  158:   FREE (rl_executing_macro);
  159:   rl_executing_macro = (char *)NULL;
  160:   executing_macro_index = 0;
  161: 
  162:   if (macro_list)
  163:     {
  164:       macro = macro_list;
  165:       rl_executing_macro = macro_list->string;
  166:       executing_macro_index = macro_list->sindex;
  167:       macro_list = macro_list->next;
  168:       xfree (macro);
  169:     }
  170: 
  171:   if (rl_executing_macro == 0)
  172:     RL_UNSETSTATE(RL_STATE_MACROINPUT);
  173: }
  174: 
  175: /* Add a character to the macro being built. */
  176: void
  177: _rl_add_macro_char (c)
  178:      int c;
  179: {
  180:   if (current_macro_index + 1 >= current_macro_size)
  181:     {
  182:       if (current_macro == 0)
  183: 	current_macro = (char *)xmalloc (current_macro_size = 25);
  184:       else
  185: 	current_macro = (char *)xrealloc (current_macro, current_macro_size += 25);
  186:     }
  187: 
  188:   current_macro[current_macro_index++] = c;
  189:   current_macro[current_macro_index] = '\0';
  190: }
  191: 
  192: void
  193: _rl_kill_kbd_macro ()
  194: {
  195:   if (current_macro)
  196:     {
  197:       xfree (current_macro);
  198:       current_macro = (char *) NULL;
  199:     }
  200:   current_macro_size = current_macro_index = 0;
  201: 
  202:   FREE (rl_executing_macro);
  203:   rl_executing_macro = (char *) NULL;
  204:   executing_macro_index = 0;
  205: 
  206:   RL_UNSETSTATE(RL_STATE_MACRODEF);
  207: }
  208: 
  209: /* Begin defining a keyboard macro.
  210:    Keystrokes are recorded as they are executed.
  211:    End the definition with rl_end_kbd_macro ().
  212:    If a numeric argument was explicitly typed, then append this
  213:    definition to the end of the existing macro, and start by
  214:    re-executing the existing macro. */
  215: int
  216: rl_start_kbd_macro (ignore1, ignore2)
  217:      int ignore1, ignore2;
  218: {
  219:   if (RL_ISSTATE (RL_STATE_MACRODEF))
  220:     {
  221:       _rl_abort_internal ();
  222:       return -1;
  223:     }
  224: 
  225:   if (rl_explicit_arg)
  226:     {
  227:       if (current_macro)
  228: 	_rl_with_macro_input (savestring (current_macro));
  229:     }
  230:   else
  231:     current_macro_index = 0;
  232: 
  233:   RL_SETSTATE(RL_STATE_MACRODEF);
  234:   return 0;
  235: }
  236: 
  237: /* Stop defining a keyboard macro.
  238:    A numeric argument says to execute the macro right now,
  239:    that many times, counting the definition as the first time. */
  240: int
  241: rl_end_kbd_macro (count, ignore)
  242:      int count, ignore;
  243: {
  244:   if (RL_ISSTATE (RL_STATE_MACRODEF) == 0)
  245:     {
  246:       _rl_abort_internal ();
  247:       return -1;
  248:     }
  249: 
  250:   current_macro_index -= rl_key_sequence_length;
  251:   current_macro[current_macro_index] = '\0';
  252: 
  253:   RL_UNSETSTATE(RL_STATE_MACRODEF);
  254: 
  255:   return (rl_call_last_kbd_macro (--count, 0));
  256: }
  257: 
  258: /* Execute the most recently defined keyboard macro.
  259:    COUNT says how many times to execute it. */
  260: int
  261: rl_call_last_kbd_macro (count, ignore)
  262:      int count, ignore;
  263: {
  264:   if (current_macro == 0)
  265:     _rl_abort_internal ();
  266: 
  267:   if (RL_ISSTATE (RL_STATE_MACRODEF))
  268:     {
  269:       rl_ding ();		/* no recursive macros */
  270:       current_macro[--current_macro_index] = '\0';	/* erase this char */
  271:       return 0;
  272:     }
  273: 
  274:   while (count--)
  275:     _rl_with_macro_input (savestring (current_macro));
  276:   return 0;
  277: }
  278: 
  279: int
  280: rl_print_last_kbd_macro (count, ignore)
  281:      int count, ignore;
  282: {
  283:   char *m;
  284: 
  285:   if (current_macro == 0)
  286:     {
  287:       rl_ding ();
  288:       return 0;
  289:     }
  290:   m = _rl_untranslate_macro_value (current_macro, 1);
  291:   rl_crlf ();
  292:   printf ("%s", m);
  293:   fflush (stdout);
  294:   rl_crlf ();
  295:   FREE (m);
  296:   rl_forced_update_display ();
  297:   rl_display_fixed = 1;
  298: 
  299:   return 0;
  300: }
  301: 
  302: void
  303: rl_push_macro_input (macro)
  304:      char *macro;
  305: {
  306:   _rl_with_macro_input (macro);
  307: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>