本文转载自 http://blog.itpub.net/7232789/viewspace-758167/

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

3parse_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;

}

 

 

4parse_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对象。

 

5parse_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组成一个双向链表指向该actioncommands字段中。



更多相关文章

  1. 工作总结
  2. 两分钟彻底让你明白Android(安卓)Activity生命周期(图文)!
  3. Android(安卓)正则表达式
  4. 安卓选择器 selector 的笔记
  5. Android数据储存之SharedPreferences
  6. color 颜色代码 android res/values/colors.xml
  7. Android反射出一个类中的其他类对象并调用其对应方法
  8. Android(安卓)edittext中添加图片并且监听图片的点击事件
  9. android 控件放大缩小效果实现

随机推荐

  1. 获取Android设备的设备详细信息
  2. Android(安卓)Design Support Library学
  3. Android(安卓)自定义CheckBox 样式
  4. 通过 按钮 bundle 传过来 变换Q币图片
  5. 申请android google map API key
  6. Android(安卓)日志打印工具类 可显示打印
  7. android 发送短信的两种方式
  8. android.support.v4.widget.DrawerLayout
  9. Android(安卓)命令行手动编译打包详解
  10. 关于Android证书申请配置