Board index » delphi » Q: How to redirect output to screen AND a file

Q: How to redirect output to screen AND a file

Does anyone know of a simple way of optionally redirecting output to
BOTH the screen and a file.
The usual way (according to the FAQ) is:

if WriteOnlyToScreen then
  assign (OutputFile, )    {  or assignCrt  }
else
  assign (OutputFile, MyFile);
rewrite (OutputFile);
write (OutputFile, MyOutputMessage);

However, this will send the output to either the screen or the file, but
not to both. What I need is a way of writing always to the screen and
also, optionally, to a file, without having to rewrite all the write
commands twice, like:

assign (OutputFile, MyFile);
rewrite (OutputFile);
write (MyOutputMessage);
if not WriteOnlyToScreen then
  write (OutputFile, MyOutputMessage);

For those who know Common Lisp, it is an equivalent of dribble that I am
looking for.
Thanks a lot in advance.

 

Re:Q: How to redirect output to screen AND a file


Quote
marisa (mar...@kabelfoon.nl) wrote:

: Does anyone know of a simple way of optionally redirecting output to
: BOTH the screen and a file.

       You need to make a variable toggle and assign
a key to toggle it off and on.

Screen_Only:= 1;

if Ch = #15 then Screen_Only:= Screen_Only + 1;    
    (*  Shift-TAB or something *)
   if Screen_Only > 1 then Screen_Only:= 0;              

       if Screen_Only = 0 then
          Write(file,' ');
          Write(' ');    (* This line always writes *)      

Ken Fischer

---

Re:Q: How to redirect output to screen AND a file


Quote
Ken Fischer wrote:
> marisa (mar...@kabelfoon.nl) wrote:
> : Does anyone know of a simple way of optionally redirecting output to
> : BOTH the screen and a file.

>        You need to make a variable toggle and assign
> a key to toggle it off and on.

> Screen_Only:= 1;

> if Ch = #15 then Screen_Only:= Screen_Only  1;
>     (*  Shift-TAB or something *)
>    if Screen_Only > 1 then Screen_Only:= 0;

>        if Screen_Only = 0 then
>           Write(file,' ');
>           Write(' ');    (* This line always writes *)

> Ken Fischer

Thank you Ken. The problem is that I have tens of write commands in my
program, and your solution would really  clutter it if I had to go all
over each of these lines.
I could define a procedure MyWrite, which would work exactly as you've
written, and then change all the write calls by references to MyWrite.
That would be very simple. However, I was wondering if there was an idiom
for this particular problem in (Turbo) Pascal.
Thanks again.
Marisa

Re:Q: How to redirect output to screen AND a file


In article <357A5334.E8F85...@kabelfoon.nl>,

Quote
marisa  <mar...@kabelfoon.nl> wrote:

:Does anyone know of a simple way of optionally redirecting output to
:BOTH the screen and a file.
:The usual way (according to the FAQ) is:

Maybe you've been reading a diffrent FAQ :-). No guarantees, but try
the TPULOG.

 143222 May 26 1998 ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip
 tsfaqp.zip Common Turbo Pascal Questions and Timo's answers, linked

-Subject: Directing output also to printer

2. *****
 Q: I want to have a printed documentation of my students' Turbo
Pascal program exercises. How is all input and output directed also
to the printer?

 A1: Use a screen capturing program to put everything that comes
onto the screen into a file, and print the file. See FAQPROGS.TXT in
ftp://garbo.uwasa.fi/pc/ts/tsfaqn47.zip (or whatever version number
is the current) for more about these programs. Available by
anonymous FTP or mail server from garbo.uwasa.fi.

 A2: See the code in TSPAS.NWS (item: Redirecting writes to the
printer) in the ftp://garbo.uwasa.fi/pc/ts/tspa3570.zip (or whatever
is the current version number) Turbo Pascal units package (70 = 40,
50, 55, 60, or 70 depending on your TP version). Alternatively use
USECON and USEPRN routines in the TSUNTG unit of the same package.

     +------------------------------------------+
     ! To get these and other packages given as !
     !   /dir/subdir/name                       !
     ! see the instructions in PD2ANS.TXT       !
     +------------------------------------------+

 A3: But the really elegant solution to the problem of getting a
