~ubuntu-branches/ubuntu/trusty/hime/trusty

« back to all changes in this revision

Viewing changes to src/tsin-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) 1995-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 "tsin.h"
 
21
#include "gtab.h"
 
22
#include "gst.h"
 
23
#include "lang.h"
 
24
 
 
25
int hashidx[TSIN_HASH_N];
 
26
//static int *phidx;
 
27
static FILE *fp_phidx;
 
28
FILE *fph;
 
29
int phcount;
 
30
int ph_key_sz; // bytes
 
31
gboolean tsin_is_gtab;
 
32
static int tsin_hash_shift;
 
33
 
 
34
#define PHIDX_SKIP  (sizeof(phcount) + sizeof(hashidx))
 
35
 
 
36
char *current_tsin_fname;
 
37
int ts_gtabN;
 
38
//static int *ts_gtab_hash;
 
39
#define HASHN 256
 
40
 
 
41
static int a_phcount;
 
42
 
 
43
void get_hime_user_or_sys_fname(char *name, char fname[]);
 
44
 
 
45
void load_tsin_db0(char *infname, gboolean is_gtab_i)
 
46
{
 
47
  char tsidxfname[512];
 
48
//  dbg("cur %s %s\n", infname, current_tsin_fname);
 
49
 
 
50
  if (current_tsin_fname && !strcmp(current_tsin_fname, infname))
 
51
    return;
 
52
 
 
53
  strcpy(tsidxfname, infname);
 
54
  strcat(tsidxfname, ".idx");
 
55
 
 
56
//  dbg("tsidxfname %s\n", tsidxfname);
 
57
 
 
58
  FILE *fr;
 
59
 
 
60
  if ((fr=fopen(tsidxfname,"rb+"))==NULL) {
 
61
    p_err("load_tsin_db0 A Cannot open '%s'\n", tsidxfname);
 
62
  }
 
63
 
 
64
 
 
65
  fread(&phcount,4,1,fr);
 
66
#if     0
 
67
  printf("phcount:%d\n",phcount);
 
68
#endif
 
69
  a_phcount=phcount+256;
 
70
  fread(&hashidx,1,sizeof(hashidx),fr);
 
71
 
 
72
  fp_phidx = fr;
 
73
 
 
74
  if (fph)
 
75
    fclose(fph);
 
76
 
 
77
  dbg("tsfname: %s\n", infname);
 
78
 
 
79
  if ((fph=fopen(infname,"rb+"))==NULL)
 
80
    p_err("load_tsin_db0 B Cannot open '%s'", infname);
 
81
 
 
82
  free(current_tsin_fname);
 
83
  current_tsin_fname = strdup(infname);
 
84
 
 
85
  if (is_gtab_i) {
 
86
    TSIN_GTAB_HEAD head;
 
87
    fread(&head, sizeof(head), 1, fph);
 
88
    if (head.keybits*head.maxkey > 32) {
 
89
      ph_key_sz = 8;
 
90
      tsin_hash_shift = TSIN_HASH_SHIFT_64;
 
91
    }
 
92
    else {
 
93
      ph_key_sz = 4;
 
94
      tsin_hash_shift = TSIN_HASH_SHIFT_32;
 
95
    }
 
96
  } else {
 
97
    ph_key_sz = 2;
 
98
    tsin_hash_shift = TSIN_HASH_SHIFT;
 
99
  }
 
100
  tsin_is_gtab = is_gtab_i;
 
101
}
 
102
 
 
103
 
 
104
 
 
105
 
 
106
#if USE_TSIN
 
107
void free_tsin()
 
108
{
 
109
  free(current_tsin_fname); current_tsin_fname=NULL;
 
110
 
 
111
  if (fph) {
 
112
    fclose(fph); fph = NULL;
 
113
  }
 
114
 
 
115
  if (fp_phidx) {
 
116
    fclose(fp_phidx); fp_phidx=NULL;
 
117
  }
 
118
}
 
119
#endif
 
120
 
 
121
#if USE_TSIN
 
122
void load_tsin_db()
 
