1
/* Copyright (C) 1995-2011 Edward Liu, Hsin-Chu, Taiwan
3
* This library is free software; you can redistribute it and/or
4
* modify it under the terms of the GNU Lesser General Public
5
* License as published by the Free Software Foundation; either
6
* version 2.1 of the License, or (at your option) any later version.
8
* This library is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
* Lesser General Public License for more details.
13
* You should have received a copy of the GNU Lesser General Public
14
* License along with this library; if not, write to the Free Software
15
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
#include <sys/types.h>
22
#include <sys/param.h>
28
#include "hime-endian.h"
29
#include "hime-version.h"
36
char *skip_spc(char *s)
38
while ((*s==' ' || *s=='\t') && *s) s++;
44
while (*s!=' ' && *s!='\t' && *s) s++;
48
void del_nl_spc(char *s)
57
while (*t=='\n' || *t==' ' || (*t=='\t' && t > s))
67
bzero(tt, sizeof(tt));
68
myfgets(tt, sizeof(tt), fr);
75
if (tt[0]=='#' || strlen(tt) < 3)
82
void cmd_arg(char **cmd, char **arg)
109
if ((p=strchr(t, '\t')))
115
int sequ(char *s, char *t)
117
return (!strcmp(s,t));
133
#define MAX_K (500000)
136
ITEM2_64 itar64[MAX_K];
139
ITEM64 itout64[MAX_K];
142
int qcmp(const void *aa, const void *bb)
144
ITEM2 *a = (ITEM2 *)aa, *b = (ITEM2 *) bb;
146
if (a->key > b->key) return 1;
147
if (a->key < b->key) return -1;
149
return a->oseq - b->oseq;
153
int qcmp_64(const void *aa, const void *bb)
155
ITEM2_64 *a = (ITEM2_64 *)aa, *b = (ITEM2_64 *) bb;
157
if (a->key > b->key) return 1;
158
if (a->key < b->key) return -1;
160
return a->oseq - b->oseq;
164
#define mtolower(ch) (ch>='A'&&ch<='Z'?ch+0x20:ch)
166
static char kno[128];
168
int main(int argc, char **argv)
177
char kname[128][CH_SZ];
180
gtab_idx1_t idx1[256];
183
int *phridx=NULL, phr_cou=0;
187
if (!getenv("NO_GTK_INIT"))
188
gtk_init(&argc, &argv);
190
printf("-- cin2gtab encoding UTF-8 --\n");
191
printf("--- please use iconv -f big5 -t utf-8 if your file is in big5 encoding\n");
194
printf("Enter table file name [.cin] : ");
196
} else strcpy(fname,argv[1]);
199
if (!strcmp(fname, "-v") || !strcmp(fname, "--version")) {
200
dbg("cin2gtab for hime " HIME_VERSION "\n");
205
if((p=strstr(fname, ".cin")))
208
strcpy(fname_cin,fname);
209
strcpy(fname_tab,fname);
210
strcat(fname_cin,".cin");
211
strcat(fname_tab,".gtab");
213
if ((fr=fopen(fname_cin,"rb"))==NULL)
214
p_err("Cannot open %s\n", fname_cin);
216
skip_utf8_sigature(fr);
219
bzero(&th,sizeof(th));
220
bzero(kno,sizeof(kno));
221
bzero(keymap,sizeof(keymap));
223
bzero(itar,sizeof(itar));
224
bzero(itout,sizeof(itout));
225
bzero(itar64,sizeof(itar64));
226
bzero(itout64,sizeof(itout64));
229
if (sequ(cmd, "%gen_inp")) {
230
dbg("skip gen_inp\n");
234
if (!sequ(cmd,"%ename") || !(*arg) )
235
p_err("%d: %%ename english_name expected", lineno);
237
// strcpy(th.ename,arg);
240
if (!(sequ(cmd,"%prompt") || sequ(cmd,"%cname")) || !(*arg) )
241
p_err("%d: %%prompt prompt_name expected", lineno);
242
strncpy(th.cname, arg, MAX_CNAME);
243
dbg("cname %s\n", th.cname);
246
if (!sequ(cmd,"%selkey") || !(*arg) )
247
p_err("%d: %%selkey select_key_list expected", lineno);
250
if (strlen(arg) >= sizeof(th.selkey)) {
251
memcpy(th.selkey, arg, sizeof(th.selkey));
252
strcpy(th.selkey2, arg+sizeof(th.selkey));
253
dbg("th.selkey2 %s\n", th.selkey2);
255
strcpy(th.selkey,arg);
258
if (!sequ(cmd,"%dupsel") || !(*arg) ) {
259
if (th.selkey[sizeof(th.selkey)-1])
260
th.M_DUP_SEL = sizeof(th.selkey) + strlen(th.selkey2);
262
th.M_DUP_SEL = strlen(th.selkey);
265
th.M_DUP_SEL=atoi(arg);
270
if (sequ(cmd,"%endkey")) {
271
strcpy(th.endkey, arg);
274
if (sequ(cmd,"%space_style")) {
275
th.space_style = (GTAB_space_pressed_E)atoi(arg);
278
if (sequ(cmd,"%keep_key_case")) {
279
th.flag |= FLAG_KEEP_KEY_CASE;
282
if (sequ(cmd,"%symbol_kbm")) {
283
th.flag |= FLAG_GTAB_SYM_KBM;
286
if (sequ(cmd,"%phase_auto_skip_endkey")) {
287
th.flag |= FLAG_PHRASE_AUTO_SKIP_ENDKEY;
290
if (sequ(cmd,"%flag_auto_select_by_phrase")) {
291
dbg("flag_auto_select_by_phrase\n");
292
th.flag |= FLAG_AUTO_SELECT_BY_PHRASE;
295
if (sequ(cmd,"%flag_disp_partial_match")) {
296
dbg("flag_disp_partial_match\n");
297
th.flag |= FLAG_GTAB_DISP_PARTIAL_MATCH;
300
if (sequ(cmd,"%flag_disp_full_match")) {
301
dbg("flag_disp_full_match\n");
302
th.flag |= FLAG_GTAB_DISP_FULL_MATCH;
305
if (sequ(cmd,"%flag_vertical_selection")) {
306
dbg("flag_vertical_selection\n");
307
th.flag |= FLAG_GTAB_VERTICAL_SELECTION;
310
if (sequ(cmd,"%flag_press_full_auto_send")) {
311
dbg("flag_press_full_auto_send\n");
312
th.flag |= FLAG_GTAB_PRESS_FULL_AUTO_SEND;
315
if (sequ(cmd,"%flag_unique_auto_send")) {
316
dbg("flag_unique_auto_send\n");
317
th.flag |= FLAG_GTAB_UNIQUE_AUTO_SEND;
324
if (!sequ(cmd,"%keyname") || !sequ(arg,"begin")) {
325
p_err("%d: %%keyname begin expected, instead of %s %s", lineno, cmd, arg);
332
if (sequ(cmd,"%keyname")) break;
333
if (BITON(th.flag, FLAG_KEEP_KEY_CASE))
339
p_err("%d: key %c is already used",lineno, k);
341
kno[(int)k]=++KeyNum;
343
bchcpy(&kname[KeyNum][0], arg);
346
keymap[0]=kname[0][0]=kname[0][1]=' ';
348
th.KeyS=KeyNum; /* include space */
352
if (sequ(cmd,"%quick") && sequ(arg,"begin")) {
353
dbg(".. quick keys defined\n");
358
if (sequ(cmd,"%quick")) break;
359
k=kno[mtolower(cmd[0])]-1;
364
if (strlen(cmd)==1) {
366
int len=u8cpy(th.qkeys.quick1[(int)k][N++], p);
370
if (strlen(cmd)==2) {
371
int k1=kno[mtolower(cmd[1])]-1;
374
int len=u8cpy(tp, p);
379
u8cpy(th.qkeys.quick2[(int)k][(int)k1][N++], tp);
383
p_err("%d: %quick only 1&2 keys are allowed '%s'", lineno, cmd);
390
int olineno = lineno;
391
gboolean key64 = FALSE;
398
if (!cmd[0] || !arg[0])
401
if (!strcmp(cmd, "%chardef")) {
402
if (!strcmp(arg, "end"))
410
if (max_key_len < len)
415
fseek(fr, pos, SEEK_SET);
418
INMD inmd, *cur_inmd = &inmd;
420
cur_inmd->key64 = key64;
421
cur_inmd->tbl64 = itout64;
422
cur_inmd->tbl = itout;
425
cur_inmd->keybits = 6;
427
cur_inmd->keybits = 7;
429
if (cur_inmd->keybits * max_key_len > 32) {
430
cur_inmd->key64 = key64 = TRUE;
436
printf("KeyNum:%d keybits:%d\n", KeyNum, cur_inmd->keybits);
438
th.keybits = cur_inmd->keybits;
439
cur_inmd->last_k_bitn = (((cur_inmd->key64 ? 64:32) / cur_inmd->keybits) - 1) * cur_inmd->keybits;
450
if (!cmd[0] || !arg[0])
453
if (!strcmp(cmd, "%chardef")) {
454
if (!strcmp(arg, "end"))
462
if (len > th.MaxPress) {
467
p_err("%d: only <= 10 keys is allowed '%s'", lineno, cmd);
471
int key = BITON(th.flag, FLAG_KEEP_KEY_CASE) ?
472
cmd[i] : mtolower(cmd[i]);
477
p_err("%d: key undefined in keyname '%c'\n", lineno, cmd[i]);
479
kk|=(u_int64_t)k << ( LAST_K_bitN - i*th.keybits);
482
// dbg("%s kk:%llx\n", cmd, kk);
485
memcpy(&itar64[chno].key, &kk, 8);
486
itar64[chno].oseq=chno;
489
u_int key32 = (u_int)kk;
491
memcpy(&itar[chno].key, &key32, 4);
492
itar[chno].oseq=chno;
495
if ((len=strlen(arg)) <= CH_SZ && (arg[0] & 0x80)) {
498
bzero(out, sizeof(out));
499
memcpy(out, arg, len);
502
bchcpy(itar64[chno].ch, out);
504
bchcpy(itar[chno].ch, out);
508
itar64[chno].ch[0]=phr_cou>>16;
509
itar64[chno].ch[1]=(phr_cou >> 8) & 0xff;
510
itar64[chno].ch[2]=phr_cou&0xff;
513
itar[chno].ch[0]=phr_cou>>16;
514
itar[chno].ch[1]=(phr_cou >> 8) & 0xff;
515
itar[chno].ch[2]=phr_cou&0xff;
518
if (len > MAX_CIN_PHR)
519
p_err("phrase too long: %s max:%d bytes\n", arg, MAX_CIN_PHR);
521
phridx = trealloc(phridx, int, phr_cou+1);
522
phridx[phr_cou++]=prbf_cou;
523
phrbuf = (char *)realloc(phrbuf, prbf_cou + len + 1);
524
strcpy(&phrbuf[prbf_cou],arg);
525
// printf("phrase:%d len:%d'%s'\n", phr_cou, len, arg);
535
printf("MaxPress: %d\n", th.MaxPress);
538
cur_inmd->DefChars = chno;
541
_sort(itar64,chno,sizeof(ITEM2_64),qcmp_64);
543
_sort(itar,chno,sizeof(ITEM2),qcmp);
547
memcpy(&itout64[i],&itar64[i],sizeof(ITEM64));
550
memcpy(&itout[i],&itar[i],sizeof(ITEM));
554
bzero(def1,sizeof(def1));
555
bzero(idx1,sizeof(idx1));
558
u_int64_t keymask = KEY_MASK;
559
for(i=0; i<chno; i++) {
560
u_int64_t key = CONVT2(cur_inmd, i);
561
int kk = (int)((key>>LAST_K_bitN) & keymask);
564
idx1[kk]=(gtab_idx1_t)i;
570
for(i=KeyNum-1;i>0;i--)
571
if (!def1[i]) idx1[i]=idx1[i+1];
573
if ((fw=fopen(fname_tab,"wb"))==NULL) {
574
p_err("Cannot create");
577
printf("Defined Characters:%d\n", chno);
580
swap_byte_4(&th.version);
581
swap_byte_4(&th.flag);
582
swap_byte_4(&th.space_style);
583
swap_byte_4(&th.KeyS);
584
swap_byte_4(&th.MaxPress);
585
swap_byte_4(&th.M_DUP_SEL);
586
swap_byte_4(&th.DefC);
587
for(i=0; i <= KeyNum; i++)
588
swap_byte_4(&idx1[i]);
590
fwrite(&th,1,sizeof(th),fw);
591
fwrite(keymap, 1, KeyNum, fw);
592
fwrite(kname, CH_SZ, KeyNum, fw);
594
fwrite(idx1, sizeof(gtab_idx1_t), KeyNum+1, fw);
599
for(i=0; i < chno; i++) {
600
swap_byte_8(&itout64[i].key);
603
fwrite(itout64, sizeof(ITEM64), chno, fw);
605
for(i=0; i < 100; i++)
606
dbg("%d] %c%c%c\n", i, itout64[i].ch[0], itout64[i].ch[1], itout64[i].ch[2]);
611
for(i=0; i < chno; i++) {
612
swap_byte_4(&itout[i].key);
615
fwrite(itout, sizeof(ITEM), chno, fw);
619
phridx[phr_cou++]=prbf_cou;
620
printf("phrase count:%d\n", phr_cou);
622
int ophr_cou = phr_cou;
624
for(i=0; i < phr_cou; i++)
625
swap_byte_4(&phridx[i]);
626
swap_byte_4(&phr_cou);
628
fwrite(&phr_cou, sizeof(int), 1, fw);
629
fwrite(phridx, sizeof(int), ophr_cou, fw);
630
fwrite(phrbuf,1,prbf_cou,fw);
637
strcat(strcpy(bzip2, "bzip2 -f -k "), fname_tab);