init.rc文本处理

next_token函数

init/tokenizer.cpp中next_token函数

    6 int next_token(struct parse_state *state)                                       
  7 {                                                                               
  8     char *x = state->ptr;                                                       
  9     char *s;                                                                    
 10                                                                                 
 11     if (state->nexttoken) {                                                     
 12         int t = state->nexttoken;                                               
 13         state->nexttoken = 0;                                                   
 14         return t;                                                               
 15     }                                                                           
 16                                                                                 
 17     for (;;) {                                                                  
 18         switch (*x) {                                                           
 19         case 0:                                                                 
 20             state->ptr = x;                                                     
 21             return T_EOF;                                                       
 22         case '\n':                                                              
 23             x++;                                                                
 24             state->ptr = x;                                                     
 25             return T_NEWLINE;                                                   
 26         case ' ':                                                               
 27         case '\t':                                                              
 28         case '\r':                                                              
 29             x++;                                                                
 30             continue;                                                           
 31         case '#':                                                               
 32             while (*x && (*x != '\n')) x++;                                     
 33             if (*x == '\n') {                                                   
 34                 state->ptr = x+1;                                               
 35                 return T_NEWLINE;                                               
 36             } else {                                                            
 37                 state->ptr = x;                                                 
 38                 return T_EOF;                                                   
 39             }                                                                   
 40         default:                                                                
 41             goto text;                                                          
 42         }                                                                       
 43     }        
        44                                                                                 
 45 textdone:                                                                       
 46     state->ptr = x;                                                             
 47     *s = 0;                                                                     
 48     return T_TEXT;                                                              
 49 text:                                                                           
 50     state->text = s = x;                                                        
 51 textresume:                                                                     
 52     for (;;) {                                                                  
 53         switch (*x) {                                                           
 54         case 0:                                                                 
 55             goto textdone;                                                      
 56         case ' ':                                                               
 57         case '\t':                                                              
 58         case '\r':                                                              
 59             x++;                                                                
 60             goto textdone;                                                      
 61         case '\n':                                                              
 62             state->nexttoken = T_NEWLINE;                                       
 63             x++;                                                                
 64             goto textdone;                                                      
 65         case '"':                                                               
 66             x++;                                                                
 67             for (;;) {                                                          
 68                 switch (*x) {                                                   
 69                 case 0:                                                         
 70                         /* unterminated quoted thing */                         
 71                     state->ptr = x;                                             
 72                     return T_EOF;                                               
 73                 case '"':                                                       
 74                     x++;                                                        
 75                     goto textresume;                                            
 76                 default:                                                        
 77                     *s++ = *x++;                                                
 78                 }                                                               
 79             }                                                                   
 80             break;                                                   
   81         case '\\':                                                              
 82             x++;                                                                
 83             switch (*x) {                                                       
 84             case 0:                                                             
 85                 goto textdone;                                                  
 86             case 'n':                                                           
 87                 *s++ = '\n';                                                    
 88                 break;                                                          
 89             case 'r':                                                           
 90                 *s++ = '\r';                                                    
 91                 break;                                                          
 92             case 't':                                                           
 93                 *s++ = '\t';                                                    
 94                 break;                                                          
 95             case '\\':                                                          
 96                 *s++ = '\\';                                                    
 97                 break;                                                          
 98             case '\r':                                                          
 99                     /* \ <cr> <lf> -> line continuation */                      
100                 if (x[1] != '\n') {                                             
101                     x++;                                                        
102                     continue;                                                   
103                 }                                                               
104             case '\n':                                                          
105                     /* \ <lf> -> line continuation */                           
106                 state->line++;                                                  
107                 x++;                                                            
108                     /* eat any extra whitespace */                              
109                 while((*x == ' ') || (*x == '\t')) x++;                         
110                 continue;                                                       
111             default:                                                            
112                     /* unknown escape -- just copy */                           
113                 *s++ = *x++;                                                    
114             }                                                                   
115             continue;                                                           
116         default:                                                                
117             *s++ = *x++;                                                        
118         }                                                                       
119     }                                                                                                                                                                                                   
120     return T_EOF;                                                               
121 }              

next_token函数整体逻辑:把文件中所有内容保存到字符串str。
在17行到43行处理逻辑,在字符串找到有用字符,则会进入text中,分割字符串,保存内容;如果遇到字符串中非有用字符是"#",继续在字符串str中轮询,直接遇到换行符(’\n’),或者轮询到结束符(EOF),分别在35行返回T_NEWLINE,或者在38行中返回return T_EOF;如果遇到空行"\n",则返回T_NEWLINE;如到’ ‘,’\t’,'r’等特殊字符继续向前轮询字符。
有个数据结构struct parse_state。

struct parse_state                                                                 
{                                                                                  
    char *ptr;      ------>指向下一个字符串的开始字符                                                               
    char *text;     ------>保存                                                           
    int   line;    --->处理的行数                                                                                                                                                                                 
    int nexttoken;  ---->处理过的分割符                                                               
};  

举个例子:处理如下配置文件。
配置文件内容如下,使用vim set list查看,$是转行符,^I是table,其他就是看见的空格。

 # Copyright (C) 2012 The Android Open Source Project$                              
#$                                                   
# IMPORTANT: Do not create world writable files or directories.$                   
# This is a common source of Android security bugs.$                               
#$                                                                                 
$                                                                                  
import /init.environ.rc$                                                           
import /init.usb.rc$                                                               
$                                                                                  
on early-init$                                                                     
    # Set init and its forked children's oom_adj.$                                 
    write /proc/1/oom_score_adj -1000$ 

在第1个注释语句,从31行处理,直接轮询到行末换行符(’\n’),并且从35行出。
第6行是空行,则22行进,遇到换行符(’\n’),从25行出。
有用信息:

on early-init$    

处理这行,第一个字符是’o’,运行到40行,goto text,state->text = s=x,
执行到 s++ = x++;则x=‘n’,再执行s++ = *x++,x=’ ';执行到58行,
x++后
x=‘e’,然后goto textdone后,state->ptr=x,*s=0,则state->text=“on”,再返回T_TEXT。

附表

|转义字符| 意义 |ASCII码值(十进制)|
|–|--|
| \n |换行(LF),将当前位置移到下一行开头 |010|
| \r |回车(CR) ,将当前位置移到本行开头 |013|
| \t |水平制表(HT) ( 跳到下一个TAB位置)|009|

\r是回车(CR),将光标移动到行前.

#include<stdio.h>
#include<stdlib.h>
int main(int argc, char* argv[])
{

	printf("ab c\n");				// 输出:ab c
	printf("\td\n");				// 输出:	d
	printf("abc\rf\n");				// 输出:fbc
	char str1[20]="abc\rf";
	printf("%x %x %x %x %x",str1[0],str1[1],str1[2],str1[3],str1[4]);//0x61 0x62 0x63 0xd 0x66
	return 0;
}

发布了120 篇原创文章 · 获赞 7 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/chengbeng1745/article/details/104087218
今日推荐