123
{
 
124
  char tsfname[512];
 
125
  char *fname = tsin32_f;
 
126
 
 
127
  get_hime_user_or_sys_fname(fname, tsfname);
 
128
  load_tsin_db0(tsfname, FALSE);
 
129
}
 
130
#endif
 
131
 
 
132
static void seek_fp_phidx(int i)
 
133
{
 
134
  fseek(fp_phidx, PHIDX_SKIP + i*sizeof(int), SEEK_SET);
 
135
}
 
136
 
 
137
void reload_tsin_db()
 
138
{
 
139
  char tt[512];
 
140
  if (!current_tsin_fname)
 
141
    return;
 
142
 
 
143
  strcpy(tt, current_tsin_fname);
 
144
  free(current_tsin_fname); current_tsin_fname = NULL;
 
145
  load_tsin_db0(tt, tsin_is_gtab);
 
146
}
 
147
 
 
148
inline static int get_phidx(int i)
 
149
{
 
150
  seek_fp_phidx(i);
 
151
  int t;
 
152
  fread(&t, sizeof(int), 1, fp_phidx);
 
153
 
 
154
  if (tsin_is_gtab)
 
155
    t += sizeof(TSIN_GTAB_HEAD);
 
156
 
 
157
  return t;
 
158
}
 
159
 
 
160
 
 
161
static inline int phokey_t_seq16(phokey_t *a, phokey_t *b, int len)
 
162
{
 
163
  int i;
 
164
 
 
165
  for (i=0;i<len;i++) {
 
166
    if (a[i] > b[i]) return 1;
 
167
    else
 
168
    if (a[i] < b[i]) return -1;
 
169
  }
 
170
 
 
171
  return 0;
 
172
}
 
173
 
 
174
 
 
175
static inline int phokey_t_seq32(u_int *a, u_int *b, int len)
 
176
{
 
177
  int i;
 
178
 
 
179
  for (i=0;i<len;i++) {
 
180
    if (a[i] > b[i]) return 1;
 
181
    else
 
182
    if (a[i] < b[i]) return -1;
 
183
  }
 
184
 
 
185
  return 0;
 
186
}
 
187
 
 
188
 
 
189
static inline int phokey_t_seq64(u_int64_t *a, u_int64_t *b, int len)
 
190
{
 
191
  int i;
 
192
 
 
193
  for (i=0;i<len;i++) {
 
194
    if (a[i] > b[i]) return 1;
 
195
    else
 
196
    if (a[i] < b[i]) return -1;
 
197
  }
 
198
 
 
199
  return 0;
 
200
}
 
201
 
 
202
 
 
203
static int phokey_t_seq(void *a, void *b, int len)
 
204
{
 
205
  if (ph_key_sz==2)
 
206
    return phokey_t_seq16((phokey_t *)a, (phokey_t *)b, len);
 
207
  if (ph_key_sz==4)
 
208
    return phokey_t_seq32((u_int *)a, (u_int *)b, len);
 
209
  if (ph_key_sz==8)
 
210
    return phokey_t_seq64((u_int64_t*)a, (u_int64_t*)b, len);
 
211
  return 0;
 
212
}
 
213
 
 
214
 
 
215
static int phseq(u_char *a, u_char *b)
 
216
{
 
217
  u_char lena, lenb, mlen;
 
218
 
 
219
  lena=*(a++); lenb=*(b++);
 
220
  a+=sizeof(usecount_t); b+=sizeof(usecount_t);   // skip usecount
 
221
 
 
222
  mlen=Min(lena,lenb);
 
223
  u_int64_t ka[MAX_PHRASE_LEN], kb[MAX_PHRASE_LEN];
 
224
 
 
225
  memcpy(ka, a, ph_key_sz * mlen);
 
226
  memcpy(kb, b, ph_key_sz * mlen);
 
227
 
 
228
  int d = phokey_t_seq(a, b, mlen);
 
229
  if (d)
 
230
    return d;
 
231
 
 
232
  if (lena > lenb) return 1;
 
233
  if (lena < lenb) return -1;
 
234
  return 0;
 
235
}
 
236
 
 
237
void inc_dec_tsin_use_count(void *pho, char *ch, int N);
 
238
 
 
239
static gboolean saved_phrase;
 
