Init中的next_token()函数

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行的第一个for循环处理逻辑: 从文本找到待处理字符串的第一个字符。
具体操作: 在字符串找到有用字符,则会进入text中,分割字符串,保存内容;如果遇到字符串中非有用字符是"#",继续在字符串str中轮询,直接遇到换行符(’\n’),或者轮询到结束符(EOF),分别在35行返回T_NEWLINE,或者在38行中返回return T_EOF;如果遇到空行"\n",则返回T_NEWLINE;如到’ ‘,’\t’,'r’等特殊字符继续向前轮询字符。

在52行开始的第二个for循环:找到需要待处理字符串后一个字符(例如:空格、结束符号、换行)。

有个数据结构struct parse_state。

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

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

  1 import /init.environ.rc$                                                        
  2 import /init.usb.rc$                                                            
  3 $                                                                               
  4 on fs$                                                                                                                                                                                                  
  5 ^Imount_all ./fstab.uml $                                                       
  6 $                                                                               
  7 on early-init$                                                                  
  8     # Set init and its forked children's oom_adj.$                              
  9     write /proc/1/oom_score_adj -1000$                                          
 10     tom-init-rc$                                                                
 11 $                                                                               
~    

处理流程:
1)调用next_token(),如果遇到注释语句,从31行处理,直接轮询到行末换行符(’\n’),并且从35行出。
2)调用next_token(),处理到第4行,第一个字符是’o’,运行到40行,goto text,state->text = s=x。因为x=‘o’,匹配116行的default的case,执行到 s++ = x++;则x=‘n’,然后再匹配116行的default的case,执行完s++ = x++;则x是空格,则匹配56行的case,运行textdone,然后在s后面加结束符,则state->text=“on”,返回T_TEXT。
3) 调用next_token(),处理字符串“fs”,因为
s=’\n’(换行符),匹配到61行,执行state->nexttoken = T_NEWLINE;运行到textdone,运行后,则state->text=“on”,返回T_TEXT。
4)调用next_token(),运行到11行,返回T_NEWLINE,并且把state->nexttoken=0。

这样完成1行数据的处理。

附表

|转义字符| 意义 |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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 Flask 实现 Token 机制,可以使用 JWT(JSON Web Tokens)库。下面是一个简单的示例代码: ```python from flask import Flask, request from flask_jwt import JWT, jwt_required, current_identity from werkzeug.security import safe_str_cmp app = Flask(__name__) app.config['SECRET_KEY'] = 'super-secret' app.config['JWT_EXPIRATION_DELTA'] = timedelta(days=1) class User: def __init__(self, id, username, password): self.id = id self.username = username self.password = password def __str__(self): return f"User(id='{self.id}')" users = [ User(1, 'user1', 'password1'), User(2, 'user2', 'password2'), ] def authenticate(username, password): user = next((user for user in users if user.username == username), None) if user and safe_str_cmp(user.password.encode('utf-8'), password.encode('utf-8')): return user def identity(payload): user_id = payload['identity'] return next((user for user in users if user.id == user_id), None) jwt = JWT(app, authenticate, identity) @app.route('/protected') @jwt_required() def protected(): return f'Hello, {current_identity}!' if __name__ == '__main__': app.run() ``` 在上面的代码,我们首先定义了一个 `User` 类来存储用户信息。然后定义了一个 `authenticate` 函数来用于用户认证,它会查找用户列表是否存在指定的用户名和密码。如果存在,则返回该用户对象。 接下来,我们定义了一个 `identity` 函数,它会根据 JWT 存储的用户 ID 来查找用户对象。最后,我们创建了一个 `jwt` 对象,并将其绑定到 Flask 。 最后,我们定义了一个受保护的路由 `/protected`,并使用 `@jwt_required()` 装饰器来保护它。这意味着在访问该路由时,用户必须先提供有效的 JWT 才能继续访问。 当用户成功提供有效的 JWT 且通过身份验证时,`current_identity` 会返回该用户对象,我们可以在响应使用它。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值