Android培訓班(16) – Android移動開發技術文章_手機開發 Android移動開發教學課程

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
*/


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

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。