oct-rl-hist.c

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 2000-2012 John W. Eaton
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, see
00019 <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026 
00027 #include "oct-rl-hist.h"
00028 
00029 #if defined (USE_READLINE)
00030 
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 
00035 #include <readline/history.h>
00036 
00037 /* check_history_control, hc_erasedup, and the core of
00038    octave_add_history were borrowed from Bash.  */
00039 
00040 /* Check LINE against what HISTCONTROL says to do.  Returns 1 if the line
00041    should be saved; 0 if it should be discarded.  */
00042 static int
00043 check_history_control (const char *line, int history_control)
00044 {
00045   HIST_ENTRY *temp;
00046   int r;
00047 
00048   if (history_control == 0)
00049     return 1;
00050 
00051   /* ignorespace or ignoreboth */
00052   if ((history_control & HC_IGNSPACE) && *line == ' ')
00053     return 0;
00054 
00055   /* ignoredups or ignoreboth */
00056   if (history_control & HC_IGNDUPS)
00057     {
00058       using_history ();
00059       temp = previous_history ();
00060 
00061       r = (temp == 0 || strcmp (temp->line, line));
00062 
00063       using_history ();
00064 
00065       if (r == 0)
00066         return r;
00067     }
00068 
00069   return 1;
00070 }
00071 
00072 /* Remove all entries matching LINE from the history list.  Triggered when
00073    HISTCONTROL includes `erasedups'.  */
00074 
00075 static void
00076 hc_erasedups (const char *line)
00077 {
00078   HIST_ENTRY *temp;
00079   int r;
00080 
00081   using_history ();
00082   while ((temp = previous_history ()))
00083     {
00084       if (! strcmp (temp->line, line))
00085         {
00086           r = where_history ();
00087           remove_history (r);
00088         }
00089     }
00090   using_history ();
00091 }
00092 
00093 /* Check LINE against HISTCONTROL and add it to the history if it's OK.
00094    Returns 1 if the line was saved in the history, 0 otherwise.  */
00095 
00096 int
00097 octave_add_history (const char *line, int history_control)
00098 {
00099   if (check_history_control (line, history_control))
00100     {
00101       /* We're committed to saving the line.  If the user has requested it,
00102          remove other matching lines from the history.  */
00103 
00104       if (history_control & HC_ERASEDUPS)
00105         hc_erasedups (line);
00106 
00107       add_history (line);
00108 
00109       return 1;
00110     }
00111 
00112   return 0;
00113 }
00114 
00115 int
00116 octave_where_history (void)
00117 {
00118   return where_history ();
00119 }
00120 
00121 int
00122 octave_history_length (void)
00123 {
00124   return history_length;
00125 }
00126 
00127 int
00128 octave_max_input_history (void)
00129 {
00130   return max_input_history;
00131 }
00132 
00133 int
00134 octave_history_base (void)
00135 {
00136   return history_base;
00137 }
00138 
00139 void
00140 octave_stifle_history (int n)
00141 {
00142   stifle_history (n);
00143 }
00144 
00145 int
00146 octave_unstifle_history (void)
00147 {
00148   return unstifle_history ();
00149 }
00150 
00151 int
00152 octave_history_is_stifled (void)
00153 {
00154   return history_is_stifled ();
00155 }
00156 
00157 int
00158 octave_history_set_pos (int n)
00159 {
00160   return history_set_pos (n);
00161 }
00162 
00163 int
00164 octave_read_history (const char *f)
00165 {
00166   return read_history (f);
00167 }
00168 
00169 void
00170 octave_using_history (void)
00171 {
00172   using_history ();
00173 }
00174 
00175 int
00176 octave_read_history_range (const char *f, int b, int e)
00177 {
00178   return read_history_range (f, b, e);
00179 }
00180 
00181 int
00182 octave_write_history (const char *f)
00183 {
00184   return write_history (f);
00185 }
00186 
00187 int
00188 octave_append_history (int n, const char *f)
00189 {
00190   return append_history (n, f);
00191 }
00192 
00193 int
00194 octave_history_truncate_file (const char *f, int n)
00195 {
00196   return history_truncate_file (f, n);
00197 }
00198 
00199 void
00200 octave_remove_history (int n)
00201 {
00202   HIST_ENTRY *discard = remove_history (n);
00203 
00204   if (discard)
00205     {
00206       if (discard->line)
00207         free (discard->line);
00208 
00209       free (discard);
00210     }
00211 }
00212 
00213 char *
00214 octave_history_goto_mark (int n)
00215 {
00216   HIST_ENTRY *h;
00217 
00218   char *retval = 0;
00219 
00220   if (history_set_pos (n))
00221     {
00222       h = current_history ();
00223 
00224       if (h)
00225         retval = h->line;
00226     }
00227 
00228   return retval;
00229 }
00230 
00231 char *
00232 octave_history_get (int n)
00233 {
00234   char *retval = 0;
00235 
00236   HIST_ENTRY *h = history_get (n);
00237 
00238   if (h)
00239     retval = h->line;
00240 
00241   return retval;
00242 }
00243 
00244 char **
00245 octave_history_list (int limit, int number_lines)
00246 {
00247   static char **retval = 0;
00248 
00249   HIST_ENTRY **hlist = 0;
00250 
00251   if (retval)
00252     {
00253       char **p = retval;
00254 
00255       while (*p)
00256         free (*p++);
00257 
00258       free (retval);
00259 
00260       retval = 0;
00261     }
00262 
00263   hlist = history_list ();
00264 
00265   if (hlist)
00266     {
00267       int i, k;
00268 
00269       int beg = 0;
00270       int end = 0;
00271       while (hlist[end])
00272         end++;
00273 
00274       beg = (limit < 0 || end < limit) ? 0 : (end - limit);
00275 
00276       retval = malloc ((end - beg + 1) * sizeof (char **));
00277 
00278       k = 0;
00279       for (i = beg; i < end; i++)
00280         {
00281           char *line = hlist[i]->line;
00282           int len = line ? strlen (line) : 0;
00283           char *tmp = malloc (len + 64);
00284 
00285           if (number_lines)
00286             sprintf (tmp, "%5d%c%s", i + history_base,
00287                      hlist[i]->data ? '*' : ' ',
00288                      line ? line : "");
00289           else
00290             sprintf (tmp, "%c%s", hlist[i]->data ? '*' : ' ',
00291                      line ? line : "");
00292 
00293           retval[k++] = tmp;
00294         }
00295 
00296       retval[k] = 0;
00297     }
00298 
00299   return retval;
00300 }
00301 
00302 void
00303 octave_replace_history_entry (int which, const char *line)
00304 {
00305   HIST_ENTRY *discard = replace_history_entry (which, line, 0);
00306 
00307   if (discard)
00308     {
00309       if (discard->line)
00310         free (discard->line);
00311 
00312       free (discard);
00313     }
00314 }
00315 
00316 #endif
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines