Initial revision
This commit is contained in:
10
modules/src/input/AtEoIF.c
Normal file
10
modules/src/input/AtEoIF.c
Normal file
@@ -0,0 +1,10 @@
|
||||
/* $Header$ */
|
||||
|
||||
/* AtEoIF : a routine doing nothing. It is called at the end of an
|
||||
inserted file.
|
||||
*/
|
||||
int
|
||||
AtEoIF()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
10
modules/src/input/AtEoIT.c
Normal file
10
modules/src/input/AtEoIT.c
Normal file
@@ -0,0 +1,10 @@
|
||||
/* $Header$ */
|
||||
|
||||
/* AtEoIT : a routine doing nothing. It is called at the end of an
|
||||
inserted text.
|
||||
*/
|
||||
int
|
||||
AtEoIT()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
413
modules/src/input/inp_pkg.body
Normal file
413
modules/src/input/inp_pkg.body
Normal file
@@ -0,0 +1,413 @@
|
||||
/* INPUT AND BUFFER HANDLING MODULE */
|
||||
|
||||
/*
|
||||
[input.X inp_pkg.spec input.h]
|
||||
Input buffering module: this module contains the routines that
|
||||
offers an input buffering mechanism to the user.
|
||||
|
||||
This module exports the following objects:
|
||||
input.h : an include-file, which must be included when using
|
||||
this module
|
||||
InsertFile() : suspend input from current buffer and obtain the
|
||||
next input characters from the specified file
|
||||
InsertText() : suspend input from current buffer and take the
|
||||
specified text as stream of input characters
|
||||
LoadChar() : (defined in input.h) read next character from
|
||||
the input ; LoadChar() invokes loadbuf() on
|
||||
encounting a ASCII NUL character
|
||||
PushBack() : (defined in input.h) push last character back onto
|
||||
the input stream; NPUSHBACK characters of pushback
|
||||
are guaranteed, provided that they have all been read
|
||||
from the current input stream
|
||||
AtEoIT() : this routine is called at the end of an inserted text.
|
||||
A default one is provided, which does nothing.
|
||||
AtEoIF() : this routine is called at the end of an inserted file.
|
||||
A default one is provided, which does nothing.
|
||||
|
||||
Imported objects are:
|
||||
INP_NPUSHBACK, INP_READ_IN_ONE, INP_TYPE, INP_VAR,
|
||||
routines from the "alloc" package, routines from the "storage"
|
||||
package, and routines from the "system" package.
|
||||
|
||||
INP_READ_IN_ONE defined: every input file is read into memory completely
|
||||
and made an input buffer. Only use it if the size of a file
|
||||
fits always fits in an integer and you have lots of memory.
|
||||
INP_READ_IN_ONE not defined: the input from files is buffered in
|
||||
a fixed length input buffer
|
||||
INP_NPUSHBACK: the number of characters pushback
|
||||
*/
|
||||
|
||||
#include <alloc.h>
|
||||
#include <system.h>
|
||||
|
||||
#ifndef INP_NPUSHBACK
|
||||
#define INP_NPUSHBACK 1
|
||||
#endif
|
||||
|
||||
#if INP_NPUSHBACK < 1
|
||||
#define INP_NPUSHBACK 1
|
||||
#endif
|
||||
|
||||
#ifndef INP_BUFSIZE
|
||||
#define INP_BUFSIZE BUFSIZ
|
||||
#endif
|
||||
|
||||
#if INP_NPUSHBACK > INP_BUFSIZE/2
|
||||
Now this is really ridiculous! You deserve what you get!!
|
||||
#endif
|
||||
|
||||
#ifdef INP_TYPE
|
||||
extern INP_TYPE INP_VAR;
|
||||
#endif INP_TYPE
|
||||
|
||||
#ifdef DEBUG
|
||||
#define PRIVATE
|
||||
#else
|
||||
#define PRIVATE static
|
||||
#endif
|
||||
|
||||
struct buffer_header {
|
||||
struct buffer_header *next;
|
||||
int bh_size; /* = strlen (text), should be unsigned */
|
||||
char *bh_text; /* pointer to buffer containing text */
|
||||
char *bh_ipp; /* current read pointer (= stacked ipp) */
|
||||
#ifdef INP_TYPE
|
||||
INP_TYPE bh_i; /* user defined */
|
||||
#endif INP_TYPE
|
||||
File *bh_fd; /* A file descriptor in case of a file */
|
||||
char bh_eofreturned; /* set if we returned eof for this buffer */
|
||||
};
|
||||
|
||||
#ifndef INP_READ_IN_ONE
|
||||
struct i_buf {
|
||||
struct i_buf *next;
|
||||
char ib_text[INP_BUFSIZE+INP_NPUSHBACK-1];
|
||||
};
|
||||
|
||||
# endif not INP_READ_IN_ONE
|
||||
|
||||
char *_ipp;
|
||||
PRIVATE struct buffer_header *head;
|
||||
|
||||
#ifdef INP_READ_IN_ONE
|
||||
/* readfile() creates a buffer in which the text of the file
|
||||
is situated. A pointer to the start of this text is
|
||||
returned. *size is initialized with the buffer length.
|
||||
*/
|
||||
|
||||
PRIVATE int
|
||||
readfile(fd, fn, size, pbuf)
|
||||
register File *fd;
|
||||
char *fn; /* file name */
|
||||
register long *size;
|
||||
extern long sys_filesize();
|
||||
char **pbuf; /* output parameter */
|
||||
{
|
||||
int rsize;
|
||||
|
||||
if (
|
||||
(*size = sys_filesize(fn)) < 0
|
||||
||
|
||||
((unsigned) (*size + 1) != (*size + 1))
|
||||
||
|
||||
!(*pbuf = malloc((unsigned) (*size + 1)))) {
|
||||
sys_close(fd);
|
||||
return 0;
|
||||
}
|
||||
if (
|
||||
!sys_read(fd, *pbuf, (int) *size, &rsize)
|
||||
||
|
||||
*size != rsize
|
||||
) {
|
||||
sys_close(fd);
|
||||
free(*pbuf);
|
||||
return 0;
|
||||
}
|
||||
sys_close(fd);
|
||||
(*pbuf)[*size] = '\0'; /* invoke loadbuf() at end */
|
||||
return 1;
|
||||
}
|
||||
#endif INP_READ_IN_ONE
|
||||
|
||||
#ifndef INP_READ_IN_ONE
|
||||
/* Input buffer supplying routines: pushbuf()
|
||||
*/
|
||||
|
||||
PRIVATE struct i_buf *i_ptr;
|
||||
|
||||
PRIVATE char *
|
||||
pushbuf()
|
||||
{
|
||||
register struct i_buf *ib =
|
||||
(struct i_buf *) malloc(sizeof(struct i_buf));
|
||||
|
||||
if (!ib) return 0;
|
||||
ib->next = i_ptr;
|
||||
i_ptr = ib;
|
||||
|
||||
/* Don't give him all of it, we need some to implement a good
|
||||
PushBack
|
||||
*/
|
||||
return &(ib->ib_text[INP_NPUSHBACK-1]);
|
||||
}
|
||||
#endif not INP_READ_IN_ONE
|
||||
|
||||
/* Input buffer administration: push_bh() and pop_bh()
|
||||
*/
|
||||
PRIVATE struct buffer_header *
|
||||
push_bh()
|
||||
{
|
||||
register struct buffer_header *bh;
|
||||
|
||||
if (bh = head) {
|
||||
bh->bh_ipp = _ipp;
|
||||
#ifdef INP_TYPE
|
||||
bh->bh_i = INP_VAR;
|
||||
#endif INP_TYPE
|
||||
}
|
||||
if (!(bh = (struct buffer_header *)malloc(sizeof(struct buffer_header)))) return 0;
|
||||
bh->next = head;
|
||||
bh->bh_eofreturned = 0;
|
||||
head = bh;
|
||||
return bh;
|
||||
}
|
||||
|
||||
/* pop_bh() uncovers the previous inputbuffer on the stack
|
||||
of headers. 0 is returned if there are no more
|
||||
inputbuffers on the stack, 1 is returned in the other case.
|
||||
*/
|
||||
PRIVATE int
|
||||
pop_bh()
|
||||
{
|
||||
register struct buffer_header *bh = head;
|
||||
|
||||
if (bh->bh_fd) { /* unstack a file */
|
||||
#ifndef INP_READ_IN_ONE
|
||||
struct i_buf *ib;
|
||||
|
||||
ib = i_ptr->next;
|
||||
free((char *) i_ptr);
|
||||
i_ptr = ib;
|
||||
#else INP_READ_IN_ONE
|
||||
free(bh->bh_text);
|
||||
#endif INP_READ_IN_ONE
|
||||
}
|
||||
|
||||
bh = bh->next;
|
||||
free((char *) head);
|
||||
head = bh;
|
||||
|
||||
if (!bh) { /* no more entries */
|
||||
head = (struct buffer_header *) 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_ipp = bh->bh_ipp; /* restore previous input pointer */
|
||||
#ifdef INP_TYPE
|
||||
INP_VAR = bh->bh_i;
|
||||
#endif INP_TYPE
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef INP_READ_IN_ONE
|
||||
/* low level I/O routine : read one block from current input
|
||||
stream : readblock
|
||||
*/
|
||||
|
||||
PRIVATE int
|
||||
readblock(fd, buf, n)
|
||||
File *fd;
|
||||
char buf[];
|
||||
int *n;
|
||||
{
|
||||
|
||||
if (!sys_read(fd, buf, INP_BUFSIZE, n)) {
|
||||
return 0;
|
||||
}
|
||||
buf[*n] = '\0';
|
||||
return 1;
|
||||
}
|
||||
#endif not INP_READ_IN_ONE
|
||||
|
||||
/* Miscellaneous routines :
|
||||
mk_filename()
|
||||
*/
|
||||
|
||||
/* mk_filename() concatenates a dir and filename.
|
||||
*/
|
||||
PRIVATE int
|
||||
mk_filename(dir, file, newname)
|
||||
register char *dir, *file;
|
||||
char **newname;
|
||||
{
|
||||
|
||||
register char *dst;
|
||||
|
||||
dst = malloc((unsigned) (strlen(dir) + strlen(file) + 2));
|
||||
if (!dst) return 0;
|
||||
*newname = dst;
|
||||
while (*dst++ = *dir++);
|
||||
*--dst = '/';
|
||||
while (*++dst = *file++);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Interface routines : InsertFile, InsertText, and loadbuf
|
||||
*/
|
||||
|
||||
int
|
||||
InsertFile(filnam, table, result)
|
||||
char *filnam;
|
||||
char *table[];
|
||||
char **result;
|
||||
{
|
||||
char *newfn = 0;
|
||||
|
||||
#ifdef INP_READ_IN_ONE
|
||||
char *text;
|
||||
long size;
|
||||
#endif INP_READ_IN_ONE
|
||||
File *fd = 0;
|
||||
|
||||
if (!filnam) fd = STDIN;
|
||||
else {
|
||||
if (table == 0 || filnam[0] == '/') {
|
||||
/* don't look in the table! */
|
||||
if (!sys_open(filnam, OP_READ, &fd)) return 0;
|
||||
}
|
||||
else {
|
||||
while (*table) {
|
||||
/* look in the directory table */
|
||||
if (!mk_filename(*table++, filnam, &newfn)) {
|
||||
return 0;
|
||||
}
|
||||
if (sys_open(newfn, OP_READ, &fd)) {
|
||||
/* free filnam ??? NO we don't know
|
||||
where it comes from!
|
||||
*/
|
||||
filnam = newfn;
|
||||
break;
|
||||
}
|
||||
free(newfn);
|
||||
newfn = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fd) {
|
||||
struct buffer_header *push_bh();
|
||||
register struct buffer_header *bh = push_bh();
|
||||
|
||||
if (!bh) {
|
||||
if (fd != STDIN) sys_close(fd);
|
||||
return 0;
|
||||
}
|
||||
#ifdef INP_READ_IN_ONE
|
||||
if (fd == STDIN) return 0; /* illegal */
|
||||
if (!readfile(fd, filnam, &size, &text)) {
|
||||
sys_close(fd);
|
||||
return 0;
|
||||
}
|
||||
bh->bh_size = size;
|
||||
_ipp = bh->bh_text = text;
|
||||
#else not INP_READ_IN_ONE
|
||||
if (
|
||||
!(_ipp = bh->bh_text = pushbuf())
|
||||
||
|
||||
!readblock(fd,_ipp,&(bh->bh_size))) {
|
||||
if (fd != STDIN) sys_close(fd);
|
||||
return 0;
|
||||
}
|
||||
#endif INP_READ_IN_ONE
|
||||
bh->bh_fd = fd; /* this is a file */
|
||||
*result = filnam;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
InsertText(text, length)
|
||||
char *text;
|
||||
{
|
||||
struct buffer_header *push_bh();
|
||||
register struct buffer_header *bh = push_bh();
|
||||
|
||||
if (!bh) return 0;
|
||||
bh->bh_size = (long) length;
|
||||
_ipp = bh->bh_text = text;
|
||||
bh->bh_fd = 0; /* No file! */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* loadbuf() is called if LoadChar meets a '\0' character
|
||||
which may be the end-of-buffer mark of the current input
|
||||
buffer. The '\0' could be genuine although not likely.
|
||||
Note: this routine is exported due to its occurence in the definition
|
||||
of LoadChar [input.h], that is defined as a macro.
|
||||
*/
|
||||
int
|
||||
loadbuf()
|
||||
{
|
||||
register struct buffer_header *bh = head;
|
||||
static char buf[INP_NPUSHBACK + 1];
|
||||
int FromFile;
|
||||
|
||||
if (!bh) { /* stack exhausted, EOF on sourcefile */
|
||||
return EOI;
|
||||
}
|
||||
|
||||
if (_ipp < &(bh->bh_text[bh->bh_size])) {
|
||||
/* a genuine '\0' character has been seen */
|
||||
return '\0';
|
||||
}
|
||||
|
||||
FromFile = (bh->bh_fd != 0);
|
||||
|
||||
#ifndef INP_READ_IN_ONE
|
||||
if (FromFile) {
|
||||
#if INP_PUSHBACK > 1
|
||||
register char *so = &(bh->bh_text[bh->bh_size]);
|
||||
register char *de = bh->bh_text;
|
||||
register int i = INP_NPUSHBACK - 1;
|
||||
|
||||
while (i-- > 0) {
|
||||
/* make sure PushBack will work */
|
||||
*--de = *--so;
|
||||
}
|
||||
#endif
|
||||
if (
|
||||
readblock(bh->bh_fd, bh->bh_text, &(bh->bh_size))
|
||||
&&
|
||||
bh->bh_size > 0
|
||||
) {
|
||||
_ipp = bh->bh_text;
|
||||
return *_ipp++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif not INP_READ_IN_ONE
|
||||
|
||||
if (!bh->bh_eofreturned) {
|
||||
bh->bh_eofreturned = 1;
|
||||
_ipp--;
|
||||
if (FromFile) {
|
||||
if (AtEoIF()) return EOI;
|
||||
}
|
||||
else {
|
||||
if (AtEoIT()) return EOI;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef INP_READ_IN_ONE
|
||||
if (FromFile && bh->bh_fd != STDIN) sys_close(bh->bh_fd);
|
||||
#endif not INP_READ_IN_ONE
|
||||
|
||||
if (pop_bh()) {
|
||||
if (*_ipp) return *_ipp++;
|
||||
return loadbuf();
|
||||
}
|
||||
_ipp = &buf[INP_NPUSHBACK];
|
||||
return EOI;
|
||||
}
|
||||
53
modules/src/input/inp_pkg.spec
Normal file
53
modules/src/input/inp_pkg.spec
Normal file
@@ -0,0 +1,53 @@
|
||||
/* This is the specification of the generic part of the input package.
|
||||
It can be instantiated by #defining or not #defining
|
||||
INP_TYPE, INP_VAR, INP_READ_IN_ONE, and INP_NPUSHBACK.
|
||||
INP_TYPE is the type of the variable INP_VAR, which contains
|
||||
all values the user wants to save when an InsertFile is done,
|
||||
and restored when an input stream is continued after a suspend.
|
||||
For instance, line numbers and position within a line might
|
||||
be interesting.
|
||||
Not defining INP_TYPE has the effect that the instantiation is
|
||||
done without saving and restoring INP_VAR.
|
||||
Defining INP_READ_IN_ONE has the effect that files will be read
|
||||
completely with one "read". Only use this if you have lots of
|
||||
memory. Not defining it causes files to be read in blocks, with
|
||||
a suitable blocksize.
|
||||
INP_NPUSHBACK is the number of PushBacks that are guaranteed
|
||||
to work. Its default value is 1.
|
||||
*/
|
||||
|
||||
/* INPUT PRIMITIVES */
|
||||
|
||||
#define LoadChar(dest) ((dest = *_ipp++) || (dest = loadbuf()))
|
||||
#define PushBack() (--_ipp)
|
||||
|
||||
/* EOF may be defined as -1 in most programs but the character -1 may
|
||||
be expanded to the int -1 which causes troubles at the indexing in
|
||||
the class or boolean arrays.
|
||||
*/
|
||||
#define EOI (0200)
|
||||
|
||||
extern char *_ipp;
|
||||
|
||||
/* int InsertFile(filename, table, result)
|
||||
char *filename;
|
||||
char **table;
|
||||
char **result;
|
||||
|
||||
This function suspends input from the current input stream. The next
|
||||
characters are obtained from the file indicated by "filename". This file
|
||||
will be looked for in the directories, mentioned in the null-terminated
|
||||
list indicated by "table". It returns 1 if it succeeds, 0 if it fails.
|
||||
"result" will contain the full path if InsertFile returns 1.
|
||||
*/
|
||||
extern int InsertFile();
|
||||
|
||||
/* int InsertText(text, length)
|
||||
char *text;
|
||||
int length;
|
||||
This funtion suspends input from the current input stream. The next
|
||||
input characters are obtained from the string indicated by "text",
|
||||
whose length is indicated by "length".
|
||||
It returns 1 if it succeeds, 0 if it fails.
|
||||
*/
|
||||
extern int InsertText();
|
||||
140
modules/src/input/input.3
Normal file
140
modules/src/input/input.3
Normal file
@@ -0,0 +1,140 @@
|
||||
.TH INPUT 3 "March 25, 1986"
|
||||
.SH NAME
|
||||
LoadChar, PushBack, InsertFile, InsertText, AtEoIF, AtEoIT\ \-\ input
|
||||
module for compilers
|
||||
.SH SYNOPSIS
|
||||
.B LoadChar(ch)
|
||||
.br
|
||||
.B int ch;
|
||||
.PP
|
||||
.B PushBack()
|
||||
.PP
|
||||
.B int InsertFile(filename, table, result)
|
||||
.br
|
||||
.B char *filename;
|
||||
.br
|
||||
.B char *table[];
|
||||
.br
|
||||
.B char **result;
|
||||
.PP
|
||||
.B int InsertText(text, length)
|
||||
.br
|
||||
.B char *text;
|
||||
.br
|
||||
.B int length;
|
||||
.PP
|
||||
.B int AtEoIF()
|
||||
.PP
|
||||
.B int AtEoIT()
|
||||
.SH DESCRIPTION
|
||||
This set of variables, macros and routines provides a fast input mechanism
|
||||
for use by compilers.
|
||||
They also provide a means of inserting new input streams,
|
||||
thereby temporarily suspending an input
|
||||
stream to read another one.
|
||||
The \fBcurrent input stream\fR is the last inserted input stream that
|
||||
has not reached its end.
|
||||
.PP
|
||||
The module is generic: it must be instantiated by #defining INP_TYPE,
|
||||
INP_VAR, INP_READ_IN_ONE, INP_BUFSIZE, and INP_NPUSHBACK.
|
||||
An instantiation can be obtained by creating two files: \fIinput.c\fR and
|
||||
\fIinput.h\fR.
|
||||
\fIinput.h\fR could contain the following:
|
||||
.PP
|
||||
.RS
|
||||
.nf
|
||||
#define INP_NPUSHBACK 2
|
||||
#define INP_TYPE struct f_info
|
||||
#define INP_VAR file_info
|
||||
#define INP_BUFSIZE 4096
|
||||
|
||||
#include <inp_pkg.spec>
|
||||
.fi
|
||||
.RE
|
||||
.PP
|
||||
and \fIinput.c\fR could contain:
|
||||
.PP
|
||||
.RS
|
||||
.nf
|
||||
#include "f_info.h" /* contains definition for struct f_info */
|
||||
#include "input.h"
|
||||
#include <inp_pkg.body>
|
||||
.fi
|
||||
.RE
|
||||
.PP
|
||||
The user may associate certain data with each input stream. The input module
|
||||
has a facility to save these data when inserting a new input stream, and
|
||||
restoring them when restoring the suspended input stream. Examples of these
|
||||
data are for instance a linenumber, a filename, etc.
|
||||
These data must be collected in a variable INP_VAR of type INP_TYPE.
|
||||
INP_VAR and INP_TYPE must be preprocessor-#defined.
|
||||
Not #defining INP_TYPE has the effect that an instantiation will be created
|
||||
that does not save and restore these data.
|
||||
.PP
|
||||
INP_NPUSHBACK is the number of PushBacks that are guaranteed to work.
|
||||
Its default value is 1. It is expected to be small.
|
||||
.PP
|
||||
INP_READ_IN_ONE can either be defined or not defined. Defining it has the
|
||||
effect that files will be read completely with one read-system call. This
|
||||
should only be used on machines with lots of memory.
|
||||
.PP
|
||||
INP_BUFSIZE defines the input buffer size that is used when INP_READ_IN_ONE
|
||||
is not defined. Its default value is BUFSIZ, from the \fIsystem\fP(3) module.
|
||||
.PP
|
||||
The macro \fILoadChar\fR stores the next character from the current input stream
|
||||
in the variable \fIch\fR,
|
||||
which is passed as a parameter.
|
||||
Note that this simulates an output parameter!
|
||||
When the end of the current input stream is reached, the next character from
|
||||
the last suspended input stream will be stored, etc.
|
||||
If there are no suspended input streams left, the constant EOI,
|
||||
which is defined in \fIinp_pkg.spec\fR, is returned.
|
||||
.PP
|
||||
The macro \fIPushBack\fR pushes the last character read back onto the
|
||||
input stream.
|
||||
.PP
|
||||
The routine \fIInsertFile\fR suspends input from the current input stream.
|
||||
The next input characters will be obtained from the specified file
|
||||
\fIfilename\fR.
|
||||
This file will be looked for in the directories, mentioned in the
|
||||
null-terminated list \fItable\fR.
|
||||
If \fIfilename\fR is a null pointer, standard input is used. In this case,
|
||||
the package may not have been instantiated with INP_READ_IN_ONE defined.
|
||||
\fIInsertFile\fR returns 1 if it succeeds, 0 if it fails.
|
||||
When it succeeds, it stores the file name in the \fIresult\fR parameter.
|
||||
.PP
|
||||
The routine \fIInsertText\fR also suspends input from the current input stream.
|
||||
The next input characters will be obtained from the string \fItext\fR,
|
||||
which is \fIlength\fR characters long.
|
||||
\fIInsertText\fR returns 1 if it succeeds, 0 if it fails.
|
||||
.PP
|
||||
The routine \fIAtEoIF\fR is called at the end of the input stream
|
||||
inserted by \fIInsertFile\fR.
|
||||
If it returns 1, the LoadChar causing the call returns EOI, otherwize
|
||||
the LoadChar returns the next character of the suspended and now restored
|
||||
input stream.
|
||||
A default \fIAtEoIF\fR is provided. It does nothing, and returns 0,
|
||||
making the "unstacking" completely transparent.
|
||||
The user of the module can write his own if this is not what he wants.
|
||||
.PP
|
||||
The routine \fIAtEoIT\fR is called at the end of the string
|
||||
inserted by \fIInsertText\fR.
|
||||
If it returns 1, the LoadChar causing the call returns EOI, otherwise
|
||||
the LoadChar returns the next character of the suspended and now restored
|
||||
input stream.
|
||||
A default \fIAtEoIT\fR is provided. It does nothing, and returns 0,
|
||||
making the "unstacking" completely transparent.
|
||||
The user of the module can write his own if this is not what he wants.
|
||||
.SH FILES
|
||||
~em/modules/pkg/inp_pkg.spec
|
||||
.br
|
||||
~em/modules/pkg/inp_pkg.body
|
||||
.br
|
||||
~em/modules/lib/libinput.a
|
||||
.SH MODULES
|
||||
system(3), alloc(3)
|
||||
.SH "SEE ALSO"
|
||||
\fIGeneric Packages in C\fR by Dick Grune.
|
||||
.SH BUGS
|
||||
A \fILoadChar\fR-call does look like a function call,
|
||||
but behaves differently. All for the sake of speed of course ...
|
||||
Reference in New Issue
Block a user