Mercurial > octave
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 */ |