Logo Search packages:      
Sourcecode: fcitx version File versions  Download package

void LoadConfig ( Bool  bMode )

读取用户的配置文件

Parameters:
bMode标识配置文件是用户家目录下的,还是从安装目录下拷贝过来的
Returns:
void

Definition at line 1172 of file tools.c.

References SaveConfig().

{
    FILE    *fp;
    char    buf[PATH_MAX], *pbuf, *pbuf1;
    Bool    bFromUser = True;
    //用于标示group的index,在配置文件里面配置是分组的,类似与ini文件的分组
    int     group_idx;
    int           i;
    Configure   *tmpconfig;

    //用以标识配置文件是用户家目录下的,还是从安装目录下拷贝过来的
    bIsReloadConfig = bMode;  // 全局变量,定义于“src/tool.c[193]"

    pbuf = getenv("HOME");          // 从环境变量中获取当前用户家目录的绝对路径
    if(!pbuf){
        fprintf(stderr, "error: get environment variable HOME\n");
        exit(1);  // 此时可以不退出,但直接退出处理起来明了简单
    }
    //获取配置文件的绝对路径
    snprintf(buf, PATH_MAX, "%s/.fcitx/config", pbuf);

    fp = fopen(buf, "r");
    if(!fp && errno == ENOENT){ /* $HOME/.fcitx/config does not exist */
        snprintf(buf, PATH_MAX, PKGDATADIR "/data/config");
        bFromUser = False;
        fp = fopen(buf, "r");
        if(!fp){
            perror("fopen");
            exit(1);    /* 如果安装目录里面也没有配置文件,那就没办法了。
                                     * 只好告诉用户,无法运行了*/
        }
    }

    if(!bFromUser) /* create default configure file */
        SaveConfig();

    group_idx = -1;

    /* FIXME: 也许应该用另外更恰当的缓冲区长度 */
    while(fgets(buf, PATH_MAX, fp)){            //每次最多读入PATH_MAX大小的数据
        i = strlen(buf);

        /*fcitx的配置文件每行最多是PATH_MAX个字符,因此有上面的FIXME*/
        if(buf[i-1] != '\n'){
            fprintf(stderr, "error: configure file: line length\n");
            exit(1);
        }else
            buf[i-1] = '\0';

        pbuf = buf;
        while(*pbuf && isspace(*pbuf))    //将pbuf指向第一个非空字符
            pbuf++;
        if(!*pbuf || *pbuf == '#')        //如果改行是空数据或者是注释(以#开头为注释)
            continue;

        if(*pbuf == '['){ /* get a group name(组名的格式为"[组名]")*/
            pbuf++;
            pbuf1 = strchr(pbuf, ']');
            if(!pbuf1){
                fprintf(stderr, "error: configure file: configure group name\n");
                exit(1);
            }

            //根据group的名字找到其在全局变量configure_groups中的index
            group_idx = -1;
            for(i = 0; configure_groups[i].name; i++)
                if(strncmp(configure_groups[i].name, pbuf, pbuf1-pbuf) == 0){
                    group_idx = i;
                    break;
                }
            if(group_idx < 0){
                fprintf(stderr, "error: invalid configure group name\n");
                exit(1); /* 我认为这儿没有必要退出。此处完全可以忽略这个错误,
                          * 并且在后面也忽略这个组的配置即可。
                          * 因为这儿退出只会带来一个坏处,那就是扩展性。
                          * 以后再添加新的组的时候,老版本的程序就无法使用
                          * 新版本的配置文件了。或者,添加了一个可选扩展,
                          * 该扩展新添加一个组等等。所以,此处应该给一个警告,
                          * 而不是退出。*/
            }
            continue;
        }

        //pbuf1指向第一个非空字符与=之间的字符
        pbuf1 = strchr(pbuf, '=');
        if(!pbuf1){
            fprintf(stderr, "error: configure file: configure entry name\n");
            exit(1);    // 和前面一样,这儿也应该是一个警告而不应该是提示出错并退出。
        }

        /*
         * 这儿避免的是那样一种情况,即从文件头到第一个配置项(即类似与“配置名=配置值”
         * 的一行字符串)并没有任何分组。也就是防止出现下面的“配置1”和“配置2”
         * #文件头
         * 配置1=123 配置2=123
         * [组名]
         * ...
         * #文件尾
         */


        if(group_idx < 0){
            fprintf(stderr, "error: configure file: no group name at beginning\n");
            exit(1);
        }

        //找到该组中的配置项,并将其保存到对应的全局变量里面去
        for(tmpconfig = configure_groups[group_idx].configure;
                tmpconfig->name; tmpconfig++)
        {
            if(strncmp(tmpconfig->name, pbuf, pbuf1-pbuf) == 0)
                read_configure(tmpconfig, ++pbuf1);
        }
    }

    fclose(fp);

    /* Ctrl+Space就是fcitx的开关快捷键,此处构造一个结构备用。
     * 至于为什么这样做,现在还不清楚。接下去看可能会明白作者的用意。*/
    if (!Trigger_Keys) {
      iTriggerKeyCount = 0;
      Trigger_Keys = (XIMTriggerKey *) malloc (sizeof (XIMTriggerKey) * (iTriggerKeyCount + 2));
      Trigger_Keys[0].keysym = XK_space;
      Trigger_Keys[0].modifier = ControlMask;
      Trigger_Keys[0].modifier_mask = ControlMask;
      Trigger_Keys[1].keysym = 0;
      Trigger_Keys[1].modifier = 0;
      Trigger_Keys[1].modifier_mask = 0;
    }
}

Here is the call graph for this function:


Generated by  Doxygen 1.6.0   Back to index