From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13613 invoked by alias); 19 Jan 2004 21:59:17 -0000 Mailing-List: contact sid-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: sid-owner@sources.redhat.com Received: (qmail 13605 invoked from network); 19 Jan 2004 21:59:15 -0000 Received: from unknown (HELO zenia.home) (12.223.225.216) by sources.redhat.com with SMTP; 19 Jan 2004 21:59:15 -0000 Received: by zenia.home (Postfix, from userid 5433) id 0CD59208E7; Mon, 19 Jan 2004 16:58:25 -0500 (EST) To: sid@sources.redhat.com Subject: PATCH: make trace_stream better preserve std::ofstream semantics From: Jim Blandy Date: Mon, 19 Jan 2004 21:59:00 -0000 Message-ID: User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2004-q1/txt/msg00003.txt.bz2 If the user redirects trace output to a file using something like: $ sid ... -e "set basic-0/cpu trace-filename trace.hello.basic" then trace.hello.basic remains an empty file. The problem is (I think) that basic_cpu::update_trace_destination tries to close basic_cpu::trace_stream when it is already closed. cpu_trace_stream is a subclass of std::ofstream, and does not override its 'close' method. According to ISO C++, std::ofstream::close sets the stream's failbit if rdbuf ()->close fails (returns null). std::basic_filebuf::close will return null if the filebuf is not open. The first time basic_cpu::update_trace_destination gets called, cout_p is true, and the base class's stream itself has never been opened. The call to close sets the failbit, and subsequent output is ignored. This patch overrides some more functions in cpu_trace_stream to make their behavior better match that of its base class. In particular, the stream is treated as open if output is being directed to either cout or the stream itself. This doesn't completely reproduce the behavior of std::ofstream. In particular, it doesn't set failbit quite as often as it should, to be completely consistent. Rather than subclassing std::ofstream and doing this odd redirection stuff, wouldn't it be simpler to just make trace_stream an instance of plain old std::ofstream, and then call rdbuf () to set its streambuf to either cout's streambuf, or a filebuf for the trace file? sid/include/ChangeLog: 2004-01-13 Jim Blandy * sidcpuutil.h (sidutil::basic_cpu::cpu_trace_stream::is_open) (sidutil::basic_cpu::cpu_trace_stream::close): Override (non-virtual) definitions from std::ofstream, to better preserve std::ofstream's behavior, taking cout_p into account. Index: sid/include/sidcpuutil.h =================================================================== RCS file: /cvs/cvsfiles/devo/sid/include/sidcpuutil.h,v retrieving revision 1.47.2.1 diff -c -r1.47.2.1 sidcpuutil.h *** sid/include/sidcpuutil.h 22 Oct 2003 00:35:32 -0000 1.47.2.1 --- sid/include/sidcpuutil.h 14 Jan 2004 05:10:37 -0000 *************** *** 222,231 **** --- 222,241 ---- :std::ofstream (filename.c_str ()), cout_p (false) {} void divert_to_file () { cout_p = false; } void divert_to_cout () { cout_p = true; } + bool is_open () + { + return cout_p || std::ofstream::is_open (); + } void open (const std::string& filename) { std::ofstream::open (filename.c_str (), std::ios::app); cout_p = false; + } + void close () + { + if (std::ofstream::is_open ()) + std::ofstream::close (); + cout_p = false; } void end_line () {