Back to index

im-sdk  12.3.91
MakeCodeTable.c
Go to the documentation of this file.
00001 /*
00002 Copyright 1990-2001 Sun Microsystems, Inc. All Rights Reserved.
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a
00005 copy of this software and associated documentation files (the
00006 "Software"), to deal in the Software without restriction, including
00007 without limitation the rights to use, copy, modify, merge, publish,
00008 distribute, sublicense, and/or sell copies of the Software, and to
00009 permit persons to whom the Software is furnished to do so, subject to
00010 the following conditions: The above copyright notice and this
00011 permission notice shall be included in all copies or substantial
00012 portions of the Software.
00013 
00014 
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00016 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00017 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00018 IN NO EVENT SHALL THE OPEN GROUP OR SUN MICROSYSTEMS, INC. BE LIABLE
00019 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
00020 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
00021 THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE EVEN IF
00022 ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.
00023 
00024 
00025 Except as contained in this notice, the names of The Open Group and/or
00026 Sun Microsystems, Inc. shall not be used in advertising or otherwise to
00027 promote the sale, use or other dealings in this Software without prior
00028 written authorization from The Open Group and/or Sun Microsystems,
00029 Inc., as applicable.
00030 
00031 
00032 X Window System is a trademark of The Open Group
00033 
00034 OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
00035 logo, LBX, X Window System, and Xinerama are trademarks of the Open
00036 Group. All other trademarks and registered trademarks mentioned herein
00037 are the property of their respective owners. No right, title or
00038 interest in or to any trademark, service mark, logo or trade name of
00039 Sun Microsystems, Inc. or its licensors is granted.
00040 
00041 */
00042 #include <stdio.h>
00043 #include <stdlib.h>
00044 #include <string.h>
00045 #include <fcntl.h>
00046 #include "CodeTable.h"
00047 #include "UDEngine.h"
00048 
00049 #define MAXBUF              (1024 * 1024)
00050 #define MAXLEN              256
00051 #define MAXTAB              0x00018000
00052 #define OFFSET_START        1
00053 
00054 #define CODETABLE_ID "<codetable>"
00055 #define KEYTABLE_ID  "<preedit_keytable>"
00056 #define CTINFO_ID    "<codetable_info>"
00057 
00058 enum   _READING { 
00059        CODETABLE, KEYTABLE, CTINFO, OTHER 
00060 };
00061 
00062 typedef struct {
00063        char   key[12];
00064        char   *code;
00065 } key_table;
00066 
00067 char   *code_data = NULL, *p_code = NULL;        /* code table data buffer */
00068 
00069 char    name[16], locale[16], wildchar;
00070 
00071 key_table     *k_tab = NULL;
00072 table_index   tab_idx[MAXIDX];
00073 int    tablen = 0;                 /* code table length */
00074 int    max_len = 0;                /* Maximum keystroke length */
00075 
00076 int write_code_table(engine_info *im, table_index*, code_table*, int, char *, int);
00077 
00078 int make_code_table(engine_info *im, char * in_file)
00079 {
00080        FILE   *in_fp;
00081        int    fd;
00082        int    tabcomp();
00083        code_table    *c_tab = NULL;
00084        int    i, k;
00085 
00086        tablen = 0;
00087        max_len = 0;
00088 
00089        if( (in_fp = (FILE*) fopen(in_file, "r")) == NULL)  return -1;
00090 
00091        for (i = 0; i < MAXIDX; i++) {
00092               tab_idx[i].edge = tab_idx[i].used = 0;
00093               tab_idx[i].pe_text[0] = i + 0x20;
00094               for (k = 1; k < MAX_CHAR_PE; k++)
00095                      tab_idx[i].pe_text[k] = '\0';
00096        }
00097 
00098        if(k_tab == NULL) {
00099               printf("k_tab is NULL\n");
00100               k_tab = (key_table*) calloc(MAXTAB, sizeof(key_table));
00101        }
00102 
00103        if(code_data == NULL) {
00104               printf("code_data is NULL\n");
00105               code_data = (char *) calloc(MAXBUF, sizeof(char));
00106        }
00107 
00108        p_code = code_data + OFFSET_START;
00109 
00110        if(read_file(in_fp) == -1) return -1;
00111 
00112        qsort(k_tab, tablen - 1, sizeof(key_table), tabcomp);
00113 
00114        if(c_tab == NULL) {
00115               printf("c_tab is NULL\n");
00116               c_tab = (code_table *) calloc(tablen, sizeof(code_table));
00117        }
00118        generate_code_table(tab_idx, c_tab, k_tab, &tablen, code_data, &p_code);
00119        for (i = 0; i < tablen; i++)
00120               record_char_use(tab_idx, (k_tab + i)->key);
00121 
00122        for (i = 1; i < MAXIDX; i++) {
00123               if (tab_idx[i].edge < tab_idx[i-1].edge)
00124                      tab_idx[i].edge = tab_idx[i-1].edge;
00125        }
00126 
00127        write_code_table(im, tab_idx, c_tab, tablen, code_data, p_code - code_data);
00128 
00129        free(k_tab); k_tab = NULL;
00130        free(c_tab); c_tab = NULL;
00131        free(code_data); code_data = NULL;
00132 }
00133 
00134 read_file(fp)
00135 FILE   *fp;
00136 {
00137        read_text_ct(fp);
00138        fclose(fp);
00139        return 0;
00140 }
00141 
00142 is_bin_code_table(fd)
00143 int    fd;
00144 {
00145        char   header[32];
00146 
00147        read(fd, header, strlen(CODE_TABLE_HEAD));
00148 
00149        if (strcmp(header, CODE_TABLE_HEAD) == 0)
00150               return 1;
00151        lseek(fd, 0, 0);
00152        return 0;
00153 }
00154 
00155 read_bin_ct(fd)
00156 int    fd;
00157 {
00158        return -1;
00159 }
00160 
00161 read_text_ct(fp)
00162 FILE    *fp;
00163 {
00164        char   c, str[MAXLEN];
00165        unsigned char check;
00166        short  reading = OTHER;
00167        int    lineno = 0;
00168        int    i, k;
00169        char    arg[20], value[20];
00170 
00171        while (!feof(fp)) {
00172               fgets(str, MAXLEN, fp);
00173               if (feof(fp) || (str == NULL) || (strlen(str) < 1)) break;
00174               lineno++;
00175               if (str[0] == '#') {
00176                      continue;
00177               }
00178               if (strncmp(str, CTINFO_ID, 16) == 0) {
00179                      reading = CTINFO;
00180                      strcpy(name, "뷨");
00181                      strcpy(locale, "zh_CN");
00182                      wildchar = 'z';
00183                      continue;
00184               }
00185               if (strncmp(str, KEYTABLE_ID, 18) == 0) {
00186                      reading = KEYTABLE;
00187                      continue;
00188               }
00189               if (strncmp(str, CODETABLE_ID, 11) == 0) {
00190                      reading = CODETABLE;
00191                      continue;
00192               }
00193               switch (reading) {
00194               case CTINFO:
00195                      value[0] = '\0';
00196                      sscanf(str,"%s%s", arg, value);
00197                      if(!strcmp(arg, "name")) {
00198                             if(strlen(value) > 0) strcpy(name, value);
00199                             printf("name is %s\n", name);
00200                      }
00201                      else if(!strcmp(arg, "locale"))  {
00202                             if(strlen(value) > 0) strcpy(locale, value);
00203                             printf("locale is %s\n", locale);
00204                      }
00205                      else if(!strcmp(arg, "wildchar")) {
00206                             if(strlen(value) > 0) wildchar = value[0];
00207                             printf("wildchar is %c\n", wildchar);
00208                      }
00209                      break;
00210 
00211               case KEYTABLE:
00212                      if (strlen(str) != 1) {
00213                             fprintf(stderr, "Error: line %d\n", lineno);
00214                             exit(1);
00215                      }
00216                      i = idx(str[0]);
00217                      k = 0;
00218                      while ((c = getc(fp)) != EOF && c != '\n') {
00219                             if (isspace(c))
00220                                    continue;
00221                             if (k >= MAX_CHAR_PE) {
00222                                    fprintf(stderr, 
00223                                        "line %d: mapping string too long\n", 
00224                                        lineno);
00225                                    break;
00226                             }
00227                             tab_idx[i].pe_text[k++] = c;
00228                      }
00229                      break;
00230               case CODETABLE:
00231                      if( tablen >= MAXTAB ) break;
00232                      sscanf(str,"%s%s", p_code, (k_tab + tablen)->key);
00233                      check = p_code[0];
00234                      if( (check < 0x80) || (strlen((k_tab + tablen)->key) < 1) ) {
00235                             fprintf(stderr, "Codetable error, line %d , ignored.\n", lineno);
00236                             break;
00237                      }
00238                      (k_tab + tablen)->code = p_code;
00239                      p_code += strlen(p_code) + 1;
00240                      if (strlen((k_tab + tablen)->key) > max_len)
00241                             max_len = strlen((k_tab + tablen)->key);
00242                      tablen++;
00243                      break;
00244               default:
00245                      fprintf(stderr, "File format error, line %d .\n", lineno);
00246                      break;
00247               }
00248        }
00249 }
00250 
00251 tabcomp(ti1, ti2)
00252 key_table *ti1, *ti2;
00253 {
00254        int    r;
00255 
00256        if (r = strcmp(ti1->key, ti2->key))
00257               return r;
00258        return strcmp(ti1->code, ti2->code);
00259 }
00260 
00261 
00262 generate_code_table(tab_idx, c_tab, k_tab, tablen, code_data, p_code)
00263 table_index   *tab_idx;
00264 code_table    *c_tab;
00265 key_table     *k_tab;
00266 int           *tablen;
00267 char          *code_data;
00268 char          **p_code;
00269 {
00270        int    i, size;
00271        short  *l, search_for();
00272        char   *p, *str;
00273        char   fc;           /* first char */
00274 
00275        size = *tablen;
00276 
00277        /* Make code table */
00278        fc = k_tab->key[0];
00279        tab_idx[idx(fc)].edge = 0;
00280        tab_idx[idx(fc)].used = 0;
00281        for (i = 0; i < size; i++) {
00282               if (fc != (k_tab + i)->key[0]) {
00283                      tab_idx[idx(fc)].edge = i;
00284                      fc = (k_tab + i)->key[0];
00285               }
00286               c_tab[i].key = encoding((k_tab + i)->key, code_data, p_code);
00287               c_tab[i].code = (k_tab + i)->code - code_data;
00288        }
00289        tab_idx[idx(fc)].edge = i;
00290 }
00291 
00292 
00293 short
00294 search_for(code, code_data, c_tab, tablen)
00295 char          *code, *code_data;
00296 code_table    *c_tab;
00297 int           *tablen;
00298 {
00299        short  i;
00300 
00301        for (i = 0; i < *tablen; i++) {
00302               if (strcmp((char *) (c_tab[i].code + code_data), code) == 0) {
00303                      return i;
00304               }
00305        }
00306        c_tab[i].code = c_tab[i-1].code + 
00307            strlen((char *) (c_tab[i - 1].code + code_data)) + 1;
00308        strcpy((char *)(c_tab[i].code + code_data), code);
00309        *tablen += strlen(code) + 1;
00310        return i;
00311 }
00312 
00313 
00314 int write_code_table(im, tab_idx, c_tab, tablen, code_data, data_len)
00315 engine_info   *im;
00316 table_index   *tab_idx;
00317 code_table    *c_tab;
00318 int           tablen;
00319 char          *code_data;
00320 int           data_len;
00321 {
00322        strcpy(im->name, name);
00323        strcpy(im->locale, locale);
00324        im->wild_char = wildchar;
00325        memcpy(im->tab_idx, tab_idx, sizeof(table_index) * MAXIDX);
00326        im->c_tab = (code_table *) malloc(sizeof(code_table) * tablen);
00327        memcpy(im->c_tab, c_tab, sizeof(code_table) * tablen);
00328        im->data = (char *) malloc(data_len);
00329        memcpy(im->data, code_data, data_len);
00330 }
00331 
00332 
00333 encoding(str, code_data, p_code)
00334 char   str[];
00335 char   *code_data;
00336 char   **p_code;
00337 {
00338        int    code = 0;
00339        int    n;
00340 
00341        if (strlen(str) <= 5) {
00342               for (n = 1; str[n] != '\0'; n++) {
00343                      code += str[n] << (7 * (4 - n));
00344               }
00345        } else {
00346               strcpy(*p_code, (char *)&str[1]);
00347               code = KEYSTR_MASK + *p_code - code_data;
00348               *p_code += strlen(str);
00349        }
00350        return code;
00351 }
00352 
00353 
00354 record_char_use(tab_idx, str)
00355 table_index   *tab_idx;
00356 char          *str;
00357 {
00358        while (*str != '\0') {
00359               tab_idx[idx(*str)].used = 1;
00360               str++;
00361        }
00362 }
00363