gencin.c

来自「linux 下的 oxim 输入法,简单易用.」· C语言 代码 · 共 681 行 · 第 1/2 页

C
681
字号
    if (cmp_val == 0)    {	    if (aa->order < bb->order)	    {		return 1;	    }	    else if (aa->order > bb->order)	    {		return -1;	    }	    else	    {		return 0;	    }    }    else if (cmp_val > 0)	return 1;    else	return -1;}static voidcin_chardef(char *arg, cintab_t *cintab){    char cmd1[64], arg1[1024] = {'\0'}, arg2[32]= {'\0'};    cin_char_t *cch=NULL;    int argc;    unsigned int i, key_len;    unsigned int len;    unsigned int ucs4[256];    while ((argc=cmd_arg(True, cmd1, 64, arg1, 1024, arg2, 32, NULL)))    {	if ((strcasecmp("%chardef", cmd1) == 0 && strcasecmp("end", arg1) == 0) || strcasecmp("END_TABLE", cmd1) == 0)	{	    break;	}	if (argc < 2 || argc > 3)	{	    oxim_perr(OXIMMSG_WARNING, N_("%s(%d): arguement expected.\n"),		cintab->fname_cin, cintab->lineno);	    continue;	}	key_len = strlen(cmd1);	/* 	 * 看看字根中,是否有不合法的字元	 * 所謂不合法,就是在 selkey、keyname、endkey 沒有定義的字元 	 */	int allkey_valid = True;	for (i=0 ; i < key_len ; i++)	{	    unsigned int kk = cmd1[i];	    if (!th.keep_key_case && kk >= 'A' && kk <= 'Z')	    {		cmd1[i] = tolower(cmd1[i]);		kk = cmd1[i];	    }	    if (!validkey[kk])	    {#if 0		if (i || cmd1[i] != '#')		{		    oxim_perr(OXIMMSG_WARNING, N_("%s(%d): illegal key \"%c\" specified.\n"), cintab->fname_cin, cintab->lineno, cmd1[i]);		}		allkey_valid = False;		break;#else		if (i || cmd1[i] != '#')		{		    th.keyname[kk].s[0] = kk;		    th.keyname[kk].s[1] = '\0';		    validkey[kk] = '\1';		    th.n_key_name++;		}#endif	    }	}	if (!allkey_valid)	{	    continue;	}	th.n_input_content ++;	if (th.n_input_content == 1)	{	    cchar = oxim_malloc(sizeof(cin_char_t), True);	}	else	{	    cchar = oxim_realloc(cchar, (th.n_input_content+1) * sizeof(cin_char_t));	}	cch = (cchar + th.n_input_content) - 1; 	bzero(cch, sizeof(cin_char_t));	cch->key_len = key_len;	cch->keystroke = strdup(cmd1);	len = strlen(arg1);	int nbytes;	char *p = arg1;	unsigned int n_char = 0;	while (len && (nbytes = oxim_utf8_to_ucs4(p, &ucs4[n_char], len)) > 0)	{	    p += nbytes;	    len -= nbytes;	    n_char ++;	}	cch->word_len = n_char;	unsigned int size = sizeof(unsigned int) * n_char;	cch->word = oxim_malloc(size, False);	memcpy(cch->word, ucs4, size);	/* 累進單一字元數目 */	if (n_char == 1)	{	    th.n_char ++;	}	if (arg2[0] != '\0')	{	    cch->order = atoi(arg2);	}	if (th.n_max_keystroke < key_len)	    th.n_max_keystroke = key_len;	arg2[0] = '\0';    }}/*----------------------------------------------------------------------------	Main Functions.----------------------------------------------------------------------------*/struct genfunc_s {    char *name;    void (*func) (char *, cintab_t *);};static struct genfunc_s genfunc[] = {    {"%keep_key_case", cin_keepcase},    {"%setting", cin_setting},    {"%ename", cin_ename},/*    {"NAME", cin_cname},*/    {"%cname", cin_cname},    {"%prompt", cin_cname},    {"%keyname", cin_keyname},    {"BEGIN_CHAR_PROMPTS_DEFINITION", cin_keyname},    {"%selkey", cin_selkey},    {"SELECT_KEYS", scim_selkey},    {"%endkey", cin_endkey},    {"KEY_END_CHARS", cin_endkey},    {"%chardef", cin_chardef},    {"BEGIN_TABLE", cin_chardef},    {NULL, NULL}};voidgencin(cintab_t *cintab){    unsigned int i, argc;    char cmd[64], arg1[64], arg2[64];    size_t ret;    bzero(validkey, 128);    bzero(&th, sizeof(cintab_head_v1_t));    while (argc = cmd_arg(False, cmd, 64, arg1, 64, arg2, 64, NULL))    {	for (i=0; genfunc[i].name != NULL; i++)	{	    if (strcasecmp(genfunc[i].name, cmd) == 0)	    {		if (strlen(arg1) == 1 && arg1[0] == '=')		{		    genfunc[i].func(arg2, cintab);		}		else if (argc == 2)		{		    genfunc[i].func(arg1, cintab);		}		else		{		    genfunc[i].func(NULL, cintab);		}		break;	    }	    /* SCIM 的 Locale Name */	    else if (strcasecmp("NAME", cmd) == 0)	    {	    	/* */	        char tmp[128];		bzero(tmp, sizeof(tmp));		sprintf(tmp, "%s:en;", arg2);		cin_cname_scim(tmp, cintab);		break;	    }	    else if (strncasecmp("NAME.", cmd, 5) == 0)	    {	    	/* 以 XXX:zh_TW;YYY:zh_CN 的格式將輸入法表格名稱與locale一起加進去*/	        char tmp[128];		char *charset = cmd+5;		bzero(tmp, sizeof(tmp));		sprintf(tmp, "%s:%s;", arg2, charset);		cin_cname_scim(tmp, cintab);		break;	    }	}	if (genfunc[i].name == NULL)	    oxim_perr(OXIMMSG_NORMAL, N_("%s(%d): unknown command: %s, ignore.\n"), cintab->fname_cin, cintab->lineno, cmd);    }#if 1    /* 對輸入內容排序 */    stable_sort(cchar, th.n_input_content, sizeof(cin_char_t), icode_cmp);    unsigned int prefix_size = sizeof(table_prefix_t); /* 檔案識別結構 size */    unsigned int hdr_size = sizeof(cintab_head_v1_t); /* 表頭 size */    /* 國家地區列表 size */    unsigned int locale_size = sizeof(cintab_locale_table) * th.n_locale;    /* 設定列表 size */    unsigned int setting_size = sizeof(cintab_setting_table) * th.n_setting;    /* 位置索引列表 size */    unsigned int offset_size = sizeof(unsigned int) * (th.n_input_content + 1);    unsigned int *offset_table = oxim_malloc(offset_size, False);    /* 單字索引 size */    unsigned int char_index_size = sizeof(cintab_char_index) * th.n_char;    cintab_char_index *char_idx = NULL;    if (th.n_char)    {	char_idx = oxim_malloc(char_index_size, False);    }    cin_char_t *cch;    unsigned int idx = 0;    unsigned int offset = prefix_size + hdr_size + locale_size + setting_size + offset_size + char_index_size;    unsigned int rec_len = 0;    for (i=0, cch = cchar ; i < th.n_input_content ; i++, cch++)    {	offset_table[i] = offset;	/* 建立字元索引 */	if (cch->word_len == 1)	{	    char_idx[idx].ucs4 = cch->word[0];	    char_idx[idx].offset = offset;	    idx ++;	}	/* 1 + 1 + 字根長度 + 字詞長度 */	rec_len = sizeof(unsigned char) + sizeof(unsigned char) + cch->key_len + (cch->word_len * sizeof(unsigned int));	offset += rec_len;    }    offset_table[i] = offset;    /* 依據字元排序 */    if (char_idx)    {	stable_sort(char_idx, th.n_char, sizeof(cintab_char_index), char_cmp);    }    /* locale table offset */    th.locale_table_offset = prefix_size + hdr_size;    /* setting table offset */    th.setting_table_offset = th.locale_table_offset + locale_size;    /* offset table offset */    th.offset_table_offset = th.setting_table_offset + setting_size;    /* char offset */    th.char_offset = th.offset_table_offset + offset_size;    /* input content offset */    th.input_content_offset = th.char_offset + char_index_size;    /* 計算 Checksum */    th.chksum = crc32(th.chksum, (char *)&th, sizeof(cintab_head_v1_t) - sizeof(unsigned int));    /* 寫入表頭 */    gzwrite(cintab->fw, &th, hdr_size);    /* 寫入國家地區列表 */    if (th.n_locale)    {	gzwrite(cintab->fw, locale_table, locale_size);    }    /* 寫入設定列表 */    if (th.n_setting)    {	gzwrite(cintab->fw, setting_table, setting_size);    }    /* 寫入位置索引列表 */    gzwrite(cintab->fw, offset_table, offset_size);    /* 寫入字元索引列表 */    if (th.n_char)    {	gzwrite(cintab->fw, char_idx, char_index_size);    }    /* 最後寫入真正的資料 */    for (i=0, cch = cchar ; i < th.n_input_content ; i++, cch++)    {	/* 字根長度 */	gzwrite(cintab->fw, &cch->key_len, sizeof(unsigned char));	/* 字詞長度 */	gzwrite(cintab->fw, &cch->word_len, sizeof(unsigned char));	/* 字根資料 */	gzwrite(cintab->fw, cch->keystroke, cch->key_len);	/* 字詞資料 */	gzwrite(cintab->fw, cch->word, cch->word_len * sizeof(unsigned int));    }#endif    oxim_perr(OXIMMSG_NORMAL,	N_("number of locale: %d\n"), th.n_locale);    oxim_perr(OXIMMSG_NORMAL,	N_("number of settings: %d\n"), th.n_setting);    oxim_perr(OXIMMSG_NORMAL,	N_("number of keyname: %d\n"), th.n_key_name);    oxim_perr(OXIMMSG_NORMAL, 	N_("max length of keystroke: %d\n"), th.n_max_keystroke);    oxim_perr(OXIMMSG_NORMAL, 	N_("number of keystroke code defined: %d\n"), th.n_input_content);    oxim_perr(OXIMMSG_NORMAL, 	N_("number of char defined: %d\n"), th.n_char);    oxim_perr(OXIMMSG_NORMAL, 	N_("number of phrase define: %d\n"), th.n_input_content - th.n_char);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?