1/* linbox/util/commentator.C 2 * Copyright (C) 1999 B. David Saunders, 3 * Jean-Guillaume Dumas 4 * Copyright (C) 2002 Bradford Hovinen 5 * 6 * Written by B. David Saunders <saunders@cis.udel.edu>, 7 * Jean-Guillaume Dumas <Jean-Guillaume.Dumas@imag.fr>, 8 * Bradford Hovinen <hovinen@cis.udel.edu> 9 * 10 * ========LICENCE======== 11 * This file is part of the library LinBox. 12 * 13 * LinBox is free software: you can redistribute it and/or modify 14 * it under the terms of the GNU Lesser General Public 15 * License as published by the Free Software Foundation; either 16 * version 2.1 of the License, or (at your option) any later version. 17 * 18 * This library is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 * Lesser General Public License for more details. 22 * 23 * You should have received a copy of the GNU Lesser General Public 24 * License along with this library; if not, write to the Free Software 25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 26 * ========LICENCE======== 27 * 28 * This file implements the ++C interface to commentators (for 29 * providing runtime commentary to the user) 30 */ 31 32/*! @internal 33 * @file util/commentator.C 34 * @brief implementation of LinBox::Commentator. 35 */ 36 37#include "linbox/linbox-config.h" 38 39#include <string> 40#include <sstream> 41#include <cmath> 42#include <cstring> 43#include <cstdlib> 44#include <cstdio> 45 46#include "linbox/util/commentator.h" 47#include "linbox/util/debug.h" 48 49#include "givaro/givpower.h" 50 51namespace LinBox 52{ 53 // ----------------------------------------------------- 54 // Mathematical routines 55 // ----------------------------------------------------- 56 double nroot (double a, long r, double precision) 57 { 58 const long rm = r - 1 ; 59 const double c1 = double (rm) / double (r), c2 = a / double (r); 60 double g = 1, pgr = 1, err = a - 1; 61 62 while (err > precision) { 63 g = g * c1 + c2 / pgr; 64 pgr = pow (g, (double) rm); 65 err = a - pgr * g; if (err < 0) err = -err; 66 } 67 68 return g; 69 } 70 71 long isnpower (long& l, long a) 72 { 73 long r = 2; 74 double g; 75 76 while ((g = nroot ((double)a, r, 0.1)) >= 2) { 77 l = (long) floor (g); 78 if (g-double (l) > 0.1) 79 ++l; 80 if (Givaro::power (l, r) == a) 81 return r; 82 ++r; 83 } 84 85 return 0; 86 } 87 88 Commentator::Commentator () : 89 cnull ("/dev/null") 90 , _estimationMethod (BEST_ESTIMATE), _format (OUTPUT_CONSOLE), 91 _show_timing (true), _show_progress (true), _show_est_time (true) 92 ,_last_line_len(0) 93 { 94 //registerMessageClass (BRIEF_REPORT, std::clog, 1, LEVEL_IMPORTANT); 95 registerMessageClass (BRIEF_REPORT, _report, 1, LEVEL_IMPORTANT); 96 registerMessageClass (PROGRESS_REPORT, _report); 97 registerMessageClass (TIMING_MEASURE, _report); 98 registerMessageClass (TIMING_ESTIMATE, _report); 99 registerMessageClass (PARTIAL_RESULT, _report); 100 registerMessageClass (INTERNAL_WARNING, _report, 10, LEVEL_NORMAL); 101 registerMessageClass (INTERNAL_ERROR, _report, 10, LEVEL_NORMAL); 102 registerMessageClass (INTERNAL_DESCRIPTION, _report); 103 } 104 Commentator::Commentator (std::ostream& out) : 105 cnull ("/dev/null") 106 , _estimationMethod (BEST_ESTIMATE), _format (OUTPUT_CONSOLE), 107 _show_timing (true), _show_progress (true), _show_est_time (true) 108 ,_last_line_len(0) 109 { 110 //registerMessageClass (BRIEF_REPORT, out, 1, LEVEL_IMPORTANT); 111 registerMessageClass (BRIEF_REPORT, out, 1, LEVEL_IMPORTANT); 112 registerMessageClass (PROGRESS_REPORT, out); 113 registerMessageClass (TIMING_MEASURE, out); 114 registerMessageClass (TIMING_ESTIMATE, out); 115 registerMessageClass (PARTIAL_RESULT, out); 116 registerMessageClass (INTERNAL_WARNING, out, 10, LEVEL_NORMAL); 117 registerMessageClass (INTERNAL_ERROR, out, 10, LEVEL_NORMAL); 118 registerMessageClass (INTERNAL_DESCRIPTION, out); 119 } 120 121 Commentator::~Commentator() 122 { 123 _report << "That's all, Folks!" << std::endl; 124 std::map <const char *, MessageClass *, C_str_Less >::iterator i; 125 for (i = _messageClasses.begin (); i != _messageClasses.end (); ++i) 126 delete i->second; 127 while (!_activities.empty()){ 128 delete _activities.top(); 129 _activities.pop(); 130 } 131 } 132 133 void Commentator::start (const char *description, const char *fn, unsigned long len) 134 { 135 if (fn == (const char *) 0 && _activities.size () > 0) 136 fn = _activities.top ()->_fn; 137 138 if (isPrinted (_activities.size () + 1, LEVEL_IMPORTANT, INTERNAL_DESCRIPTION, fn)) 139 report (LEVEL_IMPORTANT, INTERNAL_DESCRIPTION) //<< "Starting activity: " 140 << description << std::endl; 141 142 Activity *new_act = new Activity (description, fn, len); 143 144 if (isPrinted (_activities.size (), LEVEL_IMPORTANT, BRIEF_REPORT, fn)) 145 printActivityReport (*new_act); 146 147 _activities.push (new_act); 148 149 new_act->_timer.start (); 150 } 151 152 void Commentator::start (std::string description, const char *fn, unsigned long len) 153 { 154 start(description.c_str(),fn,len); 155 } 156 157 void Commentator::startIteration (unsigned int iter, unsigned long len) 158 { 159 std::ostringstream str; 160 161 str << "Iteration " << iter << std::ends; 162 163 _iteration_str = str.str (); 164 start (_iteration_str.c_str (), (const char *) 0, len); 165 } 166 167 void Commentator::stop (const char *msg, const char *long_msg, const char *fn) 168 { 169 double realtime; //, usertime, systime; 170 Activity *top_act; 171 172 linbox_check (_activities.top () != (Activity *) 0); 173 linbox_check (msg != (const char *) 0); 174 175 if (long_msg == (const char *) 0) 176 long_msg = msg; 177 178 top_act = _activities.top (); 179 180 top_act->_timer.stop (); 181 182 realtime = top_act->_timer.time (); 183 //usertime = top_act->_timer.usertime (); 184 //systime = top_act->_timer.systime (); 185 186 if (realtime < 0) realtime = 0; 187 //if (usertime < 0) usertime = 0; 188 //if (systime < 0) systime = 0; 189 190 if (fn != (const char *) 0 && 191 _activities.size () > 0 && 192 top_act->_fn != (const char *) 0 && 193 strcmp (fn, top_act->_fn) != 0) 194 { 195 report (LEVEL_IMPORTANT, INTERNAL_WARNING) 196 << "Activity report mismatch. Check that start () and stop () calls are paired correctly." << std::endl; 197 } 198 199 fn = top_act->_fn; 200 201 _activities.pop (); 202 203 if (isPrinted (_activities.size (), LEVEL_IMPORTANT, BRIEF_REPORT, fn)) 204 { 205 finishActivityReport (*top_act, msg); 206 } 207 208 if (isPrinted (_activities.size () + 1, LEVEL_IMPORTANT, INTERNAL_DESCRIPTION, fn)) { 209 std::ostream &output = report (LEVEL_IMPORTANT, INTERNAL_DESCRIPTION); 210 output.precision (4); 211 output << "Finished activity (rea: " << realtime << "s, cpu: "; 212 //output.precision (4); 213 //output << usertime << "s, sys: "; 214 //output.precision (4); 215 //output << systime << "s): " << long_msg << std::endl; 216 } 217 else if (isPrinted (_activities.size (), LEVEL_IMPORTANT, INTERNAL_DESCRIPTION, fn)) { 218 std::ostream &output = report (LEVEL_IMPORTANT, INTERNAL_DESCRIPTION); 219 output.precision (4); 220 output << "Completed activity: " << top_act->_desc << " (r: " << realtime << "s, u: "; 221 //output.precision (4); 222 //output << usertime << "s, s: "; 223 //output.precision (4); 224 //output << systime << "s) " << long_msg << std::endl; 225 } 226 227 delete top_act; 228 } 229 230 void Commentator::progress (long k, long len) 231 { 232 linbox_check (_activities.top () != (Activity *) 0); 233 234 Activity *act = _activities.top (); 235 Givaro::RealTimer tmp = act->_timer; 236 act->_timer.stop (); 237 238 if (k == -1) 239 ++(act->_progress); 240 else 241 act->_progress = (unsigned long)k; 242 243 if (len != -1) 244 act->_len = (unsigned long) len; 245 246 if (act->_progress > act->_len) 247 act->_len = act->_progress; 248 249 std::ostream &rep = report (LEVEL_IMPORTANT, PROGRESS_REPORT); 250 rep.precision (3); 251 rep.setf (std::ios::fixed); 252 rep << "Progress: " << act->_progress << " out of " << act->_len 253 << " (" << act->_timer.time () << "s elapsed)" << std::endl; 254 255 if (_show_progress && isPrinted (_activities.size () - 1, LEVEL_IMPORTANT, BRIEF_REPORT, act->_fn)) 256 updateActivityReport (*act); 257 act->_timer = tmp; 258 } 259 260 std::ostream &Commentator::report (long level, const char *msg_class) 261 { 262 linbox_check (msg_class != (const char *) 0); 263 264 _report << "$$(" << _activities.size () << ", " << level << ", " << msg_class << ")"; 265#if 0 266 if (!isPrinted (_activities.size (), level, msg_class, 267 (_activities.size () > 0) ? _activities.top ()->_fn : (const char *) 0)) 268 return cnull; 269 270 MessageClass &messageClass = getMessageClass (msg_class); 271 272 return messageClass._stream; 273#endif 274 return _report; 275 } 276 277 void Commentator::indent (std::ostream &stream) const 278 { 279 unsigned int i; 280 281 for (i = 0; i < _activities.size (); ++i) 282 stream << " "; 283 } 284 285 void Commentator::restoreActivityState (ActivityState state) 286 { 287 std::stack<Activity *> backup; 288 289 while (!_activities.empty () && _activities.top () != state._act) { 290 backup.push (_activities.top ()); 291 _activities.pop (); 292 } 293 294 if (_activities.empty ()) { 295 // Uh oh -- the state didn't give a valid activity 296 297 while (!backup.empty ()) { 298 _activities.push (backup.top ()); 299 backup.pop (); 300 } 301 } 302 } 303 304 void Commentator::setMaxDepth (long depth) 305 { 306 MessageClass &briefReportClass = getMessageClass (BRIEF_REPORT); 307 std::map <const char *, MessageClass *, C_str_Less>::iterator i; 308 309 for (i = _messageClasses.begin (); i != _messageClasses.end (); ++i) 310 if (i->second != &briefReportClass) 311 i->second->setMaxDepth (depth); 312 } 313 314 void Commentator::setMaxDetailLevel (long level) 315 { 316 MessageClass &briefReportClass = getMessageClass (BRIEF_REPORT); 317 std::map <const char *, MessageClass *, C_str_Less>::iterator i; 318 319 for (i = _messageClasses.begin (); i != _messageClasses.end (); ++i) 320 if (i->second != &briefReportClass) 321 i->second->setMaxDetailLevel (level); 322 } 323 324 MessageClass &Commentator::registerMessageClass (const char *msg_class, std::ostream &stream, unsigned long max_depth, unsigned long max_level) 325 { 326 linbox_check (msg_class != (const char *) 0); 327 328 MessageClass *new_obj = new MessageClass (*this, msg_class, stream, max_depth, max_level); 329 _messageClasses[msg_class] = new_obj; 330 return *new_obj; 331 } 332 333 MessageClass &Commentator::cloneMessageClass (const char *new_msg_class, const char *msg_class) 334 { 335 linbox_check (new_msg_class != (const char *) 0); 336 linbox_check (msg_class != (const char *) 0); 337 338 MessageClass *new_obj = new MessageClass (getMessageClass (msg_class)); 339 new_obj->_msg_class = new_msg_class; 340 _messageClasses[new_msg_class] = new_obj; 341 return *new_obj; 342 } 343 344 MessageClass &Commentator::cloneMessageClass (const char *new_msg_class, const char *msg_class, std::ostream &stream) 345 { 346 linbox_check (new_msg_class != (const char *) 0); 347 linbox_check (msg_class != (const char *) 0); 348 349 MessageClass &old_obj = getMessageClass (msg_class); 350 MessageClass *new_obj = new MessageClass (*this, new_msg_class, stream, old_obj._configuration); 351 _messageClasses[new_msg_class] = new_obj; 352 return *new_obj; 353 } 354 355 MessageClass &Commentator::getMessageClass (const char *msg_class) 356 { return *_messageClasses[msg_class]; } 357 358 void Commentator::setPrintParameters (unsigned long depth, unsigned long level, const char *fn) 359 { 360 MessageClass &briefReportClass = getMessageClass (BRIEF_REPORT); 361 std::map <const char *, MessageClass *, C_str_Less>::iterator i; 362 363 for (i = _messageClasses.begin (); i != _messageClasses.end (); ++i) 364 if (i->second != &briefReportClass) 365 i->second->setPrintParameters (depth, level, fn); 366 } 367 368 void Commentator::setBriefReportParameters (OutputFormat format, bool show_timing, bool show_progress, bool show_est_time) 369 { 370 _format = format; 371 _show_timing = show_timing; 372 _show_progress = show_progress; 373 _show_est_time = show_est_time; 374 } 375 376 bool Commentator::isPrinted (unsigned long depth, unsigned long level, const char *msg_class, const char *fn) 377 { 378 if (_messageClasses.find (msg_class) == _messageClasses.end ()) 379 return false; 380 381 MessageClass &messageClass = getMessageClass (msg_class); 382 383 return messageClass.isPrinted (depth, level, fn); 384 } 385 386 void Commentator::setBriefReportStream (std::ostream &stream) 387 { setMessageClassStream (BRIEF_REPORT, stream); } 388 389 void Commentator::setReportStream (std::ostream &stream) 390 { 391 setMessageClassStream (BRIEF_REPORT, stream); 392 setMessageClassStream (PROGRESS_REPORT, stream); 393 setMessageClassStream (TIMING_MEASURE, stream); 394 setMessageClassStream (TIMING_ESTIMATE, stream); 395 setMessageClassStream (PARTIAL_RESULT, stream); 396 setMessageClassStream (INTERNAL_ERROR, stream); 397 setMessageClassStream (INTERNAL_WARNING, stream); 398 setMessageClassStream (INTERNAL_DESCRIPTION, stream); 399 400 if (&stream == &(getMessageClass (BRIEF_REPORT)._stream)) 401 getMessageClass (BRIEF_REPORT).setMaxDepth (0); 402 } 403 404 void Commentator::setMessageClassStream (const char *msg_class, std::ostream &stream) 405 { 406 //temporarily fixed the bug in test-commentator, left memory leaking. 407 MessageClass *old_msg_class = _messageClasses[msg_class]; 408 cloneMessageClass (msg_class, msg_class, stream); 409 delete old_msg_class; 410 411 } 412 413 void Commentator::setDefaultReportFile (const char *filename) 414 { 415 _report.open (filename); 416 } 417 418 void Commentator::printActivityReport (Activity &activity) 419 { 420 MessageClass &messageClass = getMessageClass (BRIEF_REPORT); 421 422 if (_format == OUTPUT_CONSOLE) { 423 messageClass._stream << activity._desc << "..."; 424 425 if (messageClass.isPrinted (_activities.size () + 1, LEVEL_IMPORTANT, activity._fn)) 426 messageClass._stream << std::endl; 427 else if (_show_progress && activity._len > 0) { 428 messageClass._stream << " 0%"; 429 _last_line_len = (int)strlen (" 0%"); 430 } 431 else 432 _last_line_len = 0; 433 434 messageClass._smart_streambuf.stream ().flush (); 435 } 436 else if (_format == OUTPUT_PIPE && 437 (((_show_progress || _show_est_time) && activity._len > 0) || 438 messageClass.isPrinted (_activities.size () + 1, LEVEL_IMPORTANT, activity._fn))) 439 { 440 messageClass._stream << activity._desc << "..."; 441 442 if (_show_progress) 443 messageClass._stream << std::endl; 444 } 445 } 446 447 void Commentator::updateActivityReport (Activity &activity) 448 { 449 MessageClass &messageClass = getMessageClass (BRIEF_REPORT); 450 std::ostringstream str; 451 double percent = (double) activity._progress / (double) activity._len * 100.0; 452 453 if (_format == OUTPUT_CONSOLE) { 454 if (!messageClass.isPrinted (_activities.size (), LEVEL_IMPORTANT, activity._fn)) { 455 if (_show_progress) { 456 unsigned int i, old_len; 457 for (i = 0; i < _last_line_len; ++i) 458 messageClass._stream << '\b'; 459 str.width (3); 460 str << floor (percent + 0.5) << "%" << std::ends; 461 old_len = _last_line_len; 462 _last_line_len = (unsigned int)strlen (str.str ().c_str ()); 463 messageClass._stream << str.str (); 464 for (int ii = 0; ii < (int) (old_len - _last_line_len); ++ii) 465 messageClass._stream << ' '; 466 } 467 } 468 else if (messageClass.isPrinted (_activities.size () - 1, LEVEL_UNIMPORTANT, activity._fn)) { 469#if 0 470 if (_show_est_time) 471 messageClass._stream << activity._estimate.front ()._time 472 << " remaining" << std::endl; 473#endif 474 } 475 476 messageClass._smart_streambuf.stream ().flush (); 477 } 478 else if (_format == OUTPUT_PIPE) { 479 if (_show_progress) { 480 messageClass._stream << floor (percent + 0.5) << "% done"; 481#if 0 482 if (_show_est_time) 483 messageClass._stream << " (" << activity._estimate.front ()._time 484 << " remaining)"; 485#endif 486 messageClass._stream << std::endl; 487 } 488#if 0 489 else if (_show_est_time) 490 messageClass._stream << activity._estimate.front ()._time 491 << " remaining" << std::endl; 492#endif 493 } 494 } 495 496 void Commentator::finishActivityReport (Activity &activity, const char *msg) 497 { 498 MessageClass &messageClass = getMessageClass (BRIEF_REPORT); 499 unsigned int i; 500 501 if (_format == OUTPUT_CONSOLE) { 502 if (!messageClass.isPrinted (_activities.size () + 1, LEVEL_UNIMPORTANT, activity._fn)) { 503 if (_show_progress) 504 for (i = 0; i < _last_line_len; ++i) 505 messageClass._stream << '\b'; 506 507 messageClass._stream << msg; 508 509 if (_show_timing) 510 messageClass._stream << " (" << activity._timer.time () << " s)" << std::endl; 511 else 512 messageClass._stream << std::endl; 513 } 514 else if (messageClass.isPrinted (_activities.size (), LEVEL_UNIMPORTANT, activity._fn)) { 515 for (i = 0; i < _activities.size (); ++i) 516 messageClass._stream << " "; 517 518 messageClass._stream << msg; 519 //messageClass._stream << "Done: " << msg; 520 521 if (_show_timing) 522 messageClass._stream << " (" << activity._timer.time () << " s)" << std::endl; 523 else 524 messageClass._stream << std::endl; 525 } 526 527 messageClass._smart_streambuf.stream ().flush (); 528 } 529 else if (_format == OUTPUT_PIPE) { 530 for (i = 0; i < _activities.size (); ++i) 531 messageClass._stream << " "; 532 533 if (((_show_progress || _show_est_time) && activity._len > 0) || 534 messageClass.isPrinted (_activities.size () + 1, LEVEL_IMPORTANT, activity._fn)) 535 messageClass._stream << "Done: " << msg << std::endl; 536 else 537 messageClass._stream << activity._desc << ": " << msg << std::endl; 538 } 539 } 540 541 MessageClass::MessageClass (const Commentator &comm, 542 const char *msg_class, 543 std::ostream &stream, 544 unsigned long max_depth, 545 unsigned long max_level) : 546 _msg_class (msg_class), 547 _smart_streambuf (comm, stream), 548 _stream (&_smart_streambuf), 549 _max_level (max_level), 550 _max_depth (max_depth) 551 { 552 fixDefaultConfig (); 553 } 554 555 void MessageClass::setMaxDepth (long depth) 556 { 557 _max_depth = (unsigned long) depth; 558 fixDefaultConfig (); 559 } 560 561 void MessageClass::setMaxDetailLevel (long level) 562 { 563 _max_level = (unsigned long) level; 564 fixDefaultConfig (); 565 } 566 567 void MessageClass::setPrintParameters (unsigned long depth, unsigned long level, const char *fn) 568 { 569 if (fn == (const char *) 0) 570 fn = ""; 571 572 std::list <std::pair <unsigned long, unsigned long> > &config = _configuration[fn]; 573 std::list <std::pair <unsigned long, unsigned long> >::iterator i, j; 574 575 i = config.begin (); 576 577 // Iterate through preceeding elements in the std::list and remove 578 // any that specify a lower level than we are using 579 while (i != config.end () && i->first <= depth) { 580 if (i->second <= level) { 581 j = i++; 582 config.erase (j); 583 } 584 else { 585 ++i; 586 } 587 } 588 589 // Insert our new directive into the std::list 590 if (i == config.end () || i->second != level) 591 config.insert (i, std::pair <unsigned long, unsigned long> (depth, level)); 592 593 // Iterate through following elements in the std::list and remove any 594 // that specify a higher level than we are using 595 while (i != config.end ()) { 596 if (i->second > level) { 597 j = i++; 598 config.erase (j); 599 } 600 else { 601 ++i; 602 } 603 } 604 605 // End result: The std::list should be monotonically increasing in 606 // the first parameter and decreasing in the second 607 } 608 609 bool MessageClass::isPrinted (unsigned long depth, unsigned long level, const char *fn) 610 { 611 return 612 checkConfig (_configuration[""], depth, level) 613 || 614 ( fn != (const char *) 0 615 && 616 checkConfig (_configuration[fn], depth, level) 617 ); 618#if 0 619 620 if (checkConfig (_configuration[""], depth, level)) 621 return true; 622 else if (fn != (const char *) 0) 623 //return checkConfig (_configuration[fn], depth, level); 624 { bool ans = checkConfig (_configuration[fn], depth, level); 625 if (ans) 626 { //std::cerr << " fn=" << fn << ", d " << depth << ", l " << level << " true" << std::endl; 627 return true; 628 } 629 else 630 { //std::cerr << " fn=" << fn << ", d " << depth << ", l " << level << " false" << std::endl; 631 return false; 632 } 633 } 634 635 else 636 { //std::cerr << " fn=0, d " << depth << ", l " << level << " false" << std::endl; 637 return false; 638 } 639 640#endif 641 } 642 643 MessageClass::MessageClass (const Commentator &comm, 644 const char *msg_class, 645 std::ostream &stream, 646 Configuration configuration) : 647 _msg_class (msg_class), 648 _smart_streambuf (comm, stream), 649 _stream (&_smart_streambuf), 650 _configuration (configuration) 651 {} 652 653 void MessageClass::fixDefaultConfig () 654 { 655 std::list <std::pair <unsigned long, unsigned long> > &config = _configuration[""]; 656 657 config.clear (); 658 config.push_back (std::pair <unsigned long, unsigned long> (_max_depth, _max_level)); 659 config.push_back (std::pair <unsigned long, unsigned long> ((unsigned long) -1, Commentator::LEVEL_ALWAYS)); 660 } 661 662 bool MessageClass::checkConfig (std::list <std::pair <unsigned long, unsigned long> > &config, 663 unsigned long depth, 664 unsigned long ) //lvl 665 { 666 std::list <std::pair <unsigned long, unsigned long> >::iterator i; 667 668 for ( i = config.begin (); i != config.end (); ++i) { 669 if (depth < i->first) { 670#if 0 671 // uninitialized value error goes away if we ignore level. 672 if (level <= i->second) 673 return true; 674 else 675 return false; 676#endif 677 return true; 678 } 679 } 680 681 return false; 682 } 683 684 void MessageClass::dumpConfig () const 685 { 686 Configuration::const_iterator i; 687 std::list <std::pair <unsigned long, unsigned long> >::const_iterator j; 688 689 for (i = _configuration.begin (); i != _configuration.end (); ++i) { 690 std::cerr << "Configuration (" << (*i).first << "):" << std::endl; 691 692 for (j = (*i).second.begin (); j != (*i).second.end (); ++j) 693 std::cerr << " Depth: " << (*j).first << ", Level: " << (*j).second << std::endl; 694 695 std::cerr << std::endl; 696 } 697 } 698 699 int MessageClass::smartStreambuf::sync () 700 { 701 std::streamsize n = pptr () - pbase (); 702 return (n && writeData (pbase (), n) != n) ? EOF : 0; 703 } 704 705 int MessageClass::smartStreambuf::overflow (int ch) 706 { 707 std::streamsize n = pptr () - pbase (); 708 709 if (n && sync ()) 710 return EOF; 711 712 if (ch != EOF) { 713 char cbuf[1]; 714 cbuf[0] = (char)ch; 715 if (writeData (cbuf, 1) != 1) 716 return EOF; 717 } 718 719 pbump((int)-n); 720 return 0; 721 } 722 723 std::streamsize MessageClass::smartStreambuf::xsputn (const char *text, std::streamsize n) 724 { 725 return (sync () == EOF) ? 0 : writeData (text, n); 726 } 727 728 int MessageClass::smartStreambuf::writeData (const char *text, std::streamsize n) 729 { 730 std::streamsize idx; 731 std::streamsize m = n; 732 733 if (_indent_next) { 734 _comm.indent (_stream); 735 _indent_next = false; 736 } 737 738 for (idx = 0; (idx < m) &&(text[idx] != '\n') ; ++idx) ; 739 740 while (idx < m) { 741 _stream.write (text, idx + 1); 742 m -= idx + 1; 743 744 if (m > 0) 745 _comm.indent (_stream); 746 else 747 _indent_next = true; 748 749 text += idx + 1; 750 for (idx = 0; idx != '\n' && idx < m; ++idx) ; 751 } 752 753 _stream.write (text, m); 754 755 _stream.flush (); 756 757 return int(n); 758 } 759 760 // // Default global commentator 761 // Commentator commentator ; 762} 763 764// Local Variables: 765// mode: C++ 766// tab-width: 4 767// indent-tabs-mode: nil 768// c-basic-offset: 4 769// End: 770// vim:sts=4:sw=4:ts=4:et:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s 771