comparison liboctave/cmd-hist.cc @ 1797:28aefb5a7dec

[project @ 1996-01-29 05:05:57 by jwe] Initial revision
author jwe
date Mon, 29 Jan 1996 05:05:57 +0000
parents
children ea3bb1476056
comparison
equal deleted inserted replaced
1796:d9aaa9aaa1c0 1797:28aefb5a7dec
1 // cmd-hist.cc -*- C++ -*-
2 /*
3
4 Copyright (C) 1996 John W. Eaton
5
6 This file is part of Octave.
7
8 Octave is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
11 later version.
12
13 Octave is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Octave; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <cstring>
29
30 #include <strstream.h>
31
32 #include <fcntl.h>
33
34 #ifdef HAVE_UNISTD_H
35 #include <sys/types.h>
36 #include <unistd.h>
37 #endif
38
39 extern "C"
40 {
41 #include <readline/history.h>
42 }
43
44 #include "file-ops.h"
45 #include "lo-error.h"
46 #include "cmd-hist.h"
47
48 bool command_history::initialized = false;
49
50 command_history::command_history (const string& f, int n)
51 {
52 if (initialized)
53 error ("only one history object can be active at once");
54 else
55 {
56 ignoring_additions = false;
57
58 lines_in_file = 0;
59 lines_this_session = 0;
60
61 xsize = -1;
62
63 if (! f.empty ())
64 {
65 xfile = f;
66
67 read_history (f.c_str ());
68
69 lines_in_file = where ();
70
71 using_history ();
72 }
73
74 if (n > 0)
75 xsize = n;
76
77 initialized = true;
78 }
79 }
80
81 void
82 command_history::set_file (const string& f)
83 {
84 xfile = f;
85 }
86
87 string
88 command_history::file (void)
89 {
90 return xfile;
91 }
92
93 void
94 command_history::set_size (int n)
95 {
96 xsize = n;
97 }
98
99 int
100 command_history::size (void)
101 {
102 return xsize;
103 }
104
105 void
106 command_history::ignore_entries (bool flag = true)
107 {
108 ignoring_additions = flag;
109 }
110
111 bool
112 command_history::ignoring_entries (void)
113 {
114 return ignoring_additions;
115 }
116
117 void
118 command_history::add (const string& s)
119 {
120 if (! ignoring_entries ())
121 {
122 add_history (s.c_str ());
123 lines_this_session++;
124 }
125 }
126
127 void
128 command_history::remove (int n)
129 {
130 HIST_ENTRY *discard = remove_history (n);
131
132 if (discard)
133 {
134 if (discard->line)
135 free (discard->line);
136
137 free (discard);
138 }
139 }
140
141 int
142 command_history::where (void)
143 {
144 return where_history ();
145 }
146
147 int
148 command_history::base (void)
149 {
150 return history_base;
151 }
152
153 int
154 command_history::current_number (void)
155 {
156 return (xsize > 0) ? base () + where () : -1;
157 }
158
159 void
160 command_history::stifle (int n)
161 {
162 stifle_history (n);
163 }
164
165 int
166 command_history::unstifle (void)
167 {
168 return unstifle_history ();
169 }
170
171 int
172 command_history::is_stifled (void)
173 {
174 return history_is_stifled ();
175 }
176
177 void
178 command_history::read (const string& f_arg)
179 {
180 string f = f_arg;
181
182 if (f.empty ())
183 f = xfile;
184
185 if (! f.empty ())
186 {
187 int status = read_history (f.c_str ());
188
189 if (status != 0)
190 error (status);
191 else
192 using_history ();
193 }
194 else
195 error ("command_history::read: missing file name");
196 }
197
198 void
199 command_history::read_range (const string& f_arg, int from, int to)
200 {
201 if (from < 0)
202 from = lines_in_file;
203
204 string f = f_arg;
205
206 if (f.empty ())
207 f = xfile;
208
209 if (! f.empty ())
210 {
211 int status = read_history_range (f.c_str (), from, to);
212
213 if (status != 0)
214 error (status);
215 else
216 {
217 using_history ();
218 lines_in_file = where ();
219 }
220 }
221 else
222 error ("command_history::read_range: missing file name");
223 }
224
225 void
226 command_history::write (const string& f_arg)
227 {
228 string f = f_arg;
229
230 if (f.empty ())
231 f = xfile;
232
233 if (! f.empty ())
234 {
235 int status = write_history (f.c_str ());
236
237 if (status != 0)
238 error (status);
239 }
240 else
241 error ("command_history::write: missing file name");
242 }
243
244 void
245 command_history::append (const string& f_arg)
246 {
247 if (lines_this_session)
248 {
249 if (lines_this_session < where ())
250 {
251 // Create file if it doesn't already exist.
252
253 string f = f_arg;
254
255 if (f.empty ())
256 f = xfile;
257
258 if (! f.empty ())
259 {
260 file_stat fs (f);
261
262 if (! fs)
263 {
264 int tem;
265
266 tem = open (f.c_str (), O_CREAT, 0666);
267 close (tem);
268 }
269
270 int status = append_history (lines_this_session, f.c_str ());
271
272 if (status != 0)
273 error (status);
274 else
275 lines_in_file += lines_this_session;
276
277 lines_this_session = 0;
278 }
279 else
280 error ("comman_history::append: missing file name");
281 }
282 }
283 }
284
285 void
286 command_history::truncate_file (const string& f_arg, int n)
287 {
288 string f = f_arg;
289
290 if (f.empty ())
291 f = xfile;
292
293 if (! f.empty ())
294 history_truncate_file (f.c_str (), n);
295 else
296 error ("command_history::truncate_file: missing file name");
297 }
298
299 string_vector
300 command_history::list (int limit, int number_lines)
301 {
302 string_vector retval;
303
304 if (limit)
305 {
306 HIST_ENTRY **hlist = history_list ();
307
308 if (hlist)
309 {
310 int end = 0;
311 while (hlist[end])
312 end++;
313
314 int beg = (limit < 0 || end < limit) ? 0 : (end - limit);
315
316 retval.resize (end - beg);
317
318 int k = 0;
319 for (int i = beg; i < end; i++)
320 {
321 ostrstream output_buf;
322
323 if (number_lines)
324 output_buf.form ("%5d%c", i + history_base,
325 hlist[i]->data ? '*' : ' ');
326
327 output_buf << hlist[i]->line << ends;
328
329 const char *tmp = output_buf.str ();
330
331 retval[k++] = tmp;
332
333 delete [] tmp;
334 }
335 }
336 }
337
338 return retval;
339 }
340
341 string
342 command_history::get_entry (int n)
343 {
344 string retval;
345
346 HIST_ENTRY *entry = history_get (history_base + n);
347
348 if (entry && entry->line)
349 retval = entry->line;
350
351 return retval;
352 }
353
354 void
355 command_history::replace_entry (int which, const string& line)
356 {
357 HIST_ENTRY *discard = replace_history_entry (which, line.c_str (), 0);
358
359 if (discard)
360 {
361 if (discard->line)
362 free (discard->line);
363
364 free (discard);
365 }
366 }
367
368 void
369 command_history::clean_up_and_save (const string& f_arg, int n)
370 {
371 string f = f_arg;
372
373 if (f.empty ())
374 f = xfile;
375
376 if (! f.empty ())
377 {
378 if (n < 0)
379 n = xsize;
380
381 stifle (n);
382
383 write_history (f.c_str ());
384 }
385 else
386 error ("command_history::clean_up_and_save: missing file name");
387 }
388
389 void
390 command_history::error (int errno)
391 {
392 (*current_liboctave_error_handler) ("%s", strerror (errno));
393 }
394
395 void
396 command_history::error (const string& s)
397 {
398 (*current_liboctave_error_handler) ("%s", s.c_str ());
399 }
400
401 /*
402 ;;; Local Variables: ***
403 ;;; mode: C++ ***
404 ;;; page-delimiter: "^/\\*" ***
405 ;;; End: ***
406 */