当前位置:操作系统 > 安卓/Android >>

Android培训班(16)

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, 易做图 sure it is terminated with */

#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] = ;

#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  }

补充:移动开发 , Android ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,