logfile (or a printed list) of a Turbo Pascal run is to rewrite the
write(ln) and read(ln) device driver functions. In itself writing
such driver redirections is very advanced Turbo Pascal programming,
but when the programming has once been done, the system is extremely
easy to use as many times as you like. It goes like this. The driver
redirections are programmed into a unit (say, tpulog or tpuprn). All
that is needed after that is to include the following uses statement
into the program (the target program) which has to be logged:
      uses TPULOG;    ( or )    uses TPUPRN;
This is all there is to it. Just adding one simple line to the
target program. (If you call any other units, "uses tpulog" must
come AFTER the system units (e.g. Dos), but BEFORE any which you may
define yourself!)
   The reason that I have named two units here instead of just one
in the above example is that the preferred log for the target
program may be a logfile or the printer. The better solution of
these two is to use the logfile option, and then print it. The
reason is simple. If the target program itself prints something,
your printout will look confused.
   The logging also has obvious limitations. It works for standard
input and output (read(ln) and write(ln)) only. 1) It does not
support graphics, in other words it is for the textmode. 2) It does
not support direct (Crt) screen writes. 3) And, naturally it only
shows the input and output that comes to the screen. Not any other
input or output, such as from or to a file. 4) Furthermore, you are
not allowed to reassign input or output. Statements like assign
(output, '') will result in a crash, because the rewritten output
device redirections are invalidated by such statements. 5) The
device on the default drive must not be write protected, since else
the logfile cannot be written to it. 6) It does not work for Turbo
Pascal 4.0. Despite these restrictions, the method is perfectly
suited for logging students' Turbo Pascal escapades.
   It is advisable first to test and run your target program without
"tpulog", so that if you get any strange errors you'll know whether
they are caused by the logging.
   Where to get such a unit. The code can be found in Michael
Tischer (1990), Turbo Pascal Internals, Abacus, Section 4.2. Next a
few of my own tips on this unit Tischer calls Prot. 1) The code is
in incorrect order. The code that is listed on pages 142 - 145 goes
between pages 139 and 140. 2) You can change the logfile name (const
prot_name) to lpt1 for a printed list of the target program run. In
that case it is advisable to include a test for the online status of
the printer within Tischer's unit. 3) I see no reason why the two
lines in Tischer's interface section couldn't be transferred to the
implementation section. Why have any global definitions?  But all in
all, it works like magic!

 A4: From: abcsc...@csunb.csun.edu (Naoto Kimura (ACM))
