[m-rev.] diff: fix extras/logged_output

Julien Fischer juliensf at csse.unimelb.edu.au
Wed Jan 4 22:47:52 AEDT 2012


Branches: main, 11.07

Fix extras/logged_output: it was suffering from some bit rot and wouldn't have
worked correctly in any case since it makes use of C variable length argument
lists in an undefined manner.

extras/logged_output/logged_output.m:
 	Replace a call to an out-of-date form of the MR_incr_hp macro.

 	In the definition of the the function ME_logged_output_vprintf,
 	make a copy of the varags state variable before the first call
 	to vprintf.  This fix is _NOT_ portable, the right thing to do
 	would be to use C99's va_copy macro, but if there currently
 	appear to be some problems with the Mercury runtime headers
 	when GCC is used in C99 (or GNU99) mode.

 	Syntax and formatting updates.

extras/logged_output/main.m:
 	Syntax and formatting updates.

Julien.

Index: extras/logged_output/logged_output.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/extras/logged_output/logged_output.m,v
retrieving revision 1.2
diff -u -b -r1.2 logged_output.m
--- extras/logged_output/logged_output.m	2 May 2005 00:52:01 -0000	1.2
+++ extras/logged_output/logged_output.m	4 Jan 2012 11:35:04 -0000
@@ -1,8 +1,10 @@
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
  % Copyright (C) 2000, 2005 The University of Melbourne.
  % This file may only be copied under the terms of the GNU Library General
  % Public License - see the file COPYING.LIB in the Mercury distribution.
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
  %
  % module: 	logged_output.m
  % main author:	Peter Ross (petdr at miscrit.be)
@@ -10,8 +12,8 @@
  % This provides an implementation of a stream which writes to stdout and
  % logs to a file at the same time.
  %
-%------------------------------------------------------------------------------%
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%

  :- module logged_output.

@@ -19,25 +21,27 @@

  :- import_module io.

-:- pred logged_output__init(string::in, io__result(io__output_stream)::out,
-		io__state::di, io__state::uo) is det.
+:- pred logged_output.init(string::in, io.result(io.text_output_stream)::out,
+    io::di, io::uo) is det.

-%------------------------------------------------------------------------------%
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%

  :- implementation.

-logged_output__init(FileName, Result) -->
-	create_stream(FileName, Stream),
-	{ Result = ok(Stream) }.
+%-----------------------------------------------------------------------------%

-%------------------------------------------------------------------------------%
+logged_output.init(FileName, Result, !IO) :-
+    create_stream(FileName, Stream, !IO),
+    Result = ok(Stream).

-:- pred create_stream(string::in, io__output_stream::out, io::di, io::uo)
+%-----------------------------------------------------------------------------%
+
+:- pred create_stream(string::in, io.output_stream::out, io::di, io::uo)
  	is det.

  :- pragma foreign_proc("C",
-	create_stream(FileName::in, IOStream::out, IO0::di, IO::uo), 
+    create_stream(FileName::in, IOStream::out, _IO0::di, _IO::uo),
  	[will_not_call_mercury, promise_pure],
  "
  	MercuryFile	*stream;
@@ -45,10 +49,10 @@

  	file = fopen(FileName, ""w"");

-	MR_incr_hp((MR_Word) stream, ((sizeof(MercuryFile) / sizeof(MR_Word)) + 1));
+    MR_incr_hp_type(stream, MercuryFile);

  	stream->stream_type	= MR_FILE_STREAM;
-	stream->stream_info.file= file;
+    stream->stream_info.file = file;
  	stream->line_number	= 1;

  	stream->close		= ME_logged_output_close;
@@ -61,9 +65,7 @@
  	stream->vprintf		= ME_logged_output_vfprintf;
  	stream->putc		= ME_logged_output_putch;

-	IOStream = (MercuryFilePtr) stream;
-
-	IO = IO0;
+    IOStream = MR_wrap_output_stream(stream);
  ").


@@ -74,7 +76,8 @@
    #error ""you need to use version of the mercury compiler configured with --enable-new-mercuryfile-struct""
  #endif

-#include ""stdio.h""
+#include <stdio.h>
+#include <stdarg.h>

  int ME_logged_output_putch(MR_StreamInfo *info, int);
  int ME_logged_output_close(MR_StreamInfo *info);
@@ -107,8 +110,17 @@
  ME_logged_output_vfprintf(MR_StreamInfo *info, const char *format, va_list ap)
  {
  	int rc; 
+    va_list log_ap;
+    /*
+    ** XXX we are not allowed to resue ap after a call to vfprintf
+    ** (as this code originally did) -- doing so results in undefined
+    ** behaviour.  Making a copy of ap (here log_ap) in the following manner
+    ** is NOT portable.  (C99 provides the macro va_copy, which would allow
+    ** us to do this portably.)
+    */
+    *log_ap = *ap;
  	vfprintf(stdout, format, ap);
-	rc = vfprintf(info->file, format, ap);
+    rc = vfprintf(info->file, format, log_ap);
  	return rc;
  }

@@ -152,4 +164,5 @@
  ").

  %------------------------------------------------------------------------------%
+:- end_module logged_output.
  %------------------------------------------------------------------------------%
Index: extras/logged_output/main.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/extras/logged_output/main.m,v
retrieving revision 1.1
diff -u -b -r1.1 main.m
--- extras/logged_output/main.m	11 Aug 2000 16:50:14 -0000	1.1
+++ extras/logged_output/main.m	4 Jan 2012 07:42:21 -0000
@@ -1,28 +1,40 @@
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
  % Copyright (C) 2000 The University of Melbourne.
  % This file may only be copied under the terms of the GNU Library General
  % Public License - see the file COPYING.LIB in the Mercury distribution.
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
  %
  % module: 	main.m
  % main author:	Peter Ross (petdr at miscrit.be)
  %
  % Use the logged_output stream.
  %
-%------------------------------------------------------------------------------%
-%------------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
  :- module main.
  :- interface.
  :- import_module io.
-:- pred main(io__state::di, io__state::uo) is det.
+
+:- pred main(io::di, io::uo) is det.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
  :- implementation.
+
  :- import_module logged_output.
-main -->
-	logged_output__init("OUTPUT", Result),
-	(
-		{ Result = ok(OutputStream) }
-	->
-		io__write_string(OutputStream, "Hi there.\n")
-	;
-		io__write_string("Unable to open OUTPUT\n")
+
+main(!IO) :-
+    logged_output.init("OUTPUT", Result, !IO),
+    ( if Result = ok(OutputStream) then
+        io.write_string(OutputStream, "Hi there.\n", !IO)
+      else 
+        io.write_string("Unable to open OUTPUT\n", !IO)
  	).
+
+%-----------------------------------------------------------------------------%
+:- end_module main.
+%-----------------------------------------------------------------------------%

--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list