parse_config_file函数是分析*.rc配置文件,并且把里面的参数组成链表的方式。下面来仔细地分析代码,如下:

#001 int parse_config_file(const char *fn)

#002 {

输入来的参数是文件名称的路径。

#003 char *data;

#004 data = read_file(fn, 0);

#005 if (!data) return -1;

这段代码是从文件里读取数据,并保存数据缓冲区的指针在data里。

#006

#007 parse_config(fn, data);

这行代码是分析data数据里,然后把里面的参数组成链表的方式。

#008 DUMP();

这行代码是用来调试时输出配置文件里的内容。

#009 return 0;

#010 }

接着下来分析函数read_file的代码,如下:

#001 /* reads a file, making sure it is terminated with /n /0 */

#002 void *read_file(const char *fn, unsigned *_sz)

#003 {

#004 char *data;

#005 int sz;

#006 int fd;

#007

#008 data = 0;

#009 fd = open(fn, O_RDONLY);

#010 if(fd < 0) return 0;

这段代码是打开文件路径为fn的文件,使用只读的方式打开。

#011

#012 sz = lseek(fd, 0, SEEK_END);

#013 if(sz < 0) goto oops;

这段代码是移动文件指针到文件末尾,然后计算出文件的长度。

#014

#015 if(lseek(fd, 0, SEEK_SET) != 0) goto oops;

这段代码是移动到文件头开始位置。

#016

#017 data = (char*) malloc(sz + 2);

#018 if(data == 0) goto oops;

这段代码是分配文件所需内存大小。

#019

#020 if(read(fd, data, sz) != sz) goto oops;

#021 close(fd);

#022 data[sz] = '/n';

#023 data[sz+1] = 0;

这段代码是读取文件数据到缓冲区,并设置缓冲区最后的结束字符为换行符和0字符。

#024 if(_sz) *_sz = sz;

#025 return data;

这段代码是返回文件的长度和文件缓冲区的指针。

#026

#027 oops:

#028 close(fd);

#029 if(data != 0) free(data);

#030 return 0;

#031 }

这段代码是读取文件出错,删除缓冲区。

再接着来分析函数parse_config,主要实现从缓冲区里分析配置数据,生成链表。它的代码如下:

#001 static void parse_config(const char *fn, char *s)

#002 {

#003 struct parse_state state;

#004 char *args[SVC_MAXARGS];

#005 int nargs;

#006

#007 nargs = 0;

#008 state.filename = fn;

#009 state.line = 1;

#010 state.ptr = s;

#011 state.nexttoken = 0;

#012 state.parse_line = parse_line_no_op;

这段代码是设置分析开始状态,其实state.filename指向文件名称;state.line是第一行;state.ptr是指向数据缓冲区;state.nexttoken是下一个词位置;state.parse_line是指向空操作行函数。

下面开始循环适别所有配置文件。

#013 for (;;) {

下面根据三种状态进行处理。

#014 switch (next_token(&state)) {

#015 case T_EOF:

已经到了文件结尾字符处理。

#016 state.parse_line(&state, 0, 0);

#017 return;

新一行配置文件处理。

#018 case T_NEWLINE:

#019 if (nargs) {

查找这一行里配置的关键字。

#020 int kw = lookup_keyword(args[0]);

#021 if (kw_is(kw, SECTION)) {

是关键字处理,分近这一行字符。

#022 state.parse_line(&state, 0, 0);

调用函数parse_new_section来分析这一节配置文件的意思,比如服务或者动作,或者参数等等。

#023 parse_new_section(&state, kw, nargs, args);

#024 } else {

保存一行的参数。

#025 state.parse_line(&state, nargs, args);

#026 }

#027 nargs = 0;

#028 }

#029 break;

保存命令配置的参数。

#030 case T_TEXT:

#031 if (nargs < SVC_MAXARGS) {

#032 args[nargs++] = state.text;

#033 }

#034 break;

#035 }

#036 }

#037 }

更多相关文章

  1. ClassLoader原理剖析
  2. Android应用获取外部盘符时,默认创建Android/data/包名/files目
  3. SVN问题之——org.apache.subversion.javahl.ClientException: A
  4. Android(安卓)proguard -applymapping 导致编译错误
  5. android JNI入门 之helloworld
  6. Android中使用字体文件
  7. Android(安卓)解析strings.xml国际化
  8. android 目录下三种尺寸的 drawable 文件夹
  9. Android安装常见错误解决办法

随机推荐

  1. Android中由文件名获取文件Id的两种方法
  2. android Paint 渐变色
  3. Android添加依赖出现This support librar
  4. Android(安卓)软键盘自动弹出与关闭实例
  5. Android(安卓)-- Autosizing TextView 自
  6. Android绘制(二):来用Path绘出想要的图形
  7. Android(安卓)调用 startActivityForResu
  8. Android在程序中捕捉HOME键的方法
  9. Activity与Service是否处于同一进程?
  10. Android——百度地图开发、添加覆盖物、