Subject: Re: Printing a log of students' exercises revisited
To: t...@uwasa.fi
Date: Fri, 2 Nov 90 20:52:03 pdt
[Reproduced with Naoto's kind permission]
By the way, several months ago, I had submitted a file (nktools.zip)
file on SimTel that contains sources to a unit (LOGGER), which
allows logging of I/O going through the standard input and output
files, while still being able to use the program interactively.  I
believe that I also submitted a copy to your site.  It was something
I put together for use by students here at California State
University at Northridge.  The source works equally well in all
presently available versions of Turbo Pascal.
The only requirements are that
 * you place it as one of the last entries in the USES clause.  If
   there is anything that redirects the standard input and output
   file variables, you should put that unit before my unit in the
   USES clause, so that it can see the I/O stream.
 * Don't use the GotoXY and similar screen display control
   procedures in the Crt unit and expect it to come out the same way
   you had it on the display.  Since all my unit does is just
   capture the I/O stream to send it through the normal channels and
   also to the log file, all screen control information is not sent
   to the log file.
 * All I/O you want logged should go through the standard input and
   output file variables.
 * Don't close the standard input and output file variables, because
   it will cause problems.  Basically, as far as I have checked, it
   just causes the logging to stop at that point.
--------------------------------------------------------------------

   All the best, Timo

....................................................................
Prof. Timo Salmi   Co-moderator of news:comp.archives.msdos.announce
Moderating at ftp:// & http://garbo.uwasa.fi/ archives 193.166.120.5
Department of Accounting and Business Finance  ; University of Vaasa
mailto:t...@uwasa.fi <http://www.uwasa.fi/~ts/>  ; FIN-65101,  Finland

Spam foiling in effect.  My email filter autoresponder will return a
required email password to users not yet in the privileges database.

Re:Q: How to redirect output to screen AND a file


Quote
marisa (mar...@kabelfoon.nl) wrote:
: Ken Fischer wrote:

: >        You need to make a variable toggle and assign
: > a key to toggle it off and on.
: >
: > Screen_Only:= 1;
: >
: > if Ch = #15 then Screen_Only:= Screen_Only  1;
: >     (*  Shift-TAB or something *)
: >    if Screen_Only > 1 then Screen_Only:= 0;
: >
: >        if Screen_Only = 0 then
: >           Write(file,' ');
: >           Write(' ');    (* This line always writes *)
:
: Thank you Ken. The problem is that I have tens of write commands in my
: program, and your solution would really  clutter it if I had to go all
: over each of these lines.

      I apologize, I wrote that at 04:30 local time,
and when I woke up I realized what I left out.

: I could define a procedure MyWrite, which would work exactly as you've
: written, and then change all the write calls by references to MyWrite.
: That would be very simple. However, I was wondering if there was an idiom
: for this particular problem in (Turbo) Pascal.

        I don't know of any.   If the messages exist as
strings, or are converted to strings, the toggle could
then also send the string to another procedure to write
to file or device.
        Sorry I left that out.

Ken Fischer

---

Re:Q: How to redirect output to screen AND a file


Quote
marisa (mar...@kabelfoon.nl) wrote:

: Does anyone know of a simple way of optionally redirecting output to
: BOTH the screen and a file.
: [snip]
: However, this will send the output to either the screen or the file, but
: not to both. What I need is a way of writing always to the screen and
: also, optionally, to a file, without having to rewrite all the write
: commands twice, like:
:
: assign (OutputFile, MyFile);
: rewrite (OutputFile);
: write (MyOutputMessage);
: if not WriteOnlyToScreen then
:   write (OutputFile, MyOutputMessage);
:
: For those who know Common Lisp, it is an equivalent of dribble that I am
: looking for.

       I am probably being silly for asking, but do
you leave the file open and use the "Append" statement?

Ken Fischer

---

Re:Q: How to redirect output to screen AND a file


Quote
marisa (mar...@kabelfoon.nl) wrote:
> For those who know Common Lisp, it is an equivalent of dribble that I am
> looking for.

I haven't followed the whole thread, but hasn't a TFDD solution like
TextLog on my web page been suggested?

Frank

--
Frank Heckenbach, frank@[NOSPAM.REMOVE.THIS]pascal.gnu.de
Internet links:   http://fjf.gnu.de/
Pascal programs:  http://fjf.gnu.de/programs.html (including BP Crt.Delay fix)
PGP and GPG keys: http://fjf.gnu.de/plan

Re:Q: How to redirect output to screen AND a file


Quote
marisa <mar...@kabelfoon.nl> wrote:
>Thank you Ken. The problem is that I have tens of write commands in my
>program,

I haven't looked at Frank H's TextLog TFDD or at Timo's TPULOG, but I
would assume that opening default INPUT file variable with either
would allow your existing writeln statements to function as you want.

If all you want is a quick-'n-dirty solution then write a new writeln
procedure.  Name it Writeln rather than MyWriteln as you suggested.
When you need to access the previous writeln, as would be the case
from within your new procedure, simply qualify the statement.
Example:   SYSTEM.Writeln(s);

Without a TFDD your replacement writeln would not be able to handle
variable number of parameters, or automatic conversion of integers,
etc.  If everything is strings you could simply a comma separated list
with concatenation +, but I'd guess your best bet all around would be
to use a TFDD.

    ...red

--
Support the anti-Spam amendment
  Join at http://www.cauce.org/

Re:Q: How to redirect output to screen AND a file


Quote
marisa (mar...@kabelfoon.nl) wrote:

: Thank you Ken. The problem is that I have tens of write commands in my
: program, and your solution would really  clutter it if I had to go all
: over each of these lines.

       Save the program under a different name with
an extension .BU so you have a permanent backup copy,
then load in the Turbo Pascal editor and do a Control-Q-A,
enter your current writeln statement when it asks what
to find, then enter your current writeln statement plus
the File write statement when it asks "replace with what?".
answer gu when it asks for optioons (g = global, u = either
upper or lower case).
      Press return and the efitor will write your duplicate
program with the file write statements, asking in each place
if you want to change that instance.

      This is also in reply to those that say they don't
like to type well enough to use llong self-descriptive
variable and procedure names, with the ease of use of the
Turbo IDE, epecially TP3.0, there is no excuse for not
making source code so descriptive that comments are not
needed, no matter what programming language being used. :-)

      And I apologize for all the terse variable names
