GNU Octave  3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
oct-rl-hist.c
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2000-2013 John W. Eaton
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 #include "oct-rl-hist.h"
28 
29 #if defined (USE_READLINE)
30 
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 
35 #include <readline/history.h>
36 
37 /* check_history_control, hc_erasedup, and the core of
38  octave_add_history were borrowed from Bash. */
39 
40 /* Check LINE against what HISTCONTROL says to do. Returns 1 if the line
41  should be saved; 0 if it should be discarded. */
42 static int
43 check_history_control (const char *line, int history_control)
44 {
45  HIST_ENTRY *temp;
46  int r;
47 
48  if (history_control == 0)
49  return 1;
50 
51  /* ignorespace or ignoreboth */
52  if ((history_control & HC_IGNSPACE) && *line == ' ')
53  return 0;
54 
55  /* ignoredups or ignoreboth */
56  if (history_control & HC_IGNDUPS)
57  {
58  using_history ();
59  temp = previous_history ();
60 
61  r = (temp == 0 || strcmp (temp->line, line));
62 
63  using_history ();
64 
65  if (r == 0)
66  return r;
67  }
68 
69  return 1;
70 }
71 
72 /* Remove all entries matching LINE from the history list. Triggered when
73  HISTCONTROL includes `erasedups'. */
74 
75 static void
76 hc_erasedups (const char *line)
77 {
78  HIST_ENTRY *temp;
79  int r;
80 
81  using_history ();
82  while ((temp = previous_history ()))
83  {
84  if (! strcmp (temp->line, line))
85  {
86  r = where_history ();
87  remove_history (r);
88  }
89  }
90  using_history ();
91 }
92 
93 /* Check LINE against HISTCONTROL and add it to the history if it's OK.
94  Returns 1 if the line was saved in the history, 0 otherwise. */
95 
96 int
97 octave_add_history (const char *line, int history_control)
98 {
99  if (check_history_control (line, history_control))
100  {
101  /* We're committed to saving the line. If the user has requested it,
102  remove other matching lines from the history. */
103 
104  if (history_control & HC_ERASEDUPS)
105  hc_erasedups (line);
106 
107  add_history (line);
108 
109  return 1;
110  }
111 
112  return 0;
113 }
114 
115 int
117 {
118  return where_history ();
119 }
120 
121 int
123 {
124  return history_length;
125 }
126 
127 int
129 {
130  return max_input_history;
131 }
132 
133 int
134 octave_history_base (void)
135 {
136  return history_base;
137 }
138 
139 void
140 octave_stifle_history (int n)
141 {
142  stifle_history (n);
143 }
144 
145 int
147 {
148  return unstifle_history ();
149 }
150 
151 int
153 {
154  return history_is_stifled ();
155 }
156 
157 int
159 {
160  return history_set_pos (n);
161 }
162 
163 int
164 octave_read_history (const char *f)
165 {
166  return read_history (f);
167 }
168 
169 void
171 {
172  using_history ();
173 }
174 
175 int
176 octave_read_history_range (const char *f, int b, int e)
177 {
178  return read_history_range (f, b, e);
179 }
180 
181 int
182 octave_write_history (const char *f)
183 {
184  return write_history (f);
185 }
186 
187 int
188 octave_append_history (int n, const char *f)
189 {
190  return append_history (n, f);
191 }
192 
193 int
194 octave_history_truncate_file (const char *f, int n)
195 {
196  return history_truncate_file (f, n);
197 }
198 
199 void
200 octave_remove_history (int n)
201 {
202  HIST_ENTRY *discard = remove_history (n);
203 
204  if (discard)
205  {
206  if (discard->line)
207  free (discard->line);
208 
209  free (discard);
210  }
211 }
212 
213 void
215 {
216  clear_history ();
217 }
218 
219 char *
221 {
222  HIST_ENTRY *h;
223 
224  char *retval = 0;
225 
226  if (history_set_pos (n))
227  {
228  h = current_history ();
229 
230  if (h)
231  retval = h->line;
232  }
233 
234  return retval;
235 }
236 
237 char *
238 octave_history_get (int n)
239 {
240  char *retval = 0;
241 
242  HIST_ENTRY *h = history_get (n);
243 
244  if (h)
245  retval = h->line;
246 
247  return retval;
248 }
249 
250 char **
251 octave_history_list (int limit, int number_lines)
252 {
253  static char **retval = 0;
254 
255  HIST_ENTRY **hlist = 0;
256 
257  if (retval)
258  {
259  char **p = retval;
260 
261  while (*p)
262  free (*p++);
263 
264  free (retval);
265 
266  retval = 0;
267  }
268 
269  hlist = history_list ();
270 
271  if (hlist)
272  {
273  int i, k;
274 
275  int beg = 0;
276  int end = 0;
277  while (hlist[end])
278  end++;
279 
280  beg = (limit < 0 || end < limit) ? 0 : (end - limit);
281 
282  retval = malloc ((end - beg + 1) * sizeof (char **));
283 
284  k = 0;
285  for (i = beg; i < end; i++)
286  {
287  char *line = hlist[i]->line;
288  int len = line ? strlen (line) : 0;
289  char *tmp = malloc (len + 64);
290 
291  if (number_lines)
292  sprintf (tmp, "%5d %s", i + history_base,
293  line ? line : "");
294  else
295  strcpy (tmp, line ? line : "");
296 
297  retval[k++] = tmp;
298  }
299 
300  retval[k] = 0;
301  }
302 
303  return retval;
304 }
305 
306 void
307 octave_replace_history_entry (int which, const char *line)
308 {
309  HIST_ENTRY *discard = replace_history_entry (which, line, 0);
310 
311  if (discard)
312  {
313  if (discard->line)
314  free (discard->line);
315 
316  free (discard);
317  }
318 }
319 
320 #endif