~ubuntu-branches/ubuntu/precise/hime/precise

« back to all changes in this revision

Viewing changes to src/pho-util.c

  • Committer: Package Import Robot
  • Author(s): Yao Wei (魏銘廷)
  • Date: 2012-01-14 00:24:08 UTC
  • Revision ID: package-import@ubuntu.com-20120114002408-e79gagbeg1rt8npv
Tags: upstream-0.9.9
Import upstream version 0.9.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2011 Edward Der-Hua Liu, Hsin-Chu, Taiwan
 
2
 *
 
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.
 
7
 *
 
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.
 
12
 *
 
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
 
16
 */
 
17
 
 
18
#include "hime.h"
 
19
#include "pho.h"
 
20
#include "lang.h"
 
21
#include <sys/stat.h>
 
22
#include <stdlib.h>
 
23
 
 
24
char phofname[128]="";
 
25
extern char *TableDir;
 
26
u_short idxnum_pho;
 
27
PHO_IDX *idx_pho;
 
28
int ch_pho_ofs;
 
29
PHO_ITEM *ch_pho;
 
30
int ch_phoN;
 
31
char *pho_phrase_area;
 
32
int pho_phrase_area_sz;
 
33
static char pho_normal_tab[]="pho.tab2";
 
34
static char pho_huge_tab[]="pho-huge.tab2";
 
35
static char s_pho_normal_tab[]="s-pho.tab2";
 
36
static char s_pho_huge_tab[]="s-pho-huge.tab2";
 
37
void update_table_file(char *name, int version);
 
38
 
 
39
void pho_load()
 
40
{
 
41
  char *pho_tab;
 
42
 
 
43
  if (is_chs) {
 
44
    pho_tab = phonetic_huge_tab ? s_pho_huge_tab:s_pho_normal_tab;
 
45
  } else
 
46
    pho_tab = phonetic_huge_tab ? pho_huge_tab:pho_normal_tab;
 
47
 
 
48
  if (!getenv("HIME_TABLE_DIR") && phonetic_char_dynamic_sequence) {
 
49
    get_hime_user_fname(pho_tab, phofname);
 
50
    if (access(phofname, W_OK) < 0){
 
51
      char sys_file[256], vv[256];
 
52
      get_sys_table_file_name(sys_file, pho_tab);
 
53
      sprintf(vv,"cp %s %s\n", sys_file, phofname);
 
54
      system(vv);
 
55
    }
 
56
  } else {
 
57
    get_sys_table_file_name(pho_tab, phofname);
 
58
    dbg("use system's pho, no dynamic adj\n");
 
59
  }
 
60
 
 
61
  update_table_file(pho_tab, 4);
 
62
 
 
63
  FILE *fr;
 
64
 
 
65
  if ((fr=fopen(phofname,"rb"))==NULL)
 
66
    p_err("err %s\n", phofname);
 
67
 
 
68
  fread(&idxnum_pho,sizeof(u_short),1,fr);
 
69
  fread(&idxnum_pho,sizeof(u_short),1,fr);
 
70
  fread(&ch_phoN,sizeof(int),1,fr);
 
71
  fread(&pho_phrase_area_sz, sizeof(pho_phrase_area_sz), 1,fr);
 
72
 
 
73
  if (idx_pho)
 
74
    free(idx_pho);
 
75
  idx_pho = tmalloc(PHO_IDX, idxnum_pho + 1);
 
76
  fread(idx_pho, sizeof(PHO_IDX), idxnum_pho, fr);
 
77
 
 
78
  ch_pho_ofs = ftell(fr);
 
79
 
 
80
  if (ch_pho)
 
81
    free(ch_pho);
 
82
 
 
83
  if (!(ch_pho=tmalloc(PHO_ITEM, ch_phoN)))
 
84
    p_err("malloc error");
 
85
 
 
86
  fread(ch_pho,sizeof(PHO_ITEM), ch_phoN, fr);
 
87
//  dbg("ch_phoN:%d  %d\n", ch_phoN, idxnum_pho);
 
88
  if (pho_phrase_area) {
 
89
    free(pho_phrase_area);
 
90
    pho_phrase_area = NULL;
 
91
  }
 
92
  if (pho_phrase_area_sz) {
 
93
    pho_phrase_area = tmalloc(char, pho_phrase_area_sz);
 
94
    fread(pho_phrase_area, 1,pho_phrase_area_sz, fr);
 
95
#if 0
 
96
    dbg("pho_phrase loaded %d\n", pho_phrase_area_sz);
 
97
    int i;
 
98
    for(i=0; i <pho_phrase_area_sz; i+=strlen(pho_phrase_area+i)+1) {
 
99
      dbg("  %s\n", pho_phrase_area+i);
 
100
    }
 
101
#endif
 
102
  }
 
103
 
 
104
  fclose(fr);
 
105
 
 
106
  idx_pho[idxnum_pho].key=0xffff;
 
107
  idx_pho[idxnum_pho].start=ch_phoN;
 
108
 
 
109
#if 0
 
110
  int i;
 
111
  for(i=0; i <ch_phoN; i++) {
 
112
    char tt[5];
 
113
 
 
114
    utf8cpy(tt, ch_pho[i].ch);
 
115
    dbg("oooo %s\n", tt);
 
116
  }
 
117
#endif
 
118
}
 
