comparison src/pager.cc @ 13983:7dd7cccf0757

clean up memory allocated for singletons before exit * singleton-cleanup.h, singleton-cleanup.cc: New files. * liboctave/Makefile.am (INCS, LIBOCTAVE_CXX_SOURCES): Add them to the lists. * toplev.cc (clean_up_and_exit): Call singleton_cleanup_list::cleanup. * debug.h, debug.cc (bp_table::instance_ok): Move definition to debug.cc. * coment-list.h (octave_comment_buffer::~octave_comment_buffer): Define destructor for class. * ov-typeinfo.h (octave_value_typeinfo::~octave_value_typeinfo): Likewise. * cmd-edit.h (command_editor::cleanup_instance): New function. * cmd-hist.h (command_history::cleanup_instance): New function. * file-ops.h (file_ops::cleanup_instance): New function. * mach-info.h (oct_mach_info::cleanup_instance): New function. * oct-env.h (octave_env::cleanup_instance): New function. * oct-fftw.h (octave_fftw_planner::cleanup_instance): New function. * oct-rand.h (octave_rand::cleanup_instance): New function. * oct-spparms.h (octave_sparse_params::cleanup_instance): New function. * pathsearch.h (static_members::cleanup_instance): New function. * comment-list.h (octave_comment_buffer::cleanup_instance): New function. * debug.h (bp_table::cleanup_instance): New function. * display.h (display_info::cleanup_instance): New function. * dynamic-ld.cc (octave_shlib_list::cleanup_instance, octave_mex_file_list::cleanup_instance): New functions. * dynamic-ld.h (octave_dynamic_loader::cleanup_instance): New function. * load-path.h (load_path::cleanup_instance): New function. * oct-stream.h (octave_stream_list::cleanup_instance): New function. * ov-typeinfo.h (octave_value_typeinfo::cleanup_instance): New function. * pager.h, pager.cc (octave_pager_stream::instance_ok, octave_pager_stream::cleanup_instance): New functions. (octave_diary_stream::instance_ok, octave_diary_stream::cleanup_instance): New functions. * sighandlers.h (octave_child_list::cleanup_instance): New function. * toplev.h (octave_call_stack * pager.cc (octave_pager_stream::stream, octave_diary_stream::stream): Use instance_ok to create instance. * toplev.h (octave_call_stack::cleanup_instance): New function. * cmd-edit.cc (command_editor::instance_ok): Register cleanup function. * cmd-hist.cc (command_history::instance_ok): Likewise. * file-ops.cc (file_ops::instance_ok): Likewise. * mach-info.cc (oct_mach_info::instance_ok): Likewise. * oct-env.cc (octave_env::instance_ok): Likewise. * oct-fftw.cc (octave_fftw_planner::instance_ok): Likewise. * oct-rand.cc (octave_rand::instance_ok): Likewise. * oct-spparms.cc (octave_sparse_params::instance_ok): Likewise. * pathsearch.cc (dir_path::static_members::instance_ok): Likewise. * comment-list.cc (comment_list::instance_ok): Likewise. * debug.cc (bp_table::instance_ok): Likewise. * display.cc (display_info::instance_ok): Likewise. * dynamic-ld.cc (octave_shlib_list::instance_ok, octave_mex_file_list::instance_ok, octave_dynamic_loader): Likewise. * load-path.cc (load_path::instance_ok): Likewise. * oct-stream.cc (octave_stream_list::instance_ok): Likewise. * ov-typeinfo.cc (octave_value_typeinfo::instance_ok): Likewise. * sighandlers.cc (octave_child_list::instance_ok): Likewise. * symtab.h, symtab.cc (symbol_table::scope_id::create_instance): New function. * symtab.h (symbol_table::scope_id::instance_ok): Call create_instance. * toplev.h, toplev.cc (octave_call_stack::create_instance): New function. * toplev.cc (octave_call_stack::instance_ok): Call create_instance. * pager.h, pager.cc (octave_pager_stream::set_diary_skip, octave_pager_stream::flush_current_contents_to_diary): Now static. octave_pager_stream::do_set_diary_skip, octave_pager_stream::do_flush_current_contents_to_diary): New functions. (octave_pager_stream::stream): Return std::ostream&, not octave_pager_stream&. If instance creation fails, return std::cout. (octave_diary_stream::stream): Return std::ostream&, not octave_diary_stream&. If instance creation fails, return std::cout. (octave_pager_stream::do_reset, octave_diary_stream::do_reset): Use instance_ok to create instance.
author John W. Eaton <jwe@octave.org>
date Sat, 03 Dec 2011 04:34:17 -0500
parents 79aa00a94e9e
children c15ddadffbfb
comparison
equal deleted inserted replaced
13982:6cdfbe90e2ab 13983:7dd7cccf0757
28 #include <iostream> 28 #include <iostream>
29 #include <string> 29 #include <string>
30 30
31 #include "cmd-edit.h" 31 #include "cmd-edit.h"
32 #include "oct-env.h" 32 #include "oct-env.h"
33 33 #include "singleton-cleanup.h"
34 #include "procstream.h" 34
35 35 #include "defaults.h"
36 #include <defaults.h>
37 #include "defun.h" 36 #include "defun.h"
38 #include "error.h" 37 #include "error.h"
39 #include "gripes.h" 38 #include "gripes.h"
40 #include "input.h" 39 #include "input.h"
41 #include "oct-obj.h" 40 #include "oct-obj.h"
42 #include "pager.h" 41 #include "pager.h"
42 #include "procstream.h"
43 #include "sighandlers.h" 43 #include "sighandlers.h"
44 #include "unwind-prot.h" 44 #include "unwind-prot.h"
45 #include "utils.h" 45 #include "utils.h"
46 #include "variables.h" 46 #include "variables.h"
47 47
309 { 309 {
310 flush (); 310 flush ();
311 delete pb; 311 delete pb;
312 } 312 }
313 313
314 octave_pager_stream& 314 std::ostream&
315 octave_pager_stream::stream (void) 315 octave_pager_stream::stream (void)
316 { 316 {
317 if (! instance) 317 return instance_ok () ? *instance : std::cout;
318 instance = new octave_pager_stream ();
319
320 return *instance;
321 } 318 }
322 319
323 void 320 void
324 octave_pager_stream::flush_current_contents_to_diary (void) 321 octave_pager_stream::flush_current_contents_to_diary (void)
325 { 322 {
326 if (pb) 323 if (instance_ok ())
327 pb->flush_current_contents_to_diary (); 324 instance->flush_current_contents_to_diary ();
328 } 325 }
329 326
330 void 327 void
331 octave_pager_stream::set_diary_skip (void) 328 octave_pager_stream::set_diary_skip (void)
332 { 329 {
333 if (pb) 330 if (instance_ok ())
334 pb->set_diary_skip (); 331 instance->do_set_diary_skip ();
335 } 332 }
336 333
337 // Reinitialize the pager buffer to avoid hanging on to large internal 334 // Reinitialize the pager buffer to avoid hanging on to large internal
338 // buffers when they might not be needed. This function should only be 335 // buffers when they might not be needed. This function should only be
339 // called when the pager is not in use. For example, just before 336 // called when the pager is not in use. For example, just before
340 // getting command-line input. 337 // getting command-line input.
341 338
342 void 339 void
343 octave_pager_stream::reset (void) 340 octave_pager_stream::reset (void)
344 { 341 {
345 if (! instance) 342 if (instance_ok ())
346 instance = new octave_pager_stream (); 343 instance->do_reset ();
347 344 }
348 instance->do_reset (); 345
346 void
347 octave_pager_stream::do_flush_current_contents_to_diary (void)
348 {
349 if (pb)
350 pb->flush_current_contents_to_diary ();
351 }
352
353 void
354 octave_pager_stream::do_set_diary_skip (void)
355 {
356 if (pb)
357 pb->set_diary_skip ();
349 } 358 }
350 359
351 void 360 void
352 octave_pager_stream::do_reset (void) 361 octave_pager_stream::do_reset (void)
353 { 362 {
355 pb = new octave_pager_buf (); 364 pb = new octave_pager_buf ();
356 rdbuf (pb); 365 rdbuf (pb);
357 setf (unitbuf); 366 setf (unitbuf);
358 } 367 }
359 368
369 bool
370 octave_pager_stream::instance_ok (void)
371 {
372 bool retval = true;
373
374 if (! instance)
375 {
376 instance = new octave_pager_stream ();
377
378 if (instance)
379 singleton_cleanup_list::add (cleanup_instance);
380 }
381
382 if (! instance)
383 {
384 ::error ("unable to create pager_stream object!");
385
386 retval = false;
387 }
388
389 return retval;
390 }
391
360 octave_diary_stream *octave_diary_stream::instance = 0; 392 octave_diary_stream *octave_diary_stream::instance = 0;
361 393
362 octave_diary_stream::octave_diary_stream (void) : std::ostream (0), db (0) 394 octave_diary_stream::octave_diary_stream (void) : std::ostream (0), db (0)
363 { 395 {
364 db = new octave_diary_buf (); 396 db = new octave_diary_buf ();
370 { 402 {
371 flush (); 403 flush ();
372 delete db; 404 delete db;
373 } 405 }
374 406
375 octave_diary_stream& 407 std::ostream&
376 octave_diary_stream::stream (void) 408 octave_diary_stream::stream (void)
377 { 409 {
378 if (! instance) 410 return instance_ok () ? *instance : std::cout;
379 instance = new octave_diary_stream ();
380
381 return *instance;
382 } 411 }
383 412
384 // Reinitialize the diary buffer to avoid hanging on to large internal 413 // Reinitialize the diary buffer to avoid hanging on to large internal
385 // buffers when they might not be needed. This function should only be 414 // buffers when they might not be needed. This function should only be
386 // called when the pager is not in use. For example, just before 415 // called when the pager is not in use. For example, just before
387 // getting command-line input. 416 // getting command-line input.
388 417
389 void 418 void
390 octave_diary_stream::reset (void) 419 octave_diary_stream::reset (void)
391 { 420 {
392 if (! instance) 421 if (instance_ok ())
393 instance = new octave_diary_stream (); 422 instance->do_reset ();
394
395 instance->do_reset ();
396 } 423 }
397 424
398 void 425 void
399 octave_diary_stream::do_reset (void) 426 octave_diary_stream::do_reset (void)
400 { 427 {
401 delete db; 428 delete db;
402 db = new octave_diary_buf (); 429 db = new octave_diary_buf ();
403 rdbuf (db); 430 rdbuf (db);
404 setf (unitbuf); 431 setf (unitbuf);
432 }
433
434 bool
435 octave_diary_stream::instance_ok (void)
436 {
437 bool retval = true;
438
439 if (! instance)
440 {
441 instance = new octave_diary_stream ();
442
443 if (instance)
444 singleton_cleanup_list::add (cleanup_instance);
445 }
446
447 if (! instance)
448 {
449 ::error ("unable to create diary_stream object!");
450
451 retval = false;
452 }
453
454 return retval;
405 } 455 }
406 456
407 void 457 void
408 flush_octave_stdout (void) 458 flush_octave_stdout (void)
409 { 459 {
435 // diary off; 485 // diary off;
436 // endfunction 486 // endfunction
437 // 487 //
438 // will do the right thing. 488 // will do the right thing.
439 489
440 octave_stdout.flush_current_contents_to_diary (); 490 octave_pager_stream::flush_current_contents_to_diary ();
441 491
442 if (external_diary_file.is_open ()) 492 if (external_diary_file.is_open ())
443 { 493 {
444 octave_diary.flush (); 494 octave_diary.flush ();
445 external_diary_file.close (); 495 external_diary_file.close ();
452 close_diary_file (); 502 close_diary_file ();
453 503
454 // If there is pending output in the pager buf, it should not go 504 // If there is pending output in the pager buf, it should not go
455 // into the diary file. 505 // into the diary file.
456 506
457 octave_stdout.set_diary_skip (); 507 octave_pager_stream::set_diary_skip ();
458 508
459 external_diary_file.open (diary_file.c_str (), std::ios::app); 509 external_diary_file.open (diary_file.c_str (), std::ios::app);
460 510
461 if (! external_diary_file) 511 if (! external_diary_file)
462 error ("diary: can't open diary file `%s'", diary_file.c_str ()); 512 error ("diary: can't open diary file `%s'", diary_file.c_str ());