/* * Copyright (C) 1994 Edward Der-Hua Liu, Hsin-Chu, Taiwan */ #include "big5con.h" static int *idx; /* sorted index pointing to the phrase */ static u_char *ph; /* key string, phrase string : C style */ static u_short kmap[128]; /* hash, point to idx array */ /* 0xffff if the key is undefined */ /* 65535 phrases can be defined */ static int phn = 0; extern char *tabfname[]; static qcmp_voc(int *a, int *b) { return strcmp(&ph[*a], &ph[*b]); } void InitVocBox(int usenow) { FILE *fp; char tt[1024]; int i, j; int mfree; int phsize; int len; char *p, *q; char *vocbox_fname = tabfname[11]; if (ph) { gotox(0); xprintf(" ¡iµü®w¡j"); return; } if ((fp = fopen(vocbox_fname, "r")) == NULL) { error("Cannot open voxbox file %s\n", vocbox_fname); return; } while (!feof(fp)) { fgets(tt, sizeof(tt), fp); phn++; } phn++; if (!(idx = (int *)malloc(phn * sizeof(u_char *)))) { error("phrase.c: malloc error"); return; } if (!(ph = (u_char *) malloc(phsize = 1024))) { error("phrase.c: malloc error"); return; } mfree = phn = 0; fseek(fp, 0, 0); while (!feof(fp)) { fgets(tt, sizeof(tt), fp); p = tt; len = strlen(tt); if (len && tt[len - 1] == '\n') tt[len - 1] = 0; if (tt[0] == '#') continue; while (*p == 9 || *p == ' ') p++; if (!*p) continue; q = p; while (*q != 9 && *q != ' ' && *q) q++; if (!*q) continue; len = q - p + 1; /* must include \000 */ if (len >= phsize - mfree) { phsize += 1024; if ((ph = (char *)realloc(ph, phsize)) == NULL) { error("phrase.c: realloc err"); return; } } *(q++) = 0; strcpy(&ph[mfree], p); idx[phn++] = mfree; mfree += len; while (*q == 9 || *q == ' ') q++; if (*q == '\n') *q = 0; len = strlen(q); if (*q && *(q + len - 1) == 13) { len--; *(q + len) = 0; } if (len >= phsize - mfree) { phsize += 1024; if ((ph = (char *)realloc(ph, phsize)) == NULL) { error("phrase.c: realloc err"); return; } } strcpy(&ph[mfree], q); mfree += len + 1; } qsort(idx, phn, sizeof(idx[0]), qcmp_voc); fclose(fp); { char d[128]; bzero(d, sizeof(d)); for (i = 0; i < 128; i++) kmap[i] = 0xffff; for (i = 0; i < phn; i++) { /* simple hash */ j = ph[idx[i]]; #if 0 printf("%s %s\n", &ph[idx[i]], &ph[idx[i]] + strlen(&ph[idx[i]]) + 1); #endif /* 0 */ if (!d[j]) { kmap[j] = i; d[j] = 1; } } kmap[127] = phn; for (i = 126; i >= 0; i--) if (kmap[i] == 0xffff) kmap[i] = kmap[i + 1]; } if (usenow) { gotox(0); xprintf("¡iµü®w¡j"); } } /* InitPhrase */ static u_char inch[40]; static int cin; static int pg_idx, mic; void ClrInArea() { int i; gotox(InAreaX); for (i = 0; i < cin + 1; i++) xprintf(" "); mic = cin = 0; } void DispInputArea() { int f, i; extern char fullchar[]; gotox(InAreaX); for (i = 0; i < cin; i++) { f = (int)(inch[i] - ' ') << 1; xprintf("%c%c", fullchar[f], fullchar[f + 1]); } xprintf(" "); } feedkey_vocbox(int key) { int i, j; extern int cursor_x; switch (key) { case VK_Escape: if (cin) { ClrSelArea(); ClrInArea(); return 1; } else return 0; case VK_BackSpace: case VK_Delete: mic = 0; if (cin > 0) { cin--; break; } else return 0; case ' ': if (cin > 0) { int s_h, e_h, cou, ic, xw; char *ss, *tt, vv[512]; pg_idx = 0; inch[cin] = 0; s_h = kmap[inch[0]]; e_h = kmap[inch[0] + 1]; for (i = s_h; i < e_h; i++) if (!strcmp(&ph[idx[i]], inch)) break; if (i == e_h) { bell(); return 1; } if (i == phn - 1 || strcmp(&ph[idx[i + 1]], inch)) { putstr(&ph[idx[i]] + strlen(&ph[idx[i]]) + 1); ClrInArea(); cin = 0; return 1; } ic = 0; pg_idx = i; gotox(SelAreaX + 1); while (i < e_h && cursor_x < 40 + SelAreaX && ic < 9 && !strcmp(ss = &ph[idx[i]], inch)) { tt = ss + strlen(ss) + 1; strcpy(vv, tt); vv[6] = 0; i++; ic++; xprintf("%d%s ", ic, vv); } mic = ic; return 1; } return 0; default: if (key < ' ' || key > 0x7e) return 0; if (mic) { i = key - '1'; if (i < 0 || i >= mic) return 0; putstr(&ph[idx[pg_idx + i]] + strlen(&ph[idx[pg_idx + i]]) + 1); mic = 0; ClrSelArea(); ClrInArea(); return 1; } if (cin < 14) inch[cin++] = key; } DispInputArea(); return 1; }