119
 
 
120
 
 
121
char *pho_idx_str2(int idx, int *is_phrase)
 
122
{
 
123
  static char tt[CH_SZ+1];
 
124
 
 
125
  unsigned char *p = (u_char *)ch_pho[idx].ch;
 
126
 
 
127
  if (*p==PHO_PHRASE_ESCAPE) {
 
128
    p++;
 
129
    int ofs = (*p) | *(p+1)<<8 | *(p+2)<<16;
 
130
 
 
131
//    dbg("idx:%d ofs:%d %s\n", idx, ofs, pho_phrase_area+ofs);
 
132
    *is_phrase = TRUE;
 
133
    return pho_phrase_area+ofs;
 
134
  } else {
 
135
    *is_phrase = FALSE;
 
136
    utf8cpy(tt, (char *)p);
 
137
    return tt;
 
138
  }
 
139
}
 
140
 
 
141
char *pho_idx_str(int idx)
 
142
{
 
143
  int is_phrase;
 
144
  return pho_idx_str2(idx, &is_phrase);
 
145
}
 
146
 
 
147
void free_pho_mem()
 
148
{
 
149
  if (ch_pho)
 
150
    free(ch_pho);
 
151
}
 
152
 
 
153
typedef struct {
 
154
  phokey_t key;
 
155
  short count;
 
156
} PH_COUNT;
 
157
 
 
158
static int qcmp_pho_count(const void *aa, const void *bb)
 
159
{
 
160
  PH_COUNT *a = (PH_COUNT *)aa;
 
161
  PH_COUNT *b = (PH_COUNT *)bb;
 
162
 
 
163
  return b->count - a->count;
 
164
}
 
165
 
 
166
 
 
167
int utf8_pho_keys(char *utf8, phokey_t *phkeys)
 