240
 
 
241
gboolean save_phrase_to_db(void *phkeys, char *utf8str, int len, usecount_t usecount)
 
242
{
 
243
  int mid, ord = 0, ph_ofs, hashno;
 
244
  u_char tbuf[MAX_PHRASE_LEN*(sizeof(u_int64_t)+CH_SZ) + 1 + sizeof(usecount_t)],
 
245
         sbuf[MAX_PHRASE_LEN*(sizeof(u_int64_t)+CH_SZ) + 1 + sizeof(usecount_t)];
 
246
 
 
247
  saved_phrase = TRUE;
 
248
 
 
249
  tbuf[0]=len;
 
250
  memcpy(&tbuf[1], &usecount, sizeof(usecount));  // usecount
 
251
  int tlen = utf8_tlen(utf8str, len);
 
252
#if 0
 
253
  dbg("tlen %d  '", tlen);
 
254
  for(i=0; i < tlen; i++)
 
255
    putchar(utf8str[i]);
 
256
  dbg("'\n");
 
257
#endif
 
258
 
 
259
  dbg("save_phrase_to_db '%s'  tlen:%d\n", utf8str, tlen);
 
260
 
 
261
  memcpy(&tbuf[1 + sizeof(usecount_t)], phkeys, ph_key_sz * len);
 
262
  memcpy(&tbuf[ph_key_sz*len + 1 + sizeof(usecount_t)], utf8str, tlen);
 
263
 
 
264
  if (ph_key_sz==2)
 
265
    hashno= *((phokey_t *)phkeys) >> TSIN_HASH_SHIFT;
 
266
  else if (ph_key_sz==4)
 
267
    hashno= *((u_int *)phkeys) >> TSIN_HASH_SHIFT_32;
 
268
  else
 
269
    hashno= *((u_int64_t *)phkeys) >> TSIN_HASH_SHIFT_64;
 
270
 
 
271
//  dbg("hashno %d\n", hashno);
 
272
 
 
273
  if (hashno >= TSIN_HASH_N)
 
274
    return FALSE;
 
275
 
 
276
  for(mid=hashidx[hashno]; mid<hashidx[hashno+1]; mid++) {
 
277
    ph_ofs=get_phidx(mid);
 
278
 
 
279
    fseek(fph, ph_ofs, SEEK_SET);
 
280
    fread(sbuf,1,1,fph);
 
281
    fread(&sbuf[1], sizeof(usecount_t), 1, fph); // use count
 
282
    fread(&sbuf[1+sizeof(usecount_t)], 1, (ph_key_sz + CH_SZ) * sbuf[0], fph);
 
283
    if ((ord=phseq(sbuf,tbuf)) > 0)
 
284
      break;
 
285
 
 
286
    if (!ord && !memcmp(&sbuf[sbuf[0]*ph_key_sz+1+sizeof(usecount_t)], utf8str, tlen)) {
 
287
//    bell();
 
288
      dbg("Phrase already exists\n");
 
289
      inc_dec_tsin_use_count(phkeys, utf8str, len);
 
290
      return FALSE;
 
291
    }
 
292
  }
 
293
 
 
294
  int wN = phcount - mid;
 
295
 
 
296
//  dbg("wN %d  phcount:%d mid:%d\n", wN, phcount, mid);
 
297
 
 
298
  if (wN > 0) {
 
299
    int *phidx = tmalloc(int, wN);
 
300
    seek_fp_phidx(mid);
 
301
    fread(phidx, sizeof(int), wN, fp_phidx);
 
302
    seek_fp_phidx(mid+1);
 
303
    fwrite(phidx, sizeof(int), wN, fp_phidx);
 
304
    free(phidx);
 
305
  }
 
306
 
 
307
  fseek(fph,0,SEEK_END);
 
308
 
 
309
  ph_ofs=ftell(fph);
 
310
  if (tsin_is_gtab)
 
311
    ph_ofs -= sizeof(TSIN_GTAB_HEAD);
 
312
 
 
313
//  dbg("ph_ofs %d  ph_key_sz:%d\n", ph_ofs, ph_key_sz);
 
314
  seek_fp_phidx(mid);
 
315
  fwrite(&ph_ofs, sizeof(int), 1, fp_phidx);
 
316
  phcount++;
 
317
 
 
318
  fwrite(tbuf, 1, ph_key_sz*len + tlen + 1+ sizeof(usecount_t), fph);
 
319
  fflush(fph);
 
320
 
 
321
  if (hashidx[hashno]>mid)
 
322
    hashidx[hashno]=mid;
 
323
 
 
324
  for(hashno++; hashno<TSIN_HASH_N; hashno++)
 
325
    hashidx[hashno]++;
 
326
 
 
327
  rewind(fp_phidx);
 
328
  fwrite(&phcount, sizeof(phcount), 1, fp_phidx);
 
329
  fwrite(&hashidx,sizeof(hashidx),1, fp_phidx);
 
330
  fflush(fp_phidx);
 
331
 
 
332
//  dbg("ofs %d\n", get_phidx(mid));
 
333
 
 
334
  return TRUE;
 
335
}
 
