Apache APISIX 是一个很年轻的项目,2019 年 6 月份开源,7 月份加入到
CNCF 全景图,10 月份进入 Apache 孵化器,所以我会和大家分享一下 APISIX
是如何从 0 到 1,进入 Apache 孵化器的。
Apache APISIX 现在有 17 个 committer,分别来自 16
家不同的公司,是一个非常社区化的项目。每个 committer
有一票,决定版本的发布、选举新的 committer 和 PPMC
等比较重大的事情。
Apache Way
Apache Way 是大家都比较熟悉的概念:社区大于代码。烂代码可以改,Apache
的导师并不会指导你怎么写出更高水平的代码,他们更关心的是社区是否在健康的发展,只要有一个好的社区,烂代码一定会有更高水平的人进行重构,变成更好的代码。所以只要社区在,那这个项目就能够一直存活下去,这在
Apache 是最重要的。
邮件列表优先是另一个重要的点,没有在邮件列表中出现过的,就当做不存在。这在中国其实是一个非常大的挑战,大家在文化上和习惯上都不太喜欢用邮件:第一是时间不够及时,可能发一封邮件后隔
1-2 ...
wctype.h
wctype.h 提供 ctype.h 里面函数的宽字符版本。
宽字符类型判断函数
下面函数判断宽字符的类型。
iswalnum() 测试宽字符是否为字母数字
iswalpha() 测试宽字符是否为字母
iswblank() 测试这是否是一个宽空白字符
iswcntrl() 测试这是否是一个宽控制字符。
iswdigit() 测试这个宽字符是否是数字
iswgraph() 测试宽字符是否是可打印的非空格字符
iswlower() 测试宽字符是否为小写
iswprint() 测试宽字符是否可打印
iswpunct() 测试宽字符是否为标点符号
iswspace() 测试宽字符是否为空格
iswupper() 测试宽字符是否为大写
iswxdigit() 测试宽字符是否为十六进制数字
wctype(),iswctype()
iswctype()是上一节各种宽字符类型判断函数的通用版本,必须与wctype()配合使用。
1int iswctype(wint_t wc, wctype_t desc);
iswctype()接受两个参数,第一个参数是一个需要判断类型的宽字 ...
wchar.h
宽字符使用两个或四个字节表示一个字符,导致 C
语言常规的字符处理函数都会失效。wchar.h
定义了许多宽字符专用的处理函数。
类型别名和宏
wchar.h 定义了一个类型别名 wint_t,表示宽字符对应整数值。
wchar.h 还定义了一个宏 WEOF,表示文件结束字符 EOF 的宽字符版。
btowc(),wctob()
btowc()将单字节字符转换为宽字符,wctob()将宽字符转换为单字节字符。
12wint_t btowc(int c);int wctob(wint_t c);
btowc()返回一个宽字符。如果参数是
EOF,或转换失败,则返回 WEOF。
wctob()返回一个单字节字符。如果参数是
WEOF,或者参数宽字符无法对应单个的单字节字符,则返回 EOF。
下面是用法示例。
123456789wint_t wc = btowc('B'); // 输出宽字符 Bwprintf(L"Wide character: %lc\n", wc);unsigned char c = wctob(wc);// 输出 ...
time.h
time_t
time_t 是一个表示时间的类型别名,可以视为国际标准时
UTC。它可能是浮点数,也可能是整数,Unix 系统一般是整数。
许多系统上,time_t 表示自时间纪元(time epoch)以来的秒数。Unix
的时间纪元是国际标准时 UTC 的1970年1月1日的零分零秒。time_t
如果为负数,则表示时间纪元之前的时间。
time_t
一般是32位或64位整数类型的别名,具体类型取决于当前系统。如果是32位带符号整数,time_t
可以表示的时间到 2038年1月19日03:14:07 UTC
为止;如果是32位无符号整数,则表示到2106年。如果是64位带符号整数,可以表示-2930亿年到+2930亿年的时间范围。
struct tm
struct tm
是一个数据结构,用来保存时间的各个组成部分,比如小时、分钟、秒、日、月、年等。下面是它的结构。
1234567891011struct tm { int tm_sec; // 秒数 [0, 60] int tm_min; // 分钟 [0, 59] int tm_hour ...
string.h
string.h主要定义了字符串处理函数和内存操作函数。
字符串处理函数
以下字符串处理函数,详见《字符串》一章。
strcpy():复制字符串。
strncpy():复制字符串,有长度限制。
strcat():连接两个字符串。
strncat():连接两个字符串,有长度限制。
strcmp():比较两个字符串。
strncmp():比较两个字符串,有长度限制。
strlen():返回字符串的字节数。
strchr(),strrchr()
strchr()和strrchr()都用于在字符串中查找指定字符。不同之处是,strchr()从字符串开头开始查找,strrchr()从字符串结尾开始查找,函数名里面多出来的那个r表示
reverse(反向)。
12char* strchr(char* str, int c);char* strrchr(char *str, int c);
它们都接受两个参数,第一个参数是字符串指针,第二个参数是所要查找的字符。
一旦找到该字符,它们就会停止查找,并返回指向该字符的指针。如果没有找到,则返回
NULL。
下面是一个例子。
12 ...
stdio.h
stdio.h是 C 语言的标准 I/O
库,用于读取和写入文件,也用于控制台的输入和输出。
标准 I/O 函数
以下函数用于控制台的输入和输出。
printf():输出到控制台,详见《基本语法》一章。
scanf():从控制台读取输入,详见《I/O 函数》一章。
getchar():从控制台读取一个字符,详见《I/O 函数》一章。
putchar():向控制台写入一个字符,详见《I/O 函数》一章。
gets():从控制台读取整行输入(已废除),详见《I/O 函数》一章。
puts():向控制台写入一个字符串,详见《I/O 函数》一章。
文件操作函数
以下函数用于文件操作,详见《文件操作》一章。
fopen():打开文件。
fclose():关闭文件。
freopen():打开一个新文件,关联一个已经打开的文件指针。
fprintf():输出到文件。
fscanf():从文件读取数据。
getc():从文件读取一个字符。
fgetc():从文件读取一个字符。
putc():向文件写入一个字符。
fputc():向文件写入一个字符。
fgets():从文件读取整行 ...
stdlib.h
类型别名和宏
stdlib.h 定义了下面的类型别名。
size_t:sizeof 的返回类型。
wchar_t:宽字符类型。
stdlib.h 定义了下面的宏。
NULL:空指针。
EXIT_SUCCESS:函数运行成功时的退出状态。
EXIT_FAILURE:函数运行错误时的退出状态。
RAND_MAX:rand() 函数可以返回的最大值。
MB_CUR_MAX:当前语言环境中,多字节字符占用的最大字节数。
abs(),labs(),llabs()
这三个函数用于计算整数的绝对值。abs()用于 int
类型,labs()用于 long int 类型,llabs()用于
long long int 类型。
123int abs(int j);long int labs(long int j);long long int llabs(long long int j);
下面是用法示例。
12345// 输出 |-2| = 2printf("|-2| = %d\n", abs(-2));// 输出 |4| = 4printf(" ...
stdint.h
固定宽度的整数类型
stdint.h 定义了一些固定宽度的整数类型别名,主要有下面三类。
宽度完全确定的整数intN_t,比如int32_t。
宽度不小少于某个大小的整数int_leastN_t,比如int_least8_t。
宽度不小于某个大小、并且处理速度尽可能快的整数int_fastN_t,比如int_fast64_t。
上面所有类型都是有符号的,类型名前面可以加一个前缀u,表示无符号类型,比如uint16_t。
C 语言标准要求至少定义以下类型。
int8_t uint8_t
int16_t uint16_t
int32_t uint32_t
int64_t uint64_t
int_least8_t uint_least8_t
int_least16_t uint_least16_t
int_least32_t uint_least32_t
int_least64_t uint_least64_t
int_fast8_t uint_fast8_t
int_fast16_t uint_fast16_t
int_fast32_t uint_fast32_t ...
signal.h
简介
signal.h提供了信号(即异常情况)的处理工具。所谓“信号”(signal),可以理解成系统与程序之间的短消息,主要用来表示运行时错误,或者发生了异常事件。
头文件signal.h定义了一系列宏,表示不同的信号。
SIGABRT:异常中止(可能由于调用了 abort() 方法)。
SIGFPE:算术运算发生了错误(可能是除以 0 或者溢出)。
SIGILL:无效指令。
SIGINT:中断。
SIGSEGV:无效内存访问。
SIGTERM:终止请求。
上面每个宏的值都是一个正整数常量。
signal()
头文件signal.h还定义了一个signal()函数,用来指定某种信号的处理函数。
1signal(SIGINT, handler);
signal()接受两个参数,第一个参数是某种信号的宏,第二个参数是处理这个信号的函数指针handler。
信号处理函数handler接受一个 int
类型的参数,表示信号类型。它的原型如下。
1void (*func)(int);
handler函数体内部可以根据这个整数,判断到底接受到了哪种信号,因为多个信号可以 ...
math.h
math.h头文件提供了很多数学函数。
很多数学函数的返回值是 double 类型,但是同时提供 float 类型与 long
double
类型的版本,比如pow()函数就还有powf()和powl()版本。
123double pow(double x, double y); float powf(float x, float y);long double powl(long double x, long double y);
为了简洁,下面就略去了函数的f后缀(float
类型)和l后缀(long double)版本。
类型和宏
math.h 新定义了两个类型别名。
float_t:(当前系统)最有效执行 float 运算的类型,宽度至少与 float
一样。
double_t`:(当前系统)最有效执行 double 运算的类型,宽度至少与
double 一样。
它们的具体类型可以通过宏FLT_EVAL_METHOD来了解。
FLT_EVAL_METHOD 的值
float_t 对应的类型
double_t 对应的类型
0
float
d ...