168
{
 
169
  int i;
 
170
  int ofs=0;
 
171
  int phkeysN=0;
 
172
  PH_COUNT phcou[256];
 
173
 
 
174
  do {
 
175
    for(; ofs < ch_phoN; ofs++)
 
176
      if (utf8_eq(utf8, pho_idx_str(ofs)))
 
177
        break;
 
178
 
 
179
    if (ofs==ch_phoN)
 
180
      goto ret;
 
181
 
 
182
    for(i=0; i < idxnum_pho; i++) {
 
183
      if (idx_pho[i].start<= ofs && ofs < idx_pho[i+1].start) {
 
184
//        dbg("ofs:%d %d  %d %d\n", ofs, i, idx_pho[i].start, idx_pho[i+1].start);
 
185
        phcou[phkeysN].count = ch_pho[ofs].count;
 
186
        phcou[phkeysN++].key = idx_pho[i].key;
 
187
        break;
 
188
      }
 
189
    }
 
190
 
 
191
    ofs++;
 
192
  } while (ofs < ch_phoN);
 
193
 
 
194
ret:
 
195
 
 
196
#if 0
 
197
    utf8_putchar(utf8);
 
198
    dbg("n %d\n", phkeysN);
 
199
#endif
 
200
  qsort(phcou, phkeysN, sizeof(PH_COUNT), qcmp_pho_count);
 
201
 
 
202
  for(i=0; i < phkeysN; i++)
 
203
    phkeys[i] = phcou[i].key;
 
204
 
 
205
  return phkeysN;
 
206
}
 
207
 
 
208
char *phokey_to_str2(phokey_t kk, int last_number)
 
209
{
 
210
  u_int k1,k2,k3,k4;
 
211
  static char phchars[PHO_CHAR_LEN * 4 + 1];
 
212
  int phcharsN=0;
 
213
 
 
214
  phokey_t okk = kk;
 
215
  k4=(kk&7);
 
216
  kk>>=3;
 
217
  k3=(kk&15) * PHO_CHAR_LEN;
 
218
  kk>>=4;
 
219
  k2=(kk&3) * PHO_CHAR_LEN;
 
220
  kk>>=2;
 
221
  k1=(kk&31) * PHO_CHAR_LEN;
 
222
 
 
223
  if (k1==BACK_QUOTE_NO * PHO_CHAR_LEN) {
 
224
    strcpy(phchars, "、");
 
225
    int len=strlen(phchars);
 
226
    phchars[len++]=okk & 0x7f;
 
227
    phchars[len]=0;
 
228
    return phchars;
 
229
  }
 
230
 
 
231
  if (k1) {
 
232
    phcharsN+=u8cpy(phchars, &pho_chars[0][k1]);
 
233
  }
 
234
 
 
235
  if (k2) {
 
236
    phcharsN+=u8cpy(&phchars[phcharsN], &pho_chars[1][k2]);
 
237
  }
 
238
 
 
239
  if (k3)  {
 
240
    phcharsN+=u8cpy(&phchars[phcharsN], &pho_chars[2][k3]);
 
241
  }
 
242
 
 
243
  if (k4) {
 
244
//    dbg("k4 %d\n", k4);
 
245
    if (last_number)
 
246
      phchars[phcharsN++] = k4 + '0';
 
247
    else
 
248
      phcharsN+=u8cpy(&phchars[phcharsN], &pho_chars[3][k4 * PHO_CHAR_LEN]);
 
249
  }
 
250
 
 
251
  phchars[phcharsN] = 0;
 
252
 
 
253
  return phchars;
 
254
}
 
255
 
 
256
 
 
257
char *phokey_to_str(phokey_t kk)
 
258
{
 
259
  return phokey_to_str2(kk, 0);
 
260
}
 
261
 
 
262
void str_to_all_phokey_chars(char *u8_str, char *out)
 
263
{
 
264
  out[0]=0;
 
265
 
 
266
  while (*u8_str) {
 
267
    phokey_t phos[32];
 
268
 
 
269
    int n=utf8_pho_keys(u8_str, phos);
 
270
#if 0
 
271
    utf8_putchar(u8_str);
 
272
    dbg("n %d\n", n);
 
273
#endif
 
274
    int i;
 
275
    for(i=0; i < n; i++) {
 
276
      char *pstr = phokey_to_str(phos[i]);
 
277
      strcat(out, pstr);
 
278
      if (i < n -1)
 
279
        strcat(out, " ");
 
280
    }
 
281
 
 
282
    u8_str+=utf8_sz(u8_str);
 
283
 
 
284
    if (*u8_str)
 
285
      strcat(out, " | ");
 
286
  }
 
287
}