336
 
 
337
 
 
338
#include <sys/stat.h>
 
339
 
 
340
 
 
341
void load_tsin_entry0(char *len, usecount_t *usecount, void *pho, u_char *ch)
 
342
{
 
343
  *usecount = 0;
 
344
  *len = 0;
 
345
  fread(len, 1, 1, fph);
 
346
 
 
347
  if (*len > MAX_PHRASE_LEN || *len <= 0) {
 
348
    dbg("err: tsin db changed reload\n");
 
349
    reload_tsin_db(); // probably db changed, reload;
 
350
    *len = 0;
 
351
    return;
 
352
  }
 
353
 
 
354
  fread(usecount, sizeof(usecount_t), 1, fph); // use count
 
355
  fread(pho, ph_key_sz, (int)(*len), fph);
 
356
  if (ch) {
 
357
    fread(ch, CH_SZ, (int)(*len), fph);
 
358
    int tlen = utf8_tlen((char *)ch, *len);
 
359
    ch[tlen]=0;
 
360
  }
 
361
}
 
362
 
 
363
 
 
364
void load_tsin_entry(int idx, char *len, usecount_t *usecount, void *pho, u_char *ch)
 
365
{
 
366
  *usecount = 0;
 
367
 
 
368
 
 
369
  if (idx >= phcount) {
 
370
    reload_tsin_db(); // probably db changed, reload;
 
371
    *len = 0;
 
372
    return;
 
373
  }
 
374
 
 
375
  int ph_ofs=get_phidx(idx);
 
376
//  dbg("idx %d:%d\n", idx, ph_ofs);
 
377
 
 
378
  fseek(fph, ph_ofs , SEEK_SET);
 
379
  load_tsin_entry0(len, usecount, pho, ch);
 
380
}
 
381
 
 
382
// tone_mask : 1 -> pho has tone
 
383
void mask_tone(phokey_t *pho, int plen, char *tone_mask)
 
384
{
 
385
  int i;
 
386
//  dbg("mask_tone\n");
 
387
  if (!tone_mask)
 
388
    return;
 
389
 
 
390
  for(i=0; i < plen; i++) {
 
391
   if (!tone_mask[i])
 
392
    pho[i] &= (~7);
 
393
  }
 
394
}
 
395
 
 
396
 
 
397
// ***  r_sti<=  range  < r_edi
 
398
gboolean tsin_seek(void *pho, int plen, int *r_sti, int *r_edi, char *tone_mask)
 
