接口摘要按字母顺序如下列出:各个小节给出每个接口的名称及其主要类型(如果有的话)。“T是不透明的X_T”的记法,表示接口X导出了一个不透明指针类型X_T,在描述中缩写为T。如果接口会公开其主要类型,那么会给出X_T的表示。
每个接口的摘要会按字母顺序分别列出导出的变量(不包括异常)后接导出的函数。每个函数的原型都后接其可能引发的异常和对函数的简要描述。缩写c.r.e.和u.r.e.分别代表已检查的运行时错误和未检查的运行时错误 [1] 。
表A-1按类别综述了本书中的各个接口。
表A-1 本书中的各个接口
T是不透明的AP_T
传递NULL的T值给任何AP函数都是已检查的运行时错误。
T AP_add(T x, T y) Mem_Failed
T AP_addi(T x, long int y) Mem_Failed
返回和值x+y。
int AP_cmp(T x, T y)
int AP_cmpi(T x, long int y)
对于x<y、x=y、x>y,分别返回<0、=0、>0的整数。
T AP_div(T x, T y) Mem_Failed
T AP_divi(T x, long int y) Mem_Failed
返回商x / y,参见Arith_div。y=0,则为已检查的运行时错误。
void AP_fmt(int code, va_list *app, Mem_Failed
int put(int c, void *cl), void *cl,
unsigned char flags[], int width, int precision)
一个Fmt转换函数:消耗一个T,并按照printf的%d限定符对其进行格式化。app或flags
是NULL,则为已检查的运行时错误。
void AP_free(T *z)
释放*z,并将其清零。z或*z为NULL,则为已检查的运行时错误。
T AP_fromstr(const char *str, int base, char **end) Mem_Failed
将str解释为base基数下的一个整数,并返回表示结果的T。在处理过程中,会忽略str前
部的空格,可以接受一个可选的符号,后接一个或多个以base为基数的数位。对于10<base≤
36,小写或大写字母解释为大于9的数位。如果end不为NULL,*end指向str中扫描
结束处的字符。如果str不表示base基数下的一个整数,那么AP_fromstr返回NULL,
并将*end设置为str(如果end不是NULL)。str为NULL或base<2或base>36,则为
已检查的运行时错误。
T AP_lshift(T x, int s) Mem_Failed
返回x左移s个比特位的值,空出的比特位填0,结果的符号与x相同。s<0,则为已检查的运行时错误。
T AP_mod(T x, T y) Mem_Failed
long AP_modi(T x, long int y) Mem_Failed
返回x mod y,参见Arith_mod。y=0,则为已检查的运行时错误。
T AP_mul(T x, T y) Mem_Failed
T AP_muli(T x, long int y) Mem_Failed
返回乘积x * y。
T AP_neg(T x) Mem_Failed
返回-x。
T AP_new(long int n) Mem_Failed
分配和返回一个新的T,其值初始化为n。
T AP_pow(T x, T y, T p) Mem_Failed
返回xy
mod p。如果p=NULL,返回xy
。y<0,或p不是NULL且p<2,则为已检查的运行时错误。
T AP_rshift(T x, int s) Mem_Failed
返回x右移s个比特位的结果,空出的比特位填0,结果的符号与x相同。s<0,则为已检查的运行时错误。
T AP_sub(T x, T y) Mem_Failed
T AP_subi(T x, long int y) Mem_Failed
返回差值x - y。
long int AP_toint(T x)
返回一个long型值,其符号与x相同,其绝对值为|x| mod LONG_MAX + 1。
char *AP_tostr(char *str, int size, int base, T x) Mem_Failed
用x在base基数下的字符表示来填充str[0..size - 1],并返回str。如果str=NULL,
AP_tostr为其分配空间。当base>10时,大写字母用于表示大于9的数位。如果str不
是NULL但容量太小,或base<2或base>36,则为已检查的运行时错误。
T是不透明的Arena_T
向任何Arena函数传递的参数nbytes≤0或T值为NULL,均为已检查的运行时错误。
void *Arena_alloc(T arena, long nbytes, Arena—Failed
const char *file, int line)
在内存池中分配nbytes个字节并返回一个指针,指向第一个字节。分配的nbytes个字节
是未初始化的。如果Arena_alloc引发Arena_Failed异常,则将file和line作为出
错的源代码位置报告。
void *Arena_calloc(T arena, long count, Arena—Failed
long nbytes, const char *file, int line)
在内存池中为一个count个元素的数组分配空间,每个数组元素占nbytes字节,并返回
一个指针指向第一个元素。count≤0则造成已检查的运行时错误。数组的各个元素是未初
始化的。如果Arena_calloc引发Arena_Failed异常,则将file和line作为出错的
源代码位置报告。
void Arena_dispose(T *ap)
释放*ap中所有的空间,释放内存池自身,并将*ap清零。ap或*ap为NULL,则是已检查的运行时错误。
void Arena_free(T arena)
释放内存池中所有
的空间,即自上一次调用Arena_free以来所有分配的空间。
T Arena_new(void) Arena_NewFailed
分配、初始化并返回一个新的内存池。
int Arith_ceiling(int x, int y)
返回不小于x/y实数商的最小整数。y=0,则为未检查的运行时错误。
int Arith_div(int x, int y)
返回x/y,若有实数z使得z * y = x,返回值即不大于实数z的最大整数。向-∞舍入,
例如,Arith_div(-13, 5)返回-3。y=0,则为未检查的运行时错误。
int Arith_floor(int x, int y)
返回不大于x/y实数商的最大整数。y=0,则为未检查的运行时错误。
int Arith_max(int x, int y)
返回max(x, y)。
int Arith_min(int x, int y)
返回min(x, y)。
int Arith_mod(int x, int y)
返回x - y * Arith_div(x, y),例如,Arith_mod(- 13, 5)返回2。y=0,则为未检查的运行时错误。
T是不透明的Array_T
数组索引从0到N-1,其中TV是数组的长度。空数组没有元素。向任何Array函数传递为NULL的T值都是已检查的运行时错误。
T Array_copy(T array, int length) Mem_Failed
创建并返回一个新的数组,其中包含array的前length个元素。如果length大于array的长度,过多的元素将被清零。
void Array_free(T *array)
释放*array并将其清零。如果array或*array是NULL,则是已检查的运行时错误。
void *Array_get(T array, int i)
返回指向第i个数组元素的指针。i<0或i≥N,则为已检查的运行时错误,其中N是array的长度。
int Array_length(T array)
返回array中元素的数目。
T Array_new(int length, int size) Mem_Failed
分配、初始化并返回一个新的数组,由length个元素组成,每个元素长度为size字节。
各个元素都被清零。length<0或size≤0,则为已检查的运行时错误。
void *Array_put(T array, int i, void *elem)
从elem复制Array_size(array)个字节到array中第i个元素并返回elem。elem=
NULL或i<0或i≥N,则为已检查的运行时错误,其中N是array的长度。
void Array_resize(T array, int length) Mem_Failed
将数组中元素的数目改为length。如果length大于原来的长度,过多的元素将清零。
length<0,则造成已检查的运行时错误。
int Array_size(T array)
返回array中元素的长度,按字节计算。
T是Array_T
typedef struct T {
int length; int size; char *array; } *T;
改变T实例中的字段,属于未检查的运行时错误。
void ArrayRep_init(T array, int length,
int size, void *ary)
将array中的各个字段初始化为length、size和ary。如果length≠0且ary=NULL,
或length=0且ary≠null,或size≤0,都是已检查的运行时错误。用其他方式初始化T
实例,属于未检查的运行时错误。
assert(e)
如果e为0,则引发Assert_Failed异常。语法上,assert(e)是一个表达式。如果包含
assert.h头文件时,已经定义了NDEBUG,则断言被禁用。
向任何Atom函数传递值为NULL的str,都是已检查的运行时错误。修改原子,属于未检查的运行时错误。
int Atom_length(const char *str)
返回原子str的长度。如果str不是原子,则造成已检查的运行时错误。
const char *Atom_new(const char *str, int len) Mem_Failed
返回对应于str[0..len - 1]的原子,如有必要则创建一个原子。len<0,则为已检查的运行时错误。
const char *Atom_string(const char *str) Mem_Failed
返回Atom_new(str, strlen(str))。
const char *Atom_int(long n) Mem_Failed
返回对应于n的十进制字符串表示的原子。
T是不透明的Bit_T
位向量中的各个比特位按0到N-1编号,其中N是该向量的长度。向任何Bit函数传递的T值为NULL,均为已检查的运行时错误(Bit_union、Bit_inter、Bit_minus和Bit_diff除外)。
void Bit_clear(T set, int lo, int hi)
清除set中lo到hi的各个比特位。lo>hi或lo<0或lo≥N或hi<0或hi≥N,均为已检
查的运行时错误,其中N为set的长度。
int Bit_count(T set)
返回set中置位比特位数目。
T Bit_diff(T s, T t) Mem_Failed
返回s和t的对称差s / t:s和t的异或。如果s=NULL或t=NULL,则表示空集。s=
NULL且t=NULL,或s和t长度不同,则为已检查的运行时错误。
int Bit_eq(T s, T t)
如果s=t,则返回1,否则返回0。如果s和t长度不同,则为已检查的运行时错误。
void Bit_free(T *set)
释放*set,并将其清零。set或*set是NULL,则造成已检查的运行时错误。
int Bit_get(T set, int n)
返回比特位n的值。n<0或n≥N,则为已检查的运行时错误,其中N是set的长度。
T Bit_inter(T s, T t) Mem_Failed
返回s ∩ t:s和t的按位与。已检查的运行时错误,请参见Bit_diff。
int Bit_length(T set)
返回set的长度。
int Bit_leq(T s, T t)
如果s⊆t, 则返回1,否则返回0。已检查的运行时错误,请参见Bit_eq。
int Bit_lt(T s, T t)
如果s⊂t, 则返回1,否则返回0。已检查的运行时错误,请参见Bit_eq。
void Bit_map(T set,
void apply(int n, int bit, void *cl),void *cl)
对set中从0到N- 1的每个比特位调用apply(n, bit, cl),其中N是set的长度。
apply对set的修改,将影响到接下来调用apply时bit参数的值。
T Bit_minus(T s, T t) Mem_Failed
返回s- t: s和~t的按位与。已检查的运行时错误,请参见Bit_diff。
T Bit_new(int length) Mem_Failed
创建并返回一个长度为length的位向量,所有比特位均为0。length<0,则造成已检查的运行时错误。
void Bit_not(T set, int lo, int hi)
对set中lo到hi的各个比特位取反。已检查的运行时错误,请参见Bit_clear。
int Bit_put(T set, int n, int bit)
Bit_put将集合中的比特位n设置为bit,并返回该比特位的原值。bit<0或bit>1,或
n<0或n≥N,均为已检查的运行时错误,其中N是set的长度。
void Bit_set(T set, int lo, int hi)
将set中的比特位lo到hi置位。已检查的运行时错误,请参见Bit_clear。
T Bit_union(T s, T t) Mem_Failed
返回s∪t: s和t的按位或。已检查的运行时错误,请参见Bit_diff。
T是不透明的Chan_T
向任何Chan函数传递的T值为NULL,或在调用Thread_init之前调用任何Chan函数,均为已检查的运行时错误。
T Chan_new(void) Mem_Failed
创建、初始化并返回一个新的通道。
int Chan_receive(T c, void *ptr, int size) Thread_Alerted
等待一个对应Chan_send操作发出数据,然后从发送来的数据中复制不超过size字节到
ptr中,并返回复制的字节数。ptr=NULL或size<0,均为已检查的运行时错误。
int Chan_send(T c, const void *ptr, int size Thread_Alerted
等待一个对应Chan_receive操作进入接收状态,然后从ptr中复制不超过size字节给
接收方,并返回复制的字节数。已检查的运行时错误,请参见Chan_receive。
T即为Except_T
typedef struct T { char *reason; } T;
TRY语句的语法如下,S和e表示语句和异常。ELSE子句是可选的。
TRY S EXCEPT(e 1 ) S 1 . . . EXCEPT(e n ) Sn ELSE S 0 END—TRY TRY S FINALLY S 1 END_TRY
void Except_raise(const T *e, const char *file, int line)
在源代码位置file和line处引发异常*e。如果e=NULL,则为已检查的运行时错误。未
捕获的异常,将导致程序终止。
RAISE(e)
引发异常e。
RERAISE
重新引发导致异常处理程序执行的异常。
RETURN
RETURN expression
是用于TRY语句内部的返回语句。在TRY语句内使用C语言的返回语句,属于未检查的运行时错误。
T即为Fmt_T
typedef void (*T)(int code,
va_list *app, int put(int c, void *cl), void *cl,
unsigned char flags[256], int width, int precision)
定义了转换函数的类型,当格式串中出现转换限定符时,由Fmt函数调用相关联的转换函数。在这里和下文中,都是调用Put(c, cl)来输出各个被格式化的字符c。表14-1汇总了最初定义的转换限定符集合。向任何Fmt函数传递的put、buf或fmt为NULL,或格式串使用了没有关联转换函数的转换限定符,都是已检查的运行时错误。
char *Fmt_flags = "-+0"
指向转换限定符中可能出现的标志字符。
void Fmt_fmt(int put(int c, void *cl), void *cl,
const char *fmt, ...)
根据格式串fmt,格式化并输出可变部分的参数。
void Fmt_fprint(FILE *stream, const char *fmt, ...)
void Fmt_print(const char *fmt, ...)
根据fmt格式化并输出可变部分的参数,Fmt_fprint写出到流,而Fmt_print输出到stdout。
void Fmt_putd(const char *str, int len,
int put(int c, void *cl), void *cl,
unsigned char flags[256], int width, int precision)
void Fmt_puts(const char *str, int len,
int put(int c, void *cl), void *cl,
unsigned char flags[256], int width, int precision)
根据Fmt的默认值(参见表14-1)和flags、width和precision的值,格式化并输出
str[0..len - 1]中转换过的数值(使用Fmt_putd输出)或字符串(使用Fmt_puts输
出)。如果str=NULL,或len<0,或flags=NULL,均为已检查的运行时错误。
T Fmt_register(int code, T cvt)
将cvt关联到格式符code,并返回此前设定的转换函数。如果code<0或code>255,则为已检查的运行时错误。
int Fmt_sfmt(char *buf, int size, Fmt_Overflow
const char *fmt, ...)
根据fmt,将参数的可变部分格式化到buf [0..size - 1]中,并添加一个0字符,最后
返回buf的长度
[2]
。如果size≤0,则为已检查的运行时错误。如果需要输出的字符数目大
于size - 1,则引发Fmt_Overflow异常。
char *Fmt_string(const char *fmt, ...)
根据fmt,将参数的可变部分格式化为一个0结尾字符串,并返回该字符串。
void Fmt_vfmt(int put(int c, void *cl),void *cl,
const char *fmt, va_list ap)
参见Fmt_fmt,本函数从可变参数列表ap获取参数。
int Fmt_vsfmt(char *buf, int size, Fmt_Overflow
const char *fmt, va_list ap)
参见Fmt_sfmt,本函数从可变参数列表ap获取参数。
char *Fmt_vstring(const char *fmt, va_list ap)
参见Fmt_string,本函数从可变参数列表ap获取参数。
T即为List_T
typedef struct T *T;
struct T { T rest; void *first; };
所有的List函数都可以接受list参数值为NULL,并将其解释为空链表。
T List_append(T list, T tail)
将tail追加到list并返回list。如果list=NULL,List_append返回tail。
T List_copy(T list) Mem_Failed
创建并返回list的一个副本(浅层复制)。
void List_free(T *list)
释放*list并将其清零。如果list=NULL,则为已检查的运行时错误。
int List_length(T list)
返回list中元素的数目。
T List_list(void *x, ...) Mem_Failed
创建并返回一个链表,其元素来自参数的可变部分,直至遇到第一个NULL指针为止。
void List_map(T list,
void apply(void **x, void *cl), void *cl)
对于list中的每个元素p,调用apply(&p->first, cl)。如果apply修改list,则
为未检查的运行时错误。
T List_pop(T list, void **x)
将list ->first赋值给*x(如果x不是NULL),释放list,并返回list ->rest。如果
list=NULL,List_pop返回NULL,并不改变*x。
T List_push(T list, void *x) Mem_Failed
将一个包含x的新元素添加到list的前端,并返回新链表。
T List_reverse(T list)
将list中的各个元素逆向,并返回反转后的链表。
void * *List_toArray(T list, void *end) Mem_Failed
创建一个N+1个元素的数组,包含list中的N个元素,并返回指向第一个元素的指针。数
组中第N个元素设置为end。
向Mem接口中任何函数或宏传递的nbytes≤0,则为已检查的运行时错误。
ALLOC(nbytes) Mem_Failed
分配nbytes个字节并返回指向第一个字节的指针。分配的nbytes个字节是未初始化的。
参见Mem_alloc。
CALLOC(count, nbytes) Mem_Failed
为一个count个元素的数组分配空间,每个数组元素占nbytes字节,并返回一个指针指
向第一个元素。count≤0则造成已检查的运行时错误。各个元素都被清零。参见 Mem_calloc。
FREE(ptr)
如果ptr不是NULL,释放ptr,则将ptr清零。作为表达式,ptr会被求值多次。参见Mem_free。
void *Mem_alloc(long nbytes, Mem_Failed
const char *file, int line)
分配nbytes个字节并返回指向第一个字节的指针。分配的nbytes个字节是未初始化的。
如果Mem_alloc引发Mem_Failed异常,则将file和line作为出错的源代码位置报告。
void *Mem_calloc(long count, long nbytes, Mem_Failed
const char *file, int line)
为一个count个元素的数组分配空间,每个数组元素占nbytes字节,并返回一个指针指
向第一个元素。count≤0则造成已检查的运行时错误。各个元素都被清零,这不见得会将
指针初始化为NULL或将浮点值初始化为0.0。如果Mem_calloc引发Mem_Failed异常,
则将file和line作为出错的源代码位置报告。
void Mem_free(void *ptr, const char *file, int line)
如果ptr不是NULL,则释放ptr。如果ptr指针不是此前调用Mem分配函数返回的,则
造成未检查的运行时错误。接口的实现可使用file和line来报告内存使用错误。
void *Mem_resize(void *ptr, long nbytes, Mem_Failed
const char *file, int line)
变更ptr指向的内存块的长度,使之包含nbytes字节,并返回指向新内存块第一个字节
的指针。如果nbytes大于原来的内存块的长度,新增的字节将是未初始化的。如果nbytes
小于原来的内存块的长度,则原来的内存块中仅有前nbytes个字节会出现在新内存块中。
如果Mem_resize引发Mem_Failed异常,则将file和line作为出错的源代码位置报
告。如果ptr=NULL,则为已检查的运行时错误,如果ptr指针不是此前调用Mem分配函
数返回的,则为未检查的运行时错误。
NEW(p) Mem_Failed
NEW0(p) Mem_Failed
分配一个足够大、可容纳*p的内存块,将p设置为该内存块的地址,并返回该地址。NEW0
将所分配内存块的各个字节清零,而NEW分配的内存块则不进行初始化,各个字节的内容
是未初始化的。两个宏都只对ptr求值一次。
RESIZE(ptr, nbytes) Mem_Failed
变更ptr指向的内存块的长度,使之包含nbytes字节,将ptr重新指向调整大小后的内
存块,并返回该内存块的地址。作为表达式,ptr会被求值多次。参见Mem_resize。
T即为MP_T
typedef unsigned char *T
MP函数可以执行n-bit有符号和无符号算术,其中n初始化为32,可以通过MP_set修改。名称以u或ui结尾的函数,执行无符号算术,其他函数执行有符号算术。MP函数会在引发MP_Overflow或MP_DivideByZero异常之前计算其结果。向任何MP函数传递为NULL的T值都是已检查的运行时错误。向任何MP函数传递太小的T,都是未检查的运行时错误。
T MP_add(T z, T x, T y) MP_Overflow
T MP_addi(T z, T x, long y) MP_Overflow
T MP_addu(T z, T x, T y) MP_Overflow
T MP_addui(T z, T x, unsigned long y) MP_Overflow
将z设置为x + y并返回z。
T MP_and(T z, T x, T y)
T MP_andi(T z, T x, unsigned long y)
将z设置为x与y的按位与结果,并返回z。
T MP_ashift(T z, T x, int s)
将z设置为x右移s个比特位的结果,并返回z。空出的比特位用x的符号位填充。s<0,
则为已检查的运行时错误。
int MP_cmp(T x, T y)
int MP_cmpi(T x, long y)
int MP_cmpu(T x, T y)
int MP_cmpui(T x, unsigned long y)
对于x<y、x=y、x>y,分别返回<0、=0、>0的整数。
T MP_cvt(int m, T z, T x) MP_Overflow
T MP_cvtu(int m, T z, T x) MP_Overflow
将x缩窄或加宽为m-bit的有符号或无符号整数,并赋值给z,最终返回z。如果m<2,则为
已检查的运行时错误。
T MP_div(T z, T x, T y) MP_Overflow, MP_DivideByZero
T MP_divi(T z, T x, long y) MP_Overflow, MP_DivideByZero
T MP_divu(T z, T x, T y) MP_DivideByZero
T MP_divui(T z, T x, unsigned long y) MP_Overflow, MP_DivideByZero
将z设置为x/y,并返回z。处理有符号运算的函数向-∞舍入,参见Arith_div。
void MP_fmt(int code, va_list *app,
int put(int c, void *cl),void *cl,
unsigned char flags[], int width, int precision)
void MP_fmtu(int code, va_list *app,
int put(int c, void *cl), void *cl,
unsigned char flags[], int width, int precision)
以上是两个Fmt转换函数。二者均消耗一个T和一个基数b,并按类似printf的%d和%u
的风格,将其格式化。b<2或b>36,app或flags为NULL,均为已检查的运行时错误。
T MP_fromint(T z, long v) MP_Overflow
T MP_fromintu(T z, unsigned long u) MP_Overflow
这两个函数将z设置为v或u,并返回z。
T MP_fromstr(T z, const char *str, int base, char **end) MP_Overflow
将str解释为base基数下的一个整数,将z设置为该整数,并返回z。参见AP_fromstr。
T MP_lshift(T z, T x, int s)
将z设置为x左移s个比特位的结果,并返回z。空出的比特位用0填充。s<0,则为已检查的运行时错误。
T MP_mod(T z, T x, T y) MP_Overflow, MP_DivideByZero
将z设置为x mod y并返回z。向-∞舍入,参见Arith_mod。
long MP_modi(T x, long y) MP_Overflow, MP_DivideByZero
返回x mod y。向-∞舍入,参见Arith_mod。
T MP_modu(T z, T x, T y) MP_DivideByZero
将z设置为x mod y并返回z。
unsigned long MP_modui(T x, MP_Overflow, MP_DivideByZero
unsigned long y)
返回x mod y。
T MP_mul(T z, T x, T y) MP_Overflow
将z设置为x * y并返回z。
T MP_mul2(T z, T x, T y) MP_Overflow
T MP_mul2u(T z, T x, T y) MP_Overflow
将z设置为x * y的"双倍长结果"并返回z,z有2n个比特位。
T MP_muli(T z, T x, long y) MP_Overflow
T MP_mulu(T z, T x, T y) MP_Overflow
T MP_mului(T z, T x, unsigned long y) MP_Overflow
将z设置为x*y, 并返回z。
T MP_neg(T z, T x) MP_Overflow
将z设置为-x并返回z。
T MP_new(unsigned long u) Mem_Failed, MP_Overflow
创建并返回一个T实例,其值初始化为u。
T MP_not(T z, T x)
将z设置为~x并返回z。
T MP_or(T z, T x, T y)
T MP_ori(T z, T x, unsigned long y)
将z设置为x与y的按位或结果,并返回z。
T MP_rshift(T z, T x, int s)
将z设置为x右移s个比特位的结果,并返回z。空出的比特位用0填充。s<0,则为已检查的运行时错误。
int MP_set(int n) Mem_Failed
将MP重置为执行n-bit算术。n<2,则为已检查的运行时错误。
T MP_sub(T z, T x, T y) MP_Overflow
T MP_subi(T z, T x, long y) MP_Overflow
T MP_subu(T z, T x, T y) MP_Overflow
T MP_subui(T z, T x, unsigned long y) MP_Overflow
将z设置为x-y, 并返回z。
long int MP_toint(T x) MP_Overflow
unsigned long MP_tointu(T x) MP_Overflow
将x转换为long int或unsigned long返回。
char *MP_tostr(char *str, int size, int base, T x) Mem_Failed
用x在基数base下的字符串表示(0字符结尾)填充str[0..size - 1],并返回str。
如果str=NULL,MP_tostr,忽略size并为该字符串分配空间。参见AP_tostr。
T MP_xor(T z, T x, T y)
T MP_xori(T z, T x, unsigned long y)
将z设置为x与y按位异或的结果,并返回z。
T是不透明的Ring_T
环索引从0到N-1,其中N是环的长度。空环没有元素。可以在环中任何位置添加或删除指针,环会自动扩展。旋转环将改变其起点。向任何Ring函数传递为NULL的T值,均为已检查的运行时错误。
void *Ring_add(T ring, int pos, void *x) Mem_Failed
在环中位置
pos插入x并返回x。位置标识了元素之间的点,参见Str接口。pos<-N或
pos>N+1,则为已检查的运行时错误,其中N是ring的长度。
void *Ring_addhi(T ring, void *x) Mem_Failed
void *Ring_addlo(T ring, void *x) Mem_Failed
将x添加到ring的高端(索引N-1)或低端(索引0)并返回x。
void Ring_free(T *ring)
释放*ring并将其清零。如果ring或*ring为NULL,则造成已检查的运行时错误。
int Ring_length(T ring)
返回ring中元素的数目。
void *Ring_get(T ring, int i)
返回ring中第i个元素。i<0或i≥N,则为已检查的运行时错误,其中N是ring的长度。
T Ring_new(void) Mem_Failed
创建并返回一个空环。
void *Ring_put(T ring, int i, void *x) Mem_Failed
将ring中第i个元素改为x,并返回原值。已检查的运行时错误,请参见Ring_get。
void *Ring_remhi(T ring)
void *Ring_remlo(T ring)
删除并返回ring高端(索引N-1)或低端(索引0)处的元素。如果ring为空环,则为已检查的运行时错误。
void *Ring_remove(T ring, int i)
删除并返回ring中的元素i。i<0或i≥N,则为已检查的运行时错误,其中N是ring的长度。
T Ring_ring(void *x, ...) Mem_Failed
创建并返回一个环,其元素来自参数的可变部分,直至遇到第一个NULL指针为止。
void Ring_rotate(T ring, int n)
将ring的起点向左(n<0)或向右(n≥0)旋转n个元素。如果|n|>N,则为已检查的运行时错误,其中N是ring的长度。
T是不透明的Sem_T
typedef struct T { int count; void *queue; } T;
直接读写T实例中的字段,或向任何Sem函数传递未初始化的T实例,均为未检查的运行时错误。向任何Sem函数传递的T值为NULL,或在调用Thread_init之前调用任何Sem函数,均为已检查的运行时错误。
LOCK语句的语法如下,S和m分别表示语句和一个T实例。
LOCK(m ) S END_LOCK
m被锁定,接下来执行语句S,而后m被解锁。LOCK可能引发Thread_Alerted异常。
void Sem_init(T *s, int count)
将s->count设置为count。对同一T实例多次调用Sem_init,是未检查的运行时错误。
Sem_T *Sem_new(int count) Mem_Failed
创建并返回一个T实例,其count字段初始化为count。
void Sem_wait(T *s) Thread_Alerted
调用线程进入等待状态,直至s->count>0,接下来将s->count减1。
void Sem_signal(T *s) Thread_Alerted
将s->count加 1。
T是不透明的Seq_T
序列索引从0到N-1,其中N是序列的长度。空序列没有元素。可以在序列低端(索引0)或高端(索引N-1)处添加或删除指针,序列会自动扩展。向任何Seq函数传递的T值为NULL,均为已检查的运行时错误。
void *Seq_addhi(T seq, void *x) Mem_Failed
void *Seq_addlo(T seq, void *x) Mem_Failed
将x添加到seq的高端或低端并返回x。
void Seq_free(T *seq)
释放*seq并将其清零。如果seq或*seq是NULL,则为已检查的运行时错误。
int Seq_length(T seq)
返回seq中元素的数目。
void *Seq_get(T seq, int i)
返回seq中的第i个元素。i<0或i≥N,则为已检查的运行时错误,其中N是seq的长度。
T Seq_new(int hint) Mem_Failed
创建并返回一个空序列。hint是对该序列最大长度的估计。如果hint<0,则为已检查的运行时错误。
void *Seq_put(T seq, int i, void *x)
将seq中第i个元素改为x,并返回原值。已检查的运行时错误,请参见Seq_get。
void *Seq_remhi(T seq)
void *Seq_remlo(T seq)
删除并返回seq高端或低端的元素。如果seq为空,则为已检查的运行时错误。
T Seq_seq(void *x, ...) Mem_Failed
创建并返回一个序列,其元素来自参数的可变部分,直至遇到第一个NULL指针为止。
T是不透明的Set_T
向任何Set函数传递的T值或成员值为NULL,均为已检查的运行时错误(Set_diff、Set_inter、Set_minus和Set_union除外,这些函数将T的NULL值解释为空集)。
T Set_diff(T s, T t) Mem_Failed
返回s和t的对称差s / t:s和t的对称差是一个集合,其成员只出现在s中或t中。
如果s和t均为NULL,或二者均非NULL但cmp和hash函数不同,则造成已检查的运行时错误。
void Set_free(T *set)
释放*set, 并将其清零。set或*set是NULL,则造成已检查的运行时错误。
T Set_inter(T s, T t) Mem_Failed
返回s和t的交集s∩t:其成员同时出现在s和t中。已检查的运行时错误,请参见Set_diff。
int Set_length(T set)
返回set中元素的数目。
void Set_map(T set, void apply(const void *member, void *cl),void *cl)
对set的每个成员member调用apply(member, cl)。如果apply修改set,则造成已检查的运行时错误。
int Set_member(T set, const void *member)
如果member为set的成员,则返回1,否则返回0。
T Set_minus(T s, T t) Mem_Failed
返回s和t的差集s - t:其成员只出现在s中,不出现在t中。已检查的运行时错误,请参见Set_diff。
T Set_new(int hint, Mem_Failed
int cmp(const void *x, const void *y),
unsigned hash(const void *x))
创建、初始化并返回一个空集。hint、cmp和hash的解释,请参见Table_new。
void Set_put(T set, const void *member) Mem_Failed
如有必要,将member添加到set中。
void *Set_remove(T set, const void *member)
如果member为set的成员,则将member从set中删除,并返回删除的成员,否则,
Set_remove返回NULL。
void **Set_toArray(T set, void *end) Mem_Failed
创建一个N+1个元素的数组,将set的N个成员以未指定的顺序复制到数组中,并返回指向
数组第一个元素的指针。数组的元素N为end。
T Set_union(T s, T t) Mem_Failed
返回s和t的并集s∪t:其成员出现在s或t中。已检查的运行时错误,请参见Set_diff。
T是不透明的Stack_T
向任何Stack函数传递的T值为NULL,则为已检查的运行时错误。
int Stack_empty(T stk)
如果stk为空,则返回1,否则返回0。
void Stack_free(T *stk)
释放*stk并将其清零。如果stk或*stk为NULL,则为已检查的运行时错误。
T Stack_new(void) Mem_Failed
返回一个新的空栈T。
void *Stack_pop(T stk)
弹出并返回stk的栈顶元素。如果stk为空,则为已检查的运行时错误。
void Stack_push(T stk, void *x) Mem_Failed
将x推入stk栈中。
Str函数操作0结尾字符串。位置标识了字符之间的点,举例来说,"STRING"字符串中的位置如下:
任何两个位置都可以按任意顺序给出。创建字符串的Str函数会为其结果分配空间。在下文的描述中,s[i:j]表示s中位置i和j之间的子串。向任何Str函数传递的位置不存在或字符指针为NULL,均为已检查的运行时错误(Str_catv和Str_map函数指明的情形除外)。
int Str_any(const char *s, int i, const char *set)
如果s[i:i+1]字符出现在set中,则返回s中该字符之后的正数位置,否则返回0。如果
set=NULL,则为已检查的运行时错误。
char *Str_cat(const char *s1, int i1, int j1, Mem_Failed
const char *s2, int i2, int j2)
返回s1[i1: j1]连接s2 [i2: j2]的结果。
char *Str_catv(const char *s, ...) Mem_Failed
返回一个由参数可变部分的各个三元组组成的字符串,直至遇到一个NULL指针。每个三元组都指定了一个子串s[i:j]。
int Str_chr(const char *s, int i, int j, int c)
搜索s[i:j]中最左侧的字符c,并返回在s中该字符之前的位置,如果没有找到字符c,则返回0。
int Str_cmp(const char *s1, int i1, int j1,
const char *s2, int i2, int j2)
如果s1[i1:j1] <s2[i2:j2]、s1[i1: j1]=s2[i2:j2]或s1[i1:j1]>s2[i2:j2],
分别返回<0、=0、>0的整数。
char *Str_dup(const char *s, int i, int j, int n) Mem_Failed
返回s[i:j]的n个副本连接形成的结果字符串。如果n<0,则为已检查的运行时错误。
int Str_find(const char *s, int i, int j, const char *str)
搜索s[i:j]中最左侧的子串str,并返回在s中该子串之前的位置,如果没有找到子串str,
则返回0。如果str=NULL,则为已检查的运行时错误。
void Str_fmt(int code, va_list *app,
int put(int c, void *cl), void *cl,
unsigned char flags[ ], int width, int precision)
这是一个Fmt转换函数。它消耗三个参数:一个字符串和两个位置,并按printf的%s限
定符的风格,将参数指定的子串格式化。app或flags是NULL,则为已检查的运行时错误。
int Str_len(const char *s, int i, int j)
返回子串s[i:j]的长度。
int Str_many(const char *s, int i, int j, const char *set)
该函数从s[i:j]开头处查找由set中一个或多个字符构成的连续非空序列,并返回s中该
序列之后的正数位置;如果s[i:j]并非起始于set中某个字符,则返回0。如果set=NULL,
则为已检查的运行时错误。
char *Str_map(const char *s, int i, int j, Mem_Failed
const char *from, const char *to)
返回根据from和to映射s[i:j]中的字符所得到的字符串。对s[i:j]中的每个字符来说,
如果其出现在from中,则映射为to中的对应字符。不出现在from中的字符映射为本身。
如果from和to均为NULL,则使用此前设定的from和to值。如果s=NULL,则from
和to建立了一个默认映射。如果from和to中仅有二者之一为NULL,或strlen(from)
≠strlen(to),或s、from、to均为NULL,或第一次调用该函数时from和to均为NULL,
则造成已检查的运行时错误。
int Str_match(const char *s, int i, int j, const char *str)
如果s[i:j]以str开头,则返回s中str子串之后的位置,否则返回0。如果str=NULL,
则为已检查的运行时错误。
int Str_pos(const char *s, int i)
返回对应于的正数位置,从该值减去1,即可得到字符s[i:i+1]的索引值。
int Str_rchr(const char *s, int i, int j, int c)
是Str_chr的变体,只是从右侧开始搜索。
char *Str_reverse(const char *s, int i, int j) Mem_Failed
返回s[i:j]的一个副本,但其中的各个字符已经逆转为相反的方向。
int Str_rfind(const char *s, int i, int j, const char *str)
Str_find的变体,只是从右侧开始搜索。
int Str_rmany(const char *s, int i, int j, const char *set)
该函数从结尾处查找由set中一个或多个字符构成的连续非空序列,并返回s中该
序列之前的正数位置;如果s[i:j]并非结束于set中某个字符,则返回0。如果set=NULL,
则为已检查的运行时错误。
int Str_rmatch(const char *s, int i, int j,
const char *str)
如果s[i:j]结束于str,则返回s中子串str之前的正数位置,否则返回0。如果str=
NULL,则为已检查的运行时错误。
int Str_rupto(const char *s, int i, int j, const char *set)
Str_upto的变体,从右侧开始搜索。
char *Str_sub(const char *s, int i, int j) Mem_Failed
返回s[i:j]。
int Str_upto(const char *s, int i, int j, const char *set)
从s[i:j]左侧开始搜索set中任意字符,并返回s中该字符之前的位置,如果s[i:j]不
包含set中任意字符,则返回0。如果set=NULL,则为已检查的运行时错误。
T是不透明的Table_T
向任何Table函数传递的T值或key为NULL,均为已检查的运行时错误。
void Table_free(T *table)
释放*table并将其清零。如果table或*table是NULL,则是已检查的运行时错误。
void *Table_get(T table, const void *key)
返回table中与key关联的值,如果table并不包含key,则返回NULL。
int Table_length(T table)
返回table中键-值对的数目。
void Table_map(T table,
void apply(const void *key, void **value, void *cl),
void *cl)
按未指定的的顺序,对table中每个键-值调用apply(key, &value, cl)。如果apply
修改table,则造成已检查的运行时错误。
T Table_new(int hint, Mem_Failed
int cmp(const void *x, const void *y),
unsigned hash(const void *key))
创建、初始化并返回一个新的空表,可以包含任意数目的键-值对。hint是对表可能包含的
键-值对数目的估计。如果hint<0,则为已检查的运行时错误。cmp和hash是用于比较和
散列键的函数。对于键x和y,如果x<y、x=y、x>y,那么cmp(x, y)必须返回<0、=0、>0
的一个int。如果cmp(x, y)返回零,hash(x)必须等于hash(y)。如果cmp=NULL或
hash=NULL,Table_new将使用Atom_T键的对应函数。
void *Table_put(T table, Mem_Failed
const void *key, void *value)
将table中与key关联的值改为value,并返回此前与key关联的值,如果table并不
包含key,则向table添加key和value,并返回NULL。
void *Table_remove(T table, const void *key)
从table中删除键-值对并返回被删除的值。如果table并不包含key,则Table_remove
没有效果,返回NULL。
void **Table_toArray(T table, void *end) Mem_Failed
创建一个2N+1个元素的数组,将table中的N个键-值对按未指定的顺序复制到数组中,
并返回指向数组第一个元素的指针。键出现在偶数编号的数组元素中,而对应的值出现在奇
数编号的数组元素中。元素2N为end。
T即为Text_T
typedef struct T { int len; const char *str; } T;
typedef struct Text_save_T *Text_save_T;
T是一个描述符,客户程序可以读取描述符的字段,但向描述符的字段写入数据则是未检查的运行时错误。Text函数可以按值 接受并返回描述符,向任何Text函数传递的描述符,如果其字段str=NULL或len<0,则为已检查的运行时错误。
Text为其提供的不可变的字符串管理内存,向串空间写入数据,或通过外部手段释放其中的内存,均为未检查的运行时错误。串空间中的字符串可以包含0字符,因此其中的字符串不是以0字符结尾的。
一些Text函数可以接受位置作为参数,位置标识了字符之间的点,参见Str接口。在下文的描述中,s[i:j]表示s中位置i和j之间的子串。
const T Text_cset = { 256, " \000\001...\376\377" }
const T Text_ascii = { 128, " \000\001...\176\177" }
const T Text_ucase = { 26, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" }
const T Text_lease = { 26, "abedefhijklmnopqrtuvwxyz" }
const T Text_digits = { 10, "0123456789" }
const T Text_null = { 0," " }
上述是一些已经初始化的静态描述符。
int Text_any(T s, int i, T set)
如果s[i:i+1]字符出现在set中,则返回s中该字符之后的正数位置,否则返回0。
T Text_box(const char *str, int len)
为客户程序分配的长度len的字符串str,建立并返回一个描述符。如果str=NULL或
len<0,则为已检查的运行时错误。
T Text_cat(T s1, T s2) Mem_Failed
返回s1连接s2得到的字符串。
int Text_chr(T s, int i, int j, int c)
参见Str_chr。
int Text_cmp(T s1, T s2)
如果s1<s2、s1 = s2、s1>s2,分别返回<0、=0、>0的int。
T Text_dup(T s, int n) Mem_Failed
返回s的n个副本连接形成的字符串。如果n<0,则为已检查的运行时错误。
int Text_find(T s, int i, int j, T str)
参见Str_find。
void Text_fmt(int code, va_list *app,
int put(int c, void *cl), void *cl,
unsigned char flags[], int width, int precision)
这是一个Fmt转换函数。它消耗一个指向描述符的指针,并按printf的%s限定符的风格,
格式化该字符串。描述符指针、app或flags是NULL,则造成已检查的运行时错误。
char *Text_get(char *str, int size, T s)
将s.str[0..str.len - 1]复制到str[0.. size - 1],追加一个0字符,并返回str。
如果str=NULL,Text_get将为其分配空间。如果str≠null且size<s.len+1,则为
已检查的运行时错误。
int Text_many(T s, int i, int j, T set)
参见Str_many。
T Text_map(T s, const T * from, const T *to) Mem_Failed
返回根据from和to映射s中的字符所得到的字符串,参见Str_map。如果from和to
均为NULL,则使用此前设定的from和to值。如果只有from和to二者之一为NULL,或
from->len≠ to->len,则为已检查的运行时错误。
int Text_match(T s, int i, int j, T str)
参见Str_match。
int Text_pos(T s, int i)
参见Str_pos。
T Text_put(const char *str) Mem_Failed
将0结尾字符串str复制到串空间中,并返回其描述符。如果str=NULL,则为已检查的运行时错误。
int Text_rchr(T s, int i, int j, int c)
参见Str_rchr。
void Text_restore(Text_save_T *save)
释放save创建以来分配的那部分串空间。如果save=NULL,则为已检查的运行时错误。
如果在调用Text_restore之后,使用表示高于save位置的其他Text_save_T值,则为
未检查的运行时错误。
T Text—reverse(T s) Mem_Failed
返回s的一个副本,其中的各个字符已经反向。
int Text_rfind(T s, int i, int j, T str)
参见Str_rfind。
int Text_rmany(T s, int i, int j, T set)
参见Str_rmany。
int Text_rmatch(T s, int i, int j, T str)
参见Str_rmatch。
int Text_rupto(T s, int i, int j, T set)
参见Str_rupto。
Text_save_T Text_save(void) Mem_Failed
返回一个不透明指针,其编码了当前串空间顶部的位置。
T Text_sub(T s, int i, int j)
返回s[i:j]。
int Text_upto(T s, int i, int j, T set)
参见Str_upto。
T是不透明的Thread_T
在调用Thread_init之前调用任何Thread函数,均为已检查的运行时错误。
void Thread_alert(T t)
设置t的警报-待决标志,并使t变为可运行状态。下一次t运行时,或调用一个导致可能
导致阻塞的Thread、Sem或Chan原语时,线程将清除其警报-待决标志,并引发
Thread_Alerted异常。如果t=NULL,或t引用了一个不存在的线程,则为已检查的运
行时错误。
void Thread_exit(int code)
结束调用线程,并将code传递给任何等待调用线程结束的线程。当最后一个线程调用
Thread_exit时,程序将通过调用exit(code)结束。
int Thread_init(int preempt, ...)
为非抢占调度(preempt=0)或抢占调度(preempt=1)初始化Thread,并返回preempt
或0(如果preempt=1但不支持抢占调度)。Thread_init可能接受额外的由具体实现
定义的参数,可变参数列表必须结束于一个NULL指针。调用Thread_init多次,则造成
已检查的运行时错误。
int Thread_join(T t) Thread_Alerted
挂起调用线程,直至线程t结束。在t结束时,Thread_join返回t的退出代码。如果t
=NULL,调用线程将等待所有其他线程结束,然后返回0。如果t指定的线程即为调用线程
自身,或有多个线程向该函数传递了NULL参数,则为已检查的运行时错误。
T Thread_new(int apply(void *), Thread_Failed
void *args, int nbytes, ...)
创建、初始化并启动一个新线程,并返回其句柄。如果nbytes=0,新线程将执行
Thread_exit(apply(args)),否则,它执行Thread_exit(apply(p)),其中p指向起
始于args、长度为nbytes的内存块的一个副本
。新线程启动时,自身的异常栈为空。
Thread_new可能接受额外的由具体实现定义参数,可变参数列表必须结束于一个NULL指
针。如果apply=NULL,或args=NULL且nbytes<0,则为已检查的运行时错误。
void Thread_pause(void)
放弃处理器给另一个线程,也可能是调用线程自身。
T Thread_self(void)
返回调用线程的句柄。
T即为XP_T
typedef unsigned char *T;
基数28 下的一个扩展精度无符号整数,可以表示为一个数组,包括n个数位,最低有效数位在先。大多数XP函数将n作为一个参数,与源和目标T实例一同传递,如果n<1或n不等于对应T实例的长度,则为未检查的运行时错误。向任何XP函数传递的T值为NULL或太小,均为未检查的运行时错误。
int XP_add(int n, T z, T x, T y, int carry)
将z[0..n - 1]设置为x+y+carry,并返回z[n - 1]数位上的进位输出。carry必须为0或1。
int XP_cmp(int n, T x, T y)
对于x<y、x=y、x>y,分别返回<0、=0、>0的整数。
int XP_diff(int n, T z, T x, int y)
将z[0..n - 1]设置为x - y,其中y只有单个数位,并返回z[n - 1]数位上的借位。
如果y>28
,则为未检查的运行时错误。
int XP_div(int n, T q, T x, int m, T y, T r, T tmp)
将q[0..n - 1]设置为x[0..n - 1] /y[0..m - 1],将r[0..m - 1]设置为x [0..n
-1] mod y[0..m - 1],如果y≠0,则返回1。如果y=0,XP_div返回0,且不会修改
q和r。tmp必须能够容纳至少n+m+2个数位。q或r与x和y中之一相同、q和r是同
一XP_T实例、tmp能够容纳的数位太少,都是未检查的运行时错误。
unsigned long XP_fromint(int n, T z, unsigned long u)
将z[0..n - 1]设置为u mod 28n
并返回u/28n
。
int XP_fromstr(int n, T z, const char *str,
int base, char **end)
将str解释为base基数下的一个无符号整数,使用z[0..n - 1]作为转换过程中的初始
值,并返回转换步骤中第一个非零的进位输出。如果end≠null, 将*end设置为指向str
中导致扫描结束的字符或产生第一个非零进位的字符。参见AP_fromstr。
int XP_length(int n, T x)
返回x的长度,即,它返回x[0..n - 1]中最高非零数位的索引加1。
void XP_lshift(int n, T z, int m, T x, int s, int fill)
将z[0..n- 1]设置为x[0..m- 1]左移s个比特位的结果,空出的比特位用fill填充,
fill必须为0或1。如果s<0,则为未检查的运行时错误。
int XP_mul(T z, int n, T x, int m, T y)
将x[0..n - 1] *y[0..m -1]的结果加到z[0..n+m - 1],并返回z[n+m - 1]数位
的进位输出。如果z=0,XP_mul计算了乘积x * y。如果z与x或y中之一为同一T实
例,则为未检查的运行时错误。
int XP_neg(int n, T z, T x, int carry)
将z[0..n - 1]设置为~x+carry,其中carry为0或1,并返回z[n - 1]数位的进位输出。
int XP_product(int n, T z, T x, int y)
将z[0..n - 1]设置为x * y, 其中y只有单个数位,并返回z[n - 1]数位上的进位输
出。如果y≥28
,则为未检查的运行时错误。
int XP_quotient(int n, T z, T x, int y)
将z[0..n - 1]设置为x/y,其中y是单个数位,并返回x mod y。如果y=0或y≥28
,
则为未检查的运行时错误。
void XP_rshift(int n, T z, int m, T x, int s, int fill)
右移,参见XP_lshift。如果n>m,空出的比特位用fill填充。
int XP_sub(int n, T z, T x, T y, int borrow)
将z[0..n - 1]设置为x - y - borrow,并返回z[n - 1]数位上的借位。borrow必须为0或1。
int XP_sum(int n, T z, T x, int y)
将z[0..n - 1]设置为x+y,其中y只有单个数位,并返回z[n - 1]数位上的进位输
出。如果y>28
,则为未检查的运行时错误。
unsigned long XP_toint(int n, T x)
返回x mod (ULONG_MAX+1)。
char *XP_tostr(char *str, int size, int base, int n, T x)
用x在base基数下的字符表示填充str[0..size- 1],将x设置为0,并返回str。如
果str=NULL,或size太小,或base<2或base>36,均为已检查的运行时错误。
[1] 译文并未使用上述缩写。——译者注
[2] 即字符数目,不包含结尾0字符。——译者注