Someone it has been said that every program starts as cat, which copies standard input to standard output. It’s one of the first programs in Kernighan and Ritchie.
program ToyCopy;
var
src : file of byte;
tgt : file of byte;
b : byte;
begin
reset(src, 'tmp/input.txt');
rewrite(tgt, 'tmp/toycopy.txt');
while not eof(src) do
begin
read(src, b);
write(tgt, b);
end;
close(src);
close(tgt);
end.
The challenge is to restructure this program so that i/o can be sent to whereve we want.
Here we’ve rewritten the program to use external routines for the i/o. Note that we’ve had to change the program logic slightly, because in C the EOF occurs only when we ‘read past the end’.
program ToyCopy2;
type
Cfile = ^byte; { It's just a pointer, to what we don't know. }
{ Open for input and output. }
procedure tp_reset(var file_pointer : Cfile;
name_of_file : CString);
external name 'tp_reset';
procedure tp_rewrite(var file_pointer : Cfile;
name_of_file : CString);
external name 'tp_rewrite';
{ Close and end of file. }
procedure tp_close(file_pointer : Cfile);
external name 'tp_close';
function tp_eof(file_pointer : Cfile) : boolean;
external name 'tp_eof';
{ Read and write. }
procedure tp_read( file_pointer : Cfile;
var b : byte);
external name 'tp_read';
procedure tp_write(file_pointer : Cfile;
b : byte);
external name 'tp_write';
var
src : Cfile;
tgt : Cfile;
b : byte;
begin
tp_reset(src, 'tmp/input.txt');
tp_rewrite(tgt, 'tmp/toycopy2.txt');
while not tp_eof(src) do
begin
tp_read(src, b);
{ In C the EOF occurs only when we read 'past the end'. }
if not tp_eof(src) then
tp_write(tgt, b);
end;
tp_close(src);
tp_close(tgt);
end.
And here we’ve implemented these external routines.
/*
It's easier to implement this using stdio rather than the low-level
i/o provided by system calls.
*/
#include <stdio.h>
void tp_reset(FILE **file_pointer, char *name_of_file){
*file_pointer = fopen(name_of_file, "rb");
}
void tp_rewrite(FILE **file_pointer, char *name_of_file){
*file_pointer = fopen(name_of_file, "wb");
}
void tp_close(FILE *file_pointer){
fclose(file_pointer);
}
int tp_eof(FILE *file_pointer){
return feof(file_pointer);
}
void tp_read(FILE *file_pointer, char *b){
*b = getc(file_pointer);
}
void tp_write(FILE *file_pointer, char b){
putc(b, file_pointer);
}