399
{
 
400
  int mid, cmp;
 
401
  u_int64_t ss[MAX_PHRASE_LEN], stk[MAX_PHRASE_LEN];
 
402
  char len;
 
403
  usecount_t usecount;
 
404
  int hashi;
 
405
 
 
406
#if 0
 
407
  dbg("tsin_seek %d\n", plen);
 
408
#endif
 
409
 
 
410
#if 0
 
411
  if (tone_mask)
 
412
    mask_tone((phokey_t *)pho, plen, tone_mask);
 
413
#endif
 
414
 
 
415
  if (ph_key_sz==2)
 
416
    hashi= *((phokey_t *)pho) >> TSIN_HASH_SHIFT;
 
417
  else if (ph_key_sz==4)
 
418
    hashi= *((u_int *)pho) >> TSIN_HASH_SHIFT_32;
 
419
  else
 
420
    hashi= *((u_int64_t *)pho) >> TSIN_HASH_SHIFT_64;
 
421
 
 
422
  if (hashi >= TSIN_HASH_N) {
 
423
//    dbg("hashi >= TSIN_HASH_N\n");
 
424
    return FALSE;
 
425
  }
 
426
 
 
427
  int top=hashidx[hashi];
 
428
  int bot=hashidx[hashi+1];
 
429
 
 
430
  if (top>=phcount) {
 
431
//    dbg("top>=phcount\n");
 
432
    return FALSE;
 
433
  }
 
434
 
 
435
  while (top <= bot) {
 
436
    mid=(top+bot)/ 2;
 
437
    load_tsin_entry(mid, &len, &usecount, ss, NULL);
 
438
 
 
439
    u_char mlen;
 
440
    if (len > plen)
 
441
      mlen=plen;
 
442
    else
 
443
      mlen=len;
 
444
 
 
445
//    prphs(ss, mlen);
 
446
//    mask_tone((phokey_t *)ss, mlen, tone_mask);
 
447
 
 
448
#if DBG || 0
 
449
    int j;
 
450
    dbg("> ");
 
451
    prphs(ss, len);
 
452
    dbg("\n");
 
453
#endif
 
454
 
 
455
    cmp=phokey_t_seq(ss, pho, mlen);
 
456
 
 
457
    if (!cmp && len < plen)
 
458
      cmp=-2;
 
459
 
 
460
    if (cmp>0)
 
461
      bot=mid-1;
 
462
    else
 
463
    if (cmp<0)
 
464
      top=mid+1;
 
465
    else
 
466
      break;
 
467
  }
 
468
 
 
469
  if (cmp && !tone_mask) {
 
470
//    dbg("no match %d\n", cmp);
 
471
    return FALSE;
 
472
  }
 
473
 
 
474
//  dbg("<--\n");
 
475
  // seek to the first match because binary search is used
 
476
  gboolean found=FALSE;
 
477
 
 
478
  int sti;
 
479
  for(sti = mid; sti>=0; sti--) {
 
480
    load_tsin_entry(sti, &len, &usecount, stk, NULL);
 
481
 
 
482
    u_char mlen;
 
483
    if (len > plen)
 
484
      mlen=plen;
 
485
    else
 
486
      mlen=len;
 
487
#if 0
 
488
    prphs(stk, len);
 
489
#endif
 
490
    mask_tone((phokey_t *)stk, mlen, tone_mask);
 
491
 
 
492
    int v = phokey_t_seq(stk, pho, plen);
 
493
    if (!v)
 
494
      found = TRUE;
 
495
 
 
496
#if 0
 
497
    int j;
 
498
    dbg("%d] %d*> ", sti, mlen);
 
499
    prphs(stk, len);
 
500
    dbg(" v:%d\n", v);
 
501
#endif
 
502
 
 
503
    if ((!tone_mask && !v && len>=plen) ||
 
504
        ((tone_mask && v>0) || (!v && len >= plen)))
 
505
      continue;
 
506
    break;
 
507
  }
 
508
  sti++;
 
509
 
 
510
  // seek to the tail
 
511
 
 
512
  if (tone_mask) {
 
513
    int top=hashidx[hashi];
 
514
    int bot=hashidx[hashi+1];
 
515
 
 
516
    if (top>=phcount) {
 
517
  //    dbg("top>=phcount\n");
 
518
      return FALSE;
 
519
    }
 
520
 
 
521
    phokey_t tpho[MAX_PHRASE_LEN];
 
522
 
 
523
    int i;
 
524
    for(i=0; i < plen; i++)
 
525
      tpho[i]=((phokey_t*)pho)[i] | 7;
 
526
 
 
527
    while (top <= bot) {
 
528
      mid=(top+bot)/ 2;
 
529
      load_tsin_entry(mid, &len, &usecount, ss, NULL);
 
530
 
 
531
      u_char mlen;
 
532
      if (len > plen)
 
533
        mlen=plen;
 
534
      else
 
535
        mlen=len;
 
536
 
 
537
  //    prphs(ss, mlen);
 
538
 
 
539
#if DBG || 0
 
540
      int j;
 
541
      dbg("> ");
 
542
      prphs(ss, len);
 
543
      dbg("\n");
 
544
#endif
 
545
 
 
546
      cmp=phokey_t_seq(ss, tpho, mlen);
 
547
 
 
548
      if (!cmp && len < plen)
 
549
        cmp=-2;
 
550
 
 
551
      if (cmp>0)
 
552
        bot=mid-1;
 
553
      else
 
554
      if (cmp<0)
 
555
        top=mid+1;
 
556
      else
 
557
        break;
 
558
    }
 
559
  }
 
560
 
 
561
  int edi;
 
562
  for(edi = mid; edi < phcount; edi++) {
 
563
    load_tsin_entry(edi, &len, &usecount, stk, NULL);
 
564
 
 
565
    u_char mlen;
 
566
    if (len > plen)
 
567
      mlen=plen;
 
568
    else
 
569
      mlen=len;
 
570
#if 0
 
571
    prphs(stk, len);
 
572
#endif
 
573
    mask_tone((phokey_t *)stk, mlen, tone_mask);
 
574
 
 
575
    int v = phokey_t_seq(stk, pho, plen);
 
576
    if (!v)
 
577
      found = TRUE;
 
578
#if 0
 
579
    dbg("edi%d -> ", edi);
 
580
    prphs(stk, len);
 
581
    dbg(" v:%d\n", v);
 
582
#endif
 
583
 
 
584
    if ((!tone_mask && !v && len >= plen)
 
585
      || ((tone_mask && v<0) || (!v && len >= plen)))
 
586
      continue;
 
587
    break;
 
588
  }
 
589
 
 
590
#if 0
 
591
  dbg("sti%d edi:%d found:%d\n", sti, edi, found);
 
592
#endif
 
593
 
 
594
  *r_sti = sti;
 
595
  *r_edi = edi;
 
596
 
 
597
  return edi > sti;
 
598
}
 