that I have used. :-)

Ken Fischer

---

Re:Q: How to redirect output to screen AND a file


In article <Eu9CD8....@iglou.com>, Ken Fischer <kefis...@iglou.com>
writes

Quote
>marisa (mar...@kabelfoon.nl) wrote:
>: Thank you Ken. The problem is that I have tens of write commands in my
>: program, and your solution would really  clutter it if I had to go all
>: over each of these lines.

>       Save the program under a different name with
>an extension .BU so you have a permanent backup copy,
>then load in the Turbo Pascal editor and do a Control-Q-A,
>enter your current writeln statement when it asks what
>to find, then enter your current writeln statement plus
>the File write statement when it asks "replace with what?".
>answer gu when it asks for optioons (g = global, u = either
>upper or lower case).

Just fill in and tick the relevant boxes in later Tp versions.

Quote
>      Press return and the efitor will write your duplicate
>program with the file write statements, asking in each place
>if you want to change that instance.

Your suggestion will *only* work if all the writeln statements are
identical. It also will add a considerable number of bytes to the
program and slow it down somewhat.

Frank H. and Timo S. have given the solution to this. in posts in
response to this question.

--
Pedt Scragg                    <newsmas...@pedt.demon.co.uk>

Never curse the Crocodile's mother before crossing the river

Re:Q: How to redirect output to screen AND a file


In article <6lel25$...@majakka.uwasa.fi>,
  t...@majakka.uwasa.fi (Timo Salmi) wrote:

Quote

> In article <357A5334.E8F85...@kabelfoon.nl>,
> marisa  <mar...@kabelfoon.nl> wrote:
> :Does anyone know of a simple way of optionally redirecting output to
> :BOTH the screen and a file.
> :The usual way (according to the FAQ) is:

<snip>

Quote
>  A3: But the really elegant solution to the problem of getting a
> logfile (or a printed list) of a Turbo Pascal run is to rewrite the
> write(ln) and read(ln) device driver functions. In itself writing
> such driver redirections is very advanced Turbo Pascal programming,
> but when the programming has once been done, the system is extremely
> easy to use as many times as you like. It goes like this. The driver
> redirections are programmed into a unit (say, tpulog or tpuprn). All
> that is needed after that is to include the following uses statement
> into the program (the target program) which has to be logged:
>       uses TPULOG;    ( or )    uses TPUPRN;

<snip>

Quote
>    Where to get such a unit. The code can be found in Michael
> Tischer (1990), Turbo Pascal Internals, Abacus, Section 4.2. Next a
> few of my own tips on this unit Tischer calls Prot. 1) The code is
> in incorrect order. The code that is listed on pages 142 - 145 goes
> between pages 139 and 140. 2) You can change the logfile name (const
> prot_name) to lpt1 for a printed list of the target program run. In
> that case it is advisable to include a test for the online status of
> the printer within Tischer's unit. 3) I see no reason why the two
> lines in Tischer's interface section couldn't be transferred to the
> implementation section. Why have any global definitions?  But all in
> all, it works like magic!

Would it be possible for anyone who has this book (and has typed in the
above), to send me a copy of this code? (I suppose posting it here would be
frowned upon as it is copyrighted...)

Robert
--
Robert AH Prins
pri...@wcg.co.uk

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/   Now offering spam-free web-based newsreading

Re:Q: How to redirect output to screen AND a file


In article <6lel25$...@majakka.uwasa.fi>,
  t...@majakka.uwasa.fi (Timo Salmi) wrote:

