您的位置:首页 > 移动开发 > Android开发

Android init.rc文件解析过程详解(二)

2016-11-30 23:20 615 查看
Android init.rc文件解析过程详解(二)
 

3、parse_new_section代码如下:

 

void parse_new_section(struct parse_state *state, int kw,
                       int nargs, char **args)
{
    printf("[ %s %s ]\n", args[0],
           nargs > 1 ? args[1] : "");
    switch(kw) {
    case K_service:                             \\解析service类型的section
        state->context = parse_service(state, nargs, args);
        if (state->context) {
            state->parse_line = parse_line_service;
            return;
        }
        break;
    case K_on:                                                        \\解析on类型的section
        state->context = parse_action(state, nargs, args);
        if (state->context) {
            state->parse_line = parse_line_action;
            return;
        }
        break;
    case K_import:                                                  \\解析import类型的section
        parse_import(state, nargs, args);
        break;
    }
    state->parse_line = parse_line_no_op;
}
 
 
4、parse_service()和parse_line_service()
parse_service()代码如下:
static void *parse_service(struct parse_state *state, int nargs, char **args)
{
    struct service *svc;
    if (nargs < 3) {
        parse_error(state, "services must have a name and a program\n");
        return 0;
    }
    if (!valid_name(args[1])) {
        parse_error(state, "invalid service name '%s'\n", args[1]);
        return 0;
    }
 
    svc = service_find_by_name(args[1]);            //在链表中查找当前行对应的service
    if (svc) {
        parse_error(state, "ignored duplicate definition of service '%s'\n", args[1]);
        return 0;
    }
      //如果当前行对应的service还没有加入service_list链表,则新建一个
    nargs -= 2;
    svc = calloc(1, sizeof(*svc) + sizeof(char*) * nargs);
    if (!svc) {
        parse_error(state, "out of memory\n");
        return 0;
    }
    svc->name = args[1];
    svc->classname = "default";
    memcpy(svc->args, args + 2, sizeof(char*) * nargs);
    svc->args[nargs] = 0;
    svc->nargs = nargs;
    svc->onrestart.name = "onrestart";
    list_init(&svc->onrestart.commands);
    list_add_tail(&service_list, &svc->slist);        //将这个service加入到service_list
//注意此时svc对象基本上是一个空壳,因为相关的options还没有解析
    return svc;
}
 
parse_line_service()解析service对应的options行,主要是填充parse_service()中创建的service对象。
 
5、parse_action()和parse_line_action()
 
   parse_action()函数主要是根据当前行的信息创建一个action结构体类型的对象,加入到action_list双向链表中, 代码比较简单,有兴趣可自行研究。
 
 
parse_line_action()解析对应的命令行, 代码如下:
 
static void parse_line_action(struct parse_state* state, int nargs, char **args)
{
    struct command *cmd;
    struct action *act = state->context;
    int (*func)(int nargs, char **args);
    int kw, n;
 
    if (nargs == 0) {
        return;
    }
 
    kw = lookup_keyword(args[0]);
    if (!kw_is(kw, COMMAND)) {
        parse_error(state, "invalid command '%s'\n", args[0]);
        return;
    }
 
    n = kw_nargs(kw);
    if (nargs < n) {
        parse_error(state, "%s requires %d %s\n", args[0], n - 1,
            n > 2 ? "arguments" : "argument");
        return;
    }
    cmd = malloc(sizeof(*cmd) + sizeof(char*) * nargs);      //生成一个command类型的对象
    cmd->func = kw_func(kw);
    cmd->nargs = nargs;
    memcpy(cmd->args, args, sizeof(char*) * nargs);
    list_add_tail(&act->commands, &cmd->clist);      //将这个command对象加入actions->commands
}
 
 
一个on类型的section对应一个action, action类型定义如下:
 
struct action {
        /* node in list of all actions */
    struct listnode alist;
        /* node in the queue of pending actions */
    struct listnode qlist;
        /* node in list of actions for a trigger */
    struct listnode tlist;
 
    unsigned hash;
    const char *name;
   
    struct listnode commands;             //command的双向链表
    struct command *current;
};
 
因此,每个on类型section的第二行开始每一行都解析了一个command, 所有command组成一个双向链表指向该action的commands字段中。
转载:http://blog.itpub.net/7232789/viewspace-758167/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: