LIBPC(7)

NAME
libpc - library of external routines for Pascal programs

SYNOPSIS
const    bufsize = ?;
type    br1 =  1..bufsize;
    br2 = 0..bufsize;
    br3 = -1..bufsize;
    ok = -1..0;
    buf = packed array[br1] of char;
    alfa = packed array[1..8] of char;
    string = ^packed array[1..?] of char;
    filetype = file of ?;
    long = ?; {all routines must be declared extern}
function    argc:integer;
function    argv(i:integer):string;
function    environ(i:integer):string;
procedure    argshift;
procedure    buff(var f:filetype);
procedure    nobuff(var f:filetype);
procedure    notext(var f:text);
procedure    diag(var f:text);
procedure    pcreat(var f:text; s:string);
procedure    popen(var f:text; s:string);
procedure    pclose(var f:filetype);
procedure    trap(err:integer);
procedure    encaps(procedure p; procedure q(n:integer));
function    perrno:integer;
function    uread(fd:integer; var b:buf; len:br1):br3;
function    uwrite(fd:integer; var b:buf; len:br1):br3;
function    strbuf(var b:buf):string;
function    strtobuf(s:string; var b:buf; len:br1):br2;
function    strlen(s:string):integer;
function    strfetch(s:string; i:integer):char;
procedure    strstore(s:string; i:integer; c:char);
function    clock:integer;

DESCRIPTION
This library contains some often used external routines for Pascal programs. The routines can be divided into several categories:

Argument control:

    argc
        Gives the number of arguments provided when the program is called.
    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).
    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).
    argshift
        Effectively deletes the first argument from the argument list. Its function is equivalent to shift in the UNIX shell: argv[2] becomes 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.

Additional file handling routines:

    buff
        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.
    nobuff
        Turn off buffering of an output file. It causes the current contents of the buffer to be flushed.
    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.
    diag
        Initialize a file for output on the diagnostic output stream (fd=2). Output is not buffered.
    pcreat
        The same as rewrite(f), except that the file name must be provided. The name must be zero terminated. Only text files are allowed.
    popen
        The same as reset(f), except that the file name must be provided. The name must be zero terminated. Only text files are allowed.
    pclose
        To close files hidden in records or arrays. All other files are closed automatically.

String handling:

    strbuf
        Type conversion from character array to string. It is the responsibility of the user that the string is zero terminated.
    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.
    strlen
        Returns the string length excluding the terminating zero byte.
    strfetch
        Fetches the i-th character from a string. There is no check against the string length.
    strstore
        Stores a character in a string. There is no check against string length, so this is a dangerous procedure.

Trap handling:
    These routines allow for user-level handling off almost all possible error situations. Trap handlers may be user-defined, written in Pascal, replacing the default handler that produces an error message and quits. Also, traps can be generated by the user.

    trap
        Trap generates the trap passed as argument (0..252). The trap numbers 128..252 may be used freely. The others are reserved.
    encaps
        Encapsulate the execution of p with the trap handler q. Encaps replaces the previous trap handler by q, calls p and restores the previous handler when p returns. If, during the execution of p, a trap occurs, then q is called with the trap number as parameter. For the duration of q the previous trap handler is restored, so that it is possible to only handle some of the errors in q. All the other errors must then be raised again by a call to trap.
        Encapsulations may be nested: a procedure may be encapsulated while executing an encapsulated routine.
        Jumping out of an encapsulated procedure (non-local goto) is dangerous, because the previous trap handler must be restored. Therefore, it is only allowed to jump out of procedure p from inside q and it is only allowed to jump out of one level of encapsulation. To exit several levels of encapsulation, the use of traps is required. See pc_prlib(7) for lists of trap numbers for EM machine errors and Pascal run time system errors. Note that p may not have parameters.

UNIX system calls:
    The routines of this category require global variables or routines of the monitor library libmon(7).

    uread
        Equal to the read system call. Its normal name is blocked by the standard Pascal routine read.
    uwrite
        As above but for write(2).
    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.

Miscellaneous:

    clock
        Return the number of ticks of user and system time consumed by the program.

The following program presents an example of how these routines can be used. This program is equivalent to the UNIX command cat(1).
{$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.

Another example gives some idea of the way to manage trap handling:
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.

FILES

~em/lib/*/tail_pc

SEE ALSO
ack(1), pc_pem(6), pc_prlib(7), libmon(7)

DIAGNOSTICS
Two routines may cause fatal error messages to be generated. These are:

pcreat
    Rewrite error (trap 77) if the file cannot be created.
popen
    Reset error (trap 76) if the file cannot be opened for reading

AUTHOR
Johan Stevenson, Vrije Universiteit.
encaps: Ed Keizer, Vrije Universiteit.