Quote

> In article <357A5334.E8F85...@kabelfoon.nl>,
> marisa  <mar...@kabelfoon.nl> wrote:
> :Does anyone know of a simple way of optionally redirecting output to
> :BOTH the screen and a file.
> :The usual way (according to the FAQ) is:

<snip>

Quote
>  A3: But the really elegant solution to the problem of getting a
> logfile (or a printed list) of a Turbo Pascal run is to rewrite the
> write(ln) and read(ln) device driver functions. In itself writing
> such driver redirections is very advanced Turbo Pascal programming,
> but when the programming has once been done, the system is extremely
> easy to use as many times as you like. It goes like this. The driver
> redirections are programmed into a unit (say, tpulog or tpuprn). All
> that is needed after that is to include the following uses statement
> into the program (the target program) which has to be logged:
>       uses TPULOG;    ( or )    uses TPUPRN;

<snip>

Quote
>    Where to get such a unit. The code can be found in Michael
> Tischer (1990), Turbo Pascal Internals, Abacus, Section 4.2. Next a
> few of my own tips on this unit Tischer calls Prot. 1) The code is
> in incorrect order. The code that is listed on pages 142 - 145 goes
> between pages 139 and 140. 2) You can change the logfile name (const
> prot_name) to lpt1 for a printed list of the target program run. In
> that case it is advisable to include a test for the online status of
> the printer within Tischer's unit. 3) I see no reason why the two
> lines in Tischer's interface section couldn't be transferred to the
> implementation section. Why have any global definitions?  But all in
> all, it works like magic!

Would it be possible for anyone who has this book (and has typed in the
above), to send me a copy of this code? (I suppose posting it here would be
frowned upon as it is copyrighted...)

Robert
--
Robert AH Prins
pri...@wcg.co.uk

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/   Now offering spam-free web-based newsreading

Re:Q: How to redirect output to screen AND a file


Quote
marisa <mar...@kabelfoon.nl> wrote:
> However, this will send the output to either the screen or the file, but
> not to both. What I need is a way of writing always to the screen and
> also, optionally, to a file, without having to rewrite all the write

I've found a stream library, that has a streamobject that can be
attatched to a Text variable.
You simply creates the special stream-object, and tell it to log all
data written to a specified Text variable. Very simple, and works lik
a charm.
--
Venlig hilsen / Best regards
        Henning

  _H_P_C_o_n_s_u_l_t_     E-mail:  mailto:henning.peter...@hpc.dk
  Skoletoften 9, Blans    Work:    http://www.hpc.dk
  DK - 6400 Soenderborg   Private: http://home1.inet.tele.dk/oz1lln

Re:Q: How to redirect output to screen AND a file


In <6lo1k6$82...@nnrp2.dejanews.com>,
Robert AH Prins <prin...@wcg.co.uk> wrote:

Quote
> >    Where to get such a unit. The code can be found in Michael
> > Tischer (1990), Turbo Pascal Internals, Abacus, Section 4.2. Next a
> > few of my own tips on this unit Tischer calls Prot. 1) The code is
> > in incorrect order. The code that is listed on pages 142 - 145 goes
> > between pages 139 and 140. 2) You can change the logfile name (const
> > prot_name) to lpt1 for a printed list of the target program run. In
> > that case it is advisable to include a test for the online status of
> > the printer within Tischer's unit. 3) I see no reason why the two
> > lines in Tischer's interface section couldn't be transferred to the
> > implementation section. Why have any global definitions?  But all in
> > all, it works like magic!

> Would it be possible for anyone who has this book (and has typed in the
> above), to send me a copy of this code? (I suppose posting it here would be
> frowned upon as it is copyrighted...)

I don't have this book, but I wrote a unit TextLog which provides about
the same functionality (AFAICT from the above description, without having
the book) and is available from my web site.

--
Frank Heckenbach, frank@[NOSPAM.REMOVE.THIS]pascal.gnu.de
Internet links:   http://fjf.gnu.de/
Pascal programs:  http://fjf.gnu.de/programs.html (including BP Crt.Delay fix)
PGP and GPG keys: http://fjf.gnu.de/plan

Other Threads