298 lines
		
	
	
	
		
			7.8 KiB
		
	
	
	
		
			Groff
		
	
	
	
	
	
			
		
		
	
	
			298 lines
		
	
	
	
		
			7.8 KiB
		
	
	
	
		
			Groff
		
	
	
	
	
	
| .\" $Id$
 | |
| .TH LIBPC 7 "$Revision$"
 | |
| .ad
 | |
| .SH NAME
 | |
| libpc \- library of external routines for Pascal programs
 | |
| .SH SYNOPSIS
 | |
| .ta 11n
 | |
| 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 = ?;
 | |
| 
 | |
| {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.
 | |
| 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.
 | |
| Its function is equivalent to \fIshift\fP 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.
 | |
| .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 the file name must be provided.
 | |
| The name must be zero terminated. Only text files are allowed.
 | |
| .IP 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.
 | |
| .IP pclose
 | |
| 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 the responsibility of the user 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 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.
 | |
| .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
 | |
| 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
 | |
| it is possible to only handle some of the errors in \fIq\fP. All the other errors must
 | |
| then be raised again by a call to \fItrap\fP.
 | |
| .br
 | |
| Encapsulations may be nested: a procedure may be encapsulated 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.
 | |
| Therefore, it is only allowed to jump out of procedure \fIp\fP from inside \fIq\fP 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 \fIp\fP may not have parameters.
 | |
| .PD
 | |
| .PP
 | |
| .RE
 | |
| UNIX system calls:
 | |
| .RS
 | |
| The routines of this category require global variables or routines
 | |
| of the monitor library libmon(7).
 | |
| .IP uread 10
 | |
| Equal to the read system call.
 | |
| Its normal name is blocked by the standard Pascal routine read.
 | |
| .PD 0
 | |
| .IP uwrite
 | |
| As above but for write(2).
 | |
| .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.
 | |
| This program is equivalent to the UNIX command cat(1).
 | |
| .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
 | |
| .IP ~em/lib/*/tail_pc 20
 | |
| .PD
 | |
| .SH "SEE ALSO"
 | |
| ack(1), pc_pem(6), pc_prlib(7), libmon(7)
 | |
| .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.
 |