1984-07-12 15:18:13 +00:00
|
|
|
.\" $Header$
|
1987-03-02 13:30:52 +00:00
|
|
|
.TH LIBPC 7ACK
|
1984-07-12 14:14:54 +00:00
|
|
|
.ad
|
|
|
|
.SH NAME
|
|
|
|
libpc \- library of external routines for Pascal programs
|
|
|
|
.SH SYNOPSIS
|
1986-01-20 20:39:09 +00:00
|
|
|
.ta 11n
|
1984-07-12 14:14:54 +00:00
|
|
|
const bufsize = ?;
|
|
|
|
.br
|
|
|
|
type br1 = 1..bufsize;
|
|
|
|
.br
|
|
|
|
br2 = 0..bufsize;
|
|
|
|
.br
|
|
|
|
br3 = -1..bufsize;
|
|
|
|
.br
|
|
|
|
ok = -1..0;
|
|
|
|
.br
|
|
|
|
buf = packed array[br1] of char;
|
|
|
|
.br
|
|
|
|
alfa = packed array[1..8] of char;
|
|
|
|
.br
|
|
|
|
string = ^packed array[1..?] of char;
|
|
|
|
.br
|
|
|
|
filetype = file of ?;
|
|
|
|
.br
|
|
|
|
long = record high,low:integer end;
|
|
|
|
|
|
|
|
{all routines must be declared extern}
|
|
|
|
|
|
|
|
function argc:integer;
|
|
|
|
.br
|
|
|
|
function argv(i:integer):string;
|
|
|
|
.br
|
|
|
|
function environ(i:integer):string;
|
|
|
|
.br
|
|
|
|
procedure argshift;
|
|
|
|
|
|
|
|
procedure buff(var f:filetype);
|
|
|
|
.br
|
|
|
|
procedure nobuff(var f:filetype);
|
|
|
|
.br
|
|
|
|
procedure notext(var f:text);
|
|
|
|
.br
|
|
|
|
procedure diag(var f:text);
|
|
|
|
.br
|
|
|
|
procedure pcreat(var f:text; s:string);
|
|
|
|
.br
|
|
|
|
procedure popen(var f:text; s:string);
|
|
|
|
.br
|
|
|
|
procedure pclose(var f:filetype);
|
|
|
|
|
|
|
|
procedure trap(err:integer);
|
|
|
|
.br
|
|
|
|
procedure encaps(procedure p; procedure q(n:integer));
|
|
|
|
|
|
|
|
function perrno:integer;
|
|
|
|
.br
|
|
|
|
function uread(fd:integer; var b:buf; len:br1):br3;
|
|
|
|
.br
|
|
|
|
function uwrite(fd:integer; var b:buf; len:br1):br3;
|
|
|
|
|
|
|
|
function strbuf(var b:buf):string;
|
|
|
|
.br
|
|
|
|
function strtobuf(s:string; var b:buf; len:br1):br2;
|
|
|
|
.br
|
|
|
|
function strlen(s:string):integer;
|
|
|
|
.br
|
|
|
|
function strfetch(s:string; i:integer):char;
|
|
|
|
.br
|
|
|
|
procedure strstore(s:string; i:integer; c:char);
|
|
|
|
|
|
|
|
function clock:integer;
|
|
|
|
.SH DESCRIPTION
|
|
|
|
This library contains some often used external routines for Pascal programs.
|
|
|
|
Two versions exist: one for the EM interpreter and another one
|
|
|
|
that is used when programs are translated into PDP-11 code.
|
|
|
|
The routines can be divided into several categories:
|
|
|
|
.PP
|
|
|
|
Argument control:
|
|
|
|
.RS
|
|
|
|
.IP argc 10
|
|
|
|
Gives the number of arguments provided when the program is called.
|
|
|
|
.PD 0
|
|
|
|
.IP argv
|
|
|
|
Selects the specified argument from the argument list and returns a
|
|
|
|
pointer to it.
|
|
|
|
This pointer is nil if the index is out of bounds (<0 or >=argc).
|
|
|
|
.IP environ
|
|
|
|
Returns a pointer to the i-th environment string (i>=0). Returns nil
|
|
|
|
if i is beyond the end of the environment list (UNIX version 7).
|
|
|
|
.IP argshift
|
|
|
|
Effectively deletes the first argument from the argument list.
|
1986-01-20 20:39:09 +00:00
|
|
|
Its function is equivalent to \fIshift\fP in the UNIX shell: argv[2] becomes
|
1984-07-12 14:14:54 +00:00
|
|
|
argv[1], argv[3] becomes argv[2], etc.
|
|
|
|
It is a useful procedure to skip optional flag arguments.
|
|
|
|
Note that the matching of arguments and files
|
|
|
|
is done at the time a file is opened by a call to reset or rewrite.
|
|
|
|
.PD
|
|
|
|
.PP
|
|
|
|
.RE
|
|
|
|
Additional file handling routines:
|
|
|
|
.RS
|
|
|
|
.IP buff 10
|
|
|
|
Turn on buffering of a file. Not very useful, because all
|
|
|
|
files are buffered except standard output to a terminal and diagnostic output.
|
|
|
|
Input files are always buffered.
|
|
|
|
.PD 0
|
|
|
|
.IP nobuff
|
|
|
|
Turn off buffering of an output file. It causes the current contents of the
|
|
|
|
buffer to be flushed.
|
|
|
|
.IP notext
|
|
|
|
Only useful for input files.
|
|
|
|
End of line characters are not replaced by a space and character codes out of
|
|
|
|
the ASCII range (0..127) do not cause an error message.
|
|
|
|
.IP diag
|
|
|
|
Initialize a file for output on the diagnostic output stream (fd=2).
|
|
|
|
Output is not buffered.
|
|
|
|
.IP pcreat
|
|
|
|
The same as rewrite(f), except that you must provide the filename yourself.
|
|
|
|
The name must be zero terminated. Only text files are allowed.
|
|
|
|
.IP popen
|
|
|
|
The same as reset(f), except that you must provide the filename yourself.
|
|
|
|
The name must be zero terminated. Only text files are allowed.
|
|
|
|
.IP pclose
|
|
|
|
Gives you the opportunity to close files hidden in records or arrays.
|
|
|
|
All other files are closed automatically.
|
|
|
|
.PD
|
|
|
|
.PP
|
|
|
|
.RE
|
|
|
|
String handling:
|
|
|
|
.RS
|
|
|
|
.IP strbuf 10
|
|
|
|
Type conversion from character array to string.
|
|
|
|
It is your own responsibility that the string is zero terminated.
|
|
|
|
.PD 0
|
|
|
|
.IP strtobuf
|
|
|
|
Copy string into buffer until the string terminating zero byte
|
|
|
|
is found or until the buffer if full, whatever comes first.
|
|
|
|
The zero byte is also copied.
|
|
|
|
The number of copied characters, excluding the zero byte, is returned. So if
|
|
|
|
the result is equal to the buffer length, then the end of buffer is reached
|
|
|
|
before the end of string.
|
|
|
|
.IP strlen
|
|
|
|
Returns the string length excluding the terminating zero byte.
|
|
|
|
.IP strfetch
|
|
|
|
Fetches the i-th character from a string.
|
|
|
|
There is no check against the string length.
|
|
|
|
.IP strstore
|
|
|
|
Stores a character in a string. There is no check against
|
|
|
|
string length, so this is a dangerous procedure.
|
|
|
|
.PD
|
|
|
|
.PP
|
|
|
|
.RE
|
|
|
|
Trap handling:
|
|
|
|
.RS
|
|
|
|
These routines allow you to handle almost all
|
|
|
|
the possible error situations yourself.
|
|
|
|
You may define your own trap handler, written in Pascal, instead of the
|
|
|
|
default handler that produces an error message and quits.
|
|
|
|
You may also generate traps yourself.
|
|
|
|
.IP trap 10
|
|
|
|
Trap generates the trap passed as argument (0..252).
|
|
|
|
The trap numbers 128..252 may be used freely. The others are reserved.
|
|
|
|
.PD 0
|
|
|
|
.IP encaps
|
1986-01-20 20:39:09 +00:00
|
|
|
Encapsulate the execution of \fIp\fP with the trap handler \fIq\fP.
|
|
|
|
Encaps replaces the previous trap handler by \fIq\fP, calls \fIp\fP
|
|
|
|
and restores
|
|
|
|
the previous handler when \fIp\fP returns.
|
|
|
|
If, during the execution of \fIp\fP, a trap occurs,
|
|
|
|
then \fIq\fP is called with the trap number as parameter.
|
|
|
|
For the duration of \fIq\fP the previous trap handler is restored, so that
|
|
|
|
you may handle only some of the errors in \fIq\fP. All the other errors must
|
|
|
|
then be raised again by a call to \fItrap\fP.
|
1984-07-12 14:14:54 +00:00
|
|
|
.br
|
|
|
|
Encapsulations may be nested: you may encapsulate a procedure while executing
|
|
|
|
an encapsulated routine.
|
|
|
|
.br
|
|
|
|
Jumping out of an encapsulated procedure (non-local goto) is dangerous,
|
|
|
|
because the previous trap handler must be restored.
|
1986-01-20 20:39:09 +00:00
|
|
|
Therefore, you may only jump out of procedure \fIp\fP from inside \fIq\fP and
|
1984-07-12 14:14:54 +00:00
|
|
|
you may only jump out of one level of encapsulation.
|
|
|
|
If you want to exit several levels of encapsulation, use traps.
|
1987-03-02 13:30:52 +00:00
|
|
|
See pc_prlib(7) for lists of trap numbers
|
1984-07-12 14:14:54 +00:00
|
|
|
for EM machine errors and Pascal run time system errors.
|
1986-01-20 20:39:09 +00:00
|
|
|
Note that \fIp\fP may not have parameters.
|
1984-07-12 14:14:54 +00:00
|
|
|
.PD
|
|
|
|
.PP
|
|
|
|
.RE
|
|
|
|
UNIX system calls:
|
|
|
|
.RS
|
|
|
|
The routines of this category require global variables or routines
|
1987-03-02 13:30:52 +00:00
|
|
|
of the monitor library libmon(7).
|
1984-07-12 14:14:54 +00:00
|
|
|
.IP uread 10
|
|
|
|
Equal to the read system call.
|
|
|
|
Its normal name is blocked by the standard Pascal routine read.
|
|
|
|
.PD 0
|
|
|
|
.IP uwrite
|
1987-03-02 13:30:52 +00:00
|
|
|
As above but for write(2).
|
1984-07-12 14:14:54 +00:00
|
|
|
.IP perrno
|
|
|
|
Because external data references are not possible in Pascal,
|
|
|
|
this routine returns the global variable errno, indicating the result of
|
|
|
|
the last system call.
|
|
|
|
.PD
|
|
|
|
.PP
|
|
|
|
.RE
|
|
|
|
Miscellaneous:
|
|
|
|
.RS
|
|
|
|
.IP clock 10
|
|
|
|
Return the number of ticks of user and system time consumed by the program.
|
|
|
|
.PD
|
|
|
|
.PP
|
|
|
|
.RE
|
|
|
|
The following program presents an example of how these routines can be used.
|
1987-03-02 13:30:52 +00:00
|
|
|
This program is equivalent to the UNIX command cat(1).
|
1984-07-12 14:14:54 +00:00
|
|
|
.nf
|
|
|
|
{$c+}
|
|
|
|
program cat(input,inp,output);
|
|
|
|
var inp:text;
|
|
|
|
s:string;
|
|
|
|
|
|
|
|
function argc:integer; extern;
|
|
|
|
function argv(i:integer):string; extern;
|
|
|
|
procedure argshift; extern;
|
|
|
|
function strlen(s:string):integer; extern;
|
|
|
|
function strfetch(s:string; i:integer):char; extern;
|
|
|
|
|
|
|
|
procedure copy(var fi:text);
|
|
|
|
var c:char;
|
|
|
|
begin reset(fi);
|
|
|
|
while not eof(fi) do
|
|
|
|
begin
|
|
|
|
while not eoln(fi) do
|
|
|
|
begin
|
|
|
|
read(fi,c);
|
|
|
|
write(c)
|
|
|
|
end;
|
|
|
|
readln(fi);
|
|
|
|
writeln
|
|
|
|
end
|
|
|
|
end;
|
|
|
|
|
|
|
|
begin {main}
|
|
|
|
if argc = 1 then
|
|
|
|
copy(input)
|
|
|
|
else
|
|
|
|
repeat
|
|
|
|
s := argv(1);
|
|
|
|
if (strlen(s) = 1) and (strfetch(s,1) = '-')
|
|
|
|
then copy(input)
|
|
|
|
else copy(inp);
|
|
|
|
argshift;
|
|
|
|
until argc <= 1;
|
|
|
|
end.
|
|
|
|
.fi
|
|
|
|
.PP
|
|
|
|
Another example gives some idea of the way to manage trap handling:
|
|
|
|
.nf
|
|
|
|
|
|
|
|
program bigreal(output);
|
|
|
|
const EFOVFL=4;
|
|
|
|
var trapped:boolean;
|
|
|
|
|
|
|
|
procedure encaps(procedure p;
|
|
|
|
procedure q(n:integer)); extern;
|
|
|
|
procedure trap(n:integer); extern;
|
|
|
|
|
|
|
|
procedure traphandler(n:integer);
|
|
|
|
begin if n=EFOVFL then trapped:=true else trap(n) end;
|
|
|
|
|
|
|
|
procedure work;
|
|
|
|
var i,j:real;
|
|
|
|
begin trapped:=false; i:=1;
|
|
|
|
while not trapped do
|
|
|
|
begin j:=i; i:=i*2 end;
|
|
|
|
writeln('bigreal = ',j);
|
|
|
|
end;
|
|
|
|
|
|
|
|
begin
|
|
|
|
encaps(work,traphandler);
|
|
|
|
end.
|
|
|
|
.fi
|
|
|
|
.SH FILES
|
1987-03-02 13:30:52 +00:00
|
|
|
.IP ~em/lib/*/tail_pc 20
|
1984-07-12 14:14:54 +00:00
|
|
|
.PD
|
|
|
|
.SH "SEE ALSO"
|
1987-03-02 13:30:52 +00:00
|
|
|
ack(1), pc_pem(6), pc_prlib(7), libmon(7)
|
1984-07-12 14:14:54 +00:00
|
|
|
.SH DIAGNOSTICS
|
|
|
|
Two routines may cause fatal error messages to be generated.
|
|
|
|
These are:
|
|
|
|
.IP pcreat 10
|
|
|
|
Rewrite error (trap 77) if the file cannot be created.
|
|
|
|
.PD 0
|
|
|
|
.IP popen
|
|
|
|
Reset error (trap 76) if the file cannot be opened for reading
|
|
|
|
.PD
|
|
|
|
.SH AUTHOR
|
|
|
|
Johan Stevenson, Vrije Universiteit.
|
|
|
|
.br
|
|
|
|
encaps: Ed Keizer, Vrije Universiteit.
|