GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
oct-rl-hist.c
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 2000-2025 The Octave Project Developers
4//
5// See the file COPYRIGHT.md in the top-level directory of this
6// distribution or <https://octave.org/copyright/>.
7//
8// This file is part of Octave.
9//
10// Octave is free software: you can redistribute it and/or modify it
11// under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14//
15// Octave is distributed in the hope that it will be useful, but
16// WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with Octave; see the file COPYING. If not, see
22// <https://www.gnu.org/licenses/>.
23//
24////////////////////////////////////////////////////////////////////////
25
26#if defined (HAVE_CONFIG_H)
27# include "config.h"
28#endif
29
30#include "oct-rl-hist.h"
31
32#if defined (USE_READLINE)
33
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37
38#include <readline/history.h>
39
40/* check_history_control, hc_erasedup, and the core of
41 octave_add_history were borrowed from Bash. */
42
43/* Check LINE against what HISTCONTROL says to do. Returns 1 if the line
44 should be saved; 0 if it should be discarded. */
45static int
46check_history_control (const char *line, int history_control)
47{
48 HIST_ENTRY *temp;
49 int r;
50
51 if (history_control == 0)
52 return 1;
53
54 /* ignorespace or ignoreboth */
55 if ((history_control & HC_IGNSPACE) && *line == ' ')
56 return 0;
57
58 /* ignoredups or ignoreboth */
59 if (history_control & HC_IGNDUPS)
60 {
61 using_history ();
62 temp = previous_history ();
63
64 r = (temp == 0 || strcmp (temp->line, line));
65
66 using_history ();
67
68 if (r == 0)
69 return r;
70 }
71
72 return 1;
73}
74
75/* Remove all entries matching LINE from the history list. Triggered when
76 HISTCONTROL includes 'erasedups'. */
77
78static void
79hc_erasedups (const char *line)
80{
81 HIST_ENTRY *temp;
82 int r;
83
84 using_history ();
85 while ((temp = previous_history ()))
86 {
87 if (! strcmp (temp->line, line))
88 {
89 r = where_history ();
90 remove_history (r);
91 }
92 }
93 using_history ();
94}
95
96/* Check LINE against HISTCONTROL and add it to the history if it's OK.
97 Returns 1 if the line was saved in the history, 0 otherwise. */
98
99int
100octave_add_history (const char *line, int history_control)
101{
102 if (check_history_control (line, history_control))
103 {
104 /* We're committed to saving the line. If the user has requested it,
105 remove other matching lines from the history. */
106
107 if (history_control & HC_ERASEDUPS)
108 hc_erasedups (line);
109
110 add_history (line);
111
112 return 1;
113 }
114
115 return 0;
116}
117
118int
120{
121 return where_history ();
122}
123
124int
126{
127 return history_length;
128}
129
130int
132{
133 return max_input_history;
134}
135
136int
138{
139 return history_base;
140}
141
142void
144{
145 stifle_history (n);
146}
147
148int
150{
151 return unstifle_history ();
152}
153
154int
156{
157 return history_is_stifled ();
158}
159
160int
162{
163 return history_set_pos (n);
164}
165
166int
167octave_read_history (const char *f)
168{
169 return read_history (f);
170}
171
172void
174{
175 using_history ();
176}
177
178int
179octave_read_history_range (const char *f, int b, int e)
180{
181 return read_history_range (f, b, e);
182}
183
184int
185octave_write_history (const char *f)
186{
187 return write_history (f);
188}
189
190int
191octave_append_history (int n, const char *f)
192{
193 return append_history (n, f);
194}
195
196int
197octave_history_truncate_file (const char *f, int n)
198{
199 return history_truncate_file (f, n);
200}
201
202void
204{
205 HIST_ENTRY *discard = remove_history (n);
206
207 if (discard)
208 free (discard->line);
209
210 free (discard);
211}
212
213void
215{
216 clear_history ();
217}
218
219char *
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
237char *
238octave_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
250char **
251octave_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 ((size_t) (end - beg + 1) * sizeof (char *));
283 // FIXME: Should this call current_liboctave_error_handler instead?
284 if (! retval)
285 return retval;
286
287 k = 0;
288 for (i = beg; i < end; i++)
289 {
290 char *line = hlist[i]->line;
291 size_t len = line ? strlen (line) : 0;
292 char *tmp = malloc (len + 64);
293
294 if (tmp)
295 {
296 if (number_lines)
297 sprintf (tmp, "%5d %s", i + history_base,
298 line ? line : "");
299 else
300 strcpy (tmp, line ? line : "");
301
302 retval[k++] = tmp;
303 }
304 }
305
306 retval[k] = 0;
307 }
308
309 return retval;
310}
311
312void
313octave_replace_history_entry (int which, const char *line)
314{
315 HIST_ENTRY *discard = replace_history_entry (which, line, 0);
316
317 if (discard)
318 free (discard->line);
319
320 free (discard);
321}
322
323#endif
F77_RET_T const F77_DBLE const F77_DBLE * f
void octave_stifle_history(int)
char * octave_history_goto_mark(int n)
int octave_unstifle_history(void)
int octave_where_history(void)
void octave_clear_history(void)
int octave_read_history_range(const char *, int, int)
int octave_write_history(const char *)
int octave_append_history(int, const char *)
int octave_read_history(const char *)
int octave_max_input_history(void)
@ HC_IGNDUPS
Definition oct-rl-hist.h:39
@ HC_ERASEDUPS
Definition oct-rl-hist.h:40
@ HC_IGNSPACE
Definition oct-rl-hist.h:38
char ** octave_history_list(int, int)
int octave_history_length(void)
void octave_replace_history_entry(int, const char *)
char * octave_history_get(int n)
int octave_history_base(void)
int octave_history_set_pos(int)
int octave_add_history(const char *, int)
int octave_history_truncate_file(const char *, int)
void octave_using_history(void)
int octave_history_is_stifled(void)
void octave_remove_history(int)
T::size_type strlen(const typename T::value_type *str)
Definition oct-string.cc:88
bool strcmp(const T &str_a, const T &str_b)
Octave string utility functions.
void * malloc(unsigned)
void free(void *)
F77_RET_T len
Definition xerbla.cc:61