(二)ghostscript源码分析之interp()函数之IREF_NEXT宏分析
来源:互联网 发布:json字符串加密解密 编辑:程序博客网 时间:2024/05/19 20:42
interp()函数用了大量的宏。IREF_NEXT只是其中一个宏,但是出现的频率很高。
但是透彻的理解这个宏将为理解interp()函数提供便利。
它的定义形式如下:
这句看似简单的代码实际上不那么容易理解,而后面一些列的宏要么与此类似,要么间接的调用它。
而ref的定义是下面这个样子:
要使(const ref*)rp +1 变得有有意义,关键在于解析器是怎么处理的。
我们以"{}"为例,来解释它。
识别过程,是在scan_token()函数中办到的,但是具体是怎样办到的?
看下面截取的部分代码片段:
现在到了一个很关键的函数——ref_stack_store(const ref_stack_t *pstack, ref *parray, uint count,
uint skip, int age, bool check, gs_dual_memory_t *idmemory,
client_name_t cname);
这个函数能够说明为什么IREF_NEXT能以那样的形式出现是正确的。
这个函数的源代码如下:
int
ref_stack_store(const ref_stack_t *pstack, ref *parray, uint count,
uint skip, int age, bool check, gs_dual_memory_t *idmemory,
client_name_t cname)
{
uint left, pass;
ref *to;
ref_stack_enum_t rsenum;
if (count > ref_stack_count(pstack) || count > r_size(parray))
return_error(e_rangecheck);
if (check) {
int code = ref_stack_store_check(pstack, parray, count, skip);
if (code < 0)
return code;
}
to = parray->value.refs + count;
left = count, pass = skip;
ref_stack_enum_begin(&rsenum, pstack);
do {
ref *from = rsenum.ptr;
uint size = rsenum.size;
if (size <= pass)
pass -= size;
else {
if (pass != 0)
size -= pass, pass = 0;
from += size;
if (size > left)
size = left;
left -= size;
switch (age) {
case -1: /* not an array */
while (size--) {
from--, to--;
ref_assign(to, from);
}
break;
case 0: /* old array */
while (size--) {
from--, to--;
ref_assign_old(parray, to, from, cname);
}
break;
case 1: /* new array */
while (size--) {
from--, to--;
ref_assign_new(to, from);
}
break;
}
if (left == 0)
break;
}
} while (ref_stack_enum_next(&rsenum));
r_set_size(parray, count);
return 0;
}
由于传入的age参数是1,所以进入case 1:这个阶段。
加粗的黑体字代码表明了宏所运用的方式是正确的。
这点可以通过运行调试来斧正。
- (二)ghostscript源码分析之interp()函数之IREF_NEXT宏分析
- (三)ghostscript源码分析之interp函数
- (一)ghostscript源码分析之interp()函数的第二个参数
- ghostscript源码分析之 scan_token()函数 (词法分析器iscan.c)
- ghostscript 源码分析之iref.h
- Memcached源码分析之状态机(二)
- HDFS源码分析之UnderReplicatedBlocks(二)
- PackageManagerService源码分析之第一阶段(二)
- 【Zookeeper】源码分析之服务器(二)
- 【Zookeeper】源码分析之服务器(二)
- kubenetes源码分析之DNS(二)
- kubernetes 源码分析之kubeadm(二)
- kubernetes 源码分析之ingress(二)
- EventBus(二)之源码分析
- JDK源码分析之ArrayList(二)
- Memcached源码分析之二
- AsyncTask源码分析之二
- LoaderManager源码分析之二
- CEGUI 0.7.2 学习笔记----配置SDK运行环境
- 6级作文模板:
- 有些迷茫了
- 排序文件的工具-sort命令
- RHELAS4安装yum并建立本地源
- (二)ghostscript源码分析之interp()函数之IREF_NEXT宏分析
- Linux+Apache2+openssl实现https验证
- oracle数据库--学习
- C# 发邮件
- CDSN
- 把PPT转WORD形式的方法及常用文件转换
- MsgWaitForMultipleObjects
- asp.net解决中文乱码问题
- [BCB]E2089 Identifier 'ReadPragram' cannot have a type qualifier