599
 
 
600
void inc_dec_tsin_use_count(void *pho, char *ch, int N)
 
601
{
 
602
  int sti, edi;
 
603
 
 
604
//  dbg("inc_dec_tsin_use_count '%s'\n", ch);
 
605
 
 
606
  if (!tsin_seek(pho, N, &sti, &edi, NULL))
 
607
    return;
 
608
 
 
609
  int idx;
 
610
 
 
611
#if 0
 
612
  int tlen = strlen(ch);
 
613
 
 
614
  dbg("otlen %d  ", tlen);
 
615
  int i;
 
616
  for(i=0; i < tlen; i++)
 
617
    putchar(ch[i]);
 
618
  puts("");
 
619
#endif
 
620
 
 
621
  for(idx=sti; idx < edi; idx++) {
 
622
    char len;
 
623
    usecount_t usecount, n_usecount;
 
624
    u_int64_t phi[MAX_PHRASE_LEN];
 
625
    char stch[MAX_PHRASE_LEN * CH_SZ * 2];
 
626
 
 
627
    load_tsin_entry(idx, &len, &usecount, phi, (u_char *)stch);
 
628
    n_usecount = usecount;
 
629
 
 
630
    if (len!=N || phokey_t_seq(phi, pho, N))
 
631
      break;
 
632
#if 0
 
633
    for(i=0; i < tlen; i++)
 
634
      putchar(stch[i]);
 
635
    dbg(" ppp\n");
 
636
#endif
 
637
 
 
638
//      dbg("stch %s\n", stch);
 
639
    if (strcmp(stch, ch))
 
640
      continue;
 
641
#if 0
 
642
    dbg("found match\n");
 
643
#endif
 
644
    int ph_ofs=get_phidx(idx);
 
645
 
 
646
    fseek(fph, ph_ofs + 1, SEEK_SET);
 
647
 
 
648
    if (usecount < 0x3fffffff)
 
649
      n_usecount++;
 
650
 
 
651
    if (n_usecount != usecount) {
 
652
      fwrite(&n_usecount, sizeof(usecount_t), 1, fph); // use count
 
653
      fflush(fph);
 
654
    }
 
655
  }
 
656
}