Back to index

im-sdk  12.3.91
txt2bin.c
Go to the documentation of this file.
00001 /*
00002   Copyright 2002-2003 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 <ctype.h>
00043 #include <stdio.h>
00044 #include <string.h>
00045 #include <stdlib.h>
00046 #include <unistd.h>
00047 #include "codetable.h"
00048 #include "ctfile.h"
00049 #include "encode.h"
00050 
00051 #define MAX_LINE_LEN 256
00052 
00053 typedef struct _dynNode {
00054   unsigned char key;        /* the input key */
00055   char     *hzptr;          /* HZ strings */
00056   struct _dynNode *next;    /* next node in the same level */
00057   struct _dynNode *son;     /* next node down one level */
00058 } dynNode;
00059 
00060 static dynNode rootNode = {
00061   '\0', NULL, (struct _dynNode *)NULL, (struct _dynNode *)NULL
00062 };
00063 
00064 static dynNode *root = &rootNode;  /* root pointer to the dynNode */
00065 
00066 CodeTableStruct hzCodeTable;
00067 
00068 tableNode *nodeList;        /* all Nodes will be linearized to put here */
00069 unsigned char *hzList;             /* all HZ codes will be put here */
00070 unsigned  int pNodeList;    /* pointer to Node List */
00071 unsigned  int pHZList;             /* pointer to HZ List */
00072 
00073 static int totalHZbytes = 0;       /* total bytes of HZs */
00074 static int totalTableNode = 1;     /* total # of Node nodes (including root) */
00075 
00076 int lineno = 0;
00077 unsigned int clen = 0;
00078 
00079 char comment[MAX_COMMENT_LEN];
00080 keyPrompt keyprompt[MAX_USEDCODES_NUM];
00081 functionKey functionkey[MAX_FUNCTIONKEY_NUM];
00082 
00083 /*
00084  * When we read the file line by line, keys-HZs mapping are inserted
00085  * into the dynNode.  After all lines are finished, the dynNode is
00086  * reorganized (optimized and linearized) into a static tableNode structures,
00087  *
00088  * Phrase (string of multiple hanzi) is embedded into hanzi strings.
00089  * A phrase is start with 2 bytes: (1, n), where n is the length
00090  * of the phrase in byte.  { The tag (0, n) is not good for strcpy, etc. }
00091  */
00092 
00093 typedef struct _str_int {
00094   char  *string;
00095   int   value;
00096 } string_value_pair;
00097 
00098 string_value_pair selectkeymode_str_val[] = {
00099   { NUMBER_MODE_STR, NUMBER_MODE },
00100   { LOWER_MODE_STR,  LOWER_MODE },
00101   { UPPER_MODE_STR,  UPPER_MODE },
00102   { NULL,            NUMBER_MODE }
00103 };
00104 
00105 int str2val(string_value_pair *str_val, char *str)
00106 {
00107   while (str_val->string) {
00108     /*
00109       printf("%d: %s\n", str_val->value, str_val->string);
00110     */
00111     if (!strncasecmp (str_val->string, str, strlen(str_val->string)))
00112       return (str_val->value);
00113     str_val++;
00114   }
00115   return (str_val->value);
00116 }
00117 
00118 char *val2str(string_value_pair *str_val, int value)
00119 {
00120   while (str_val->string) {
00121     if (str_val->value == value)
00122       return (str_val->string);
00123     str_val++;
00124   }
00125   return (str_val->string);
00126 }
00127 
00128 char *skip_space(char *s)
00129 {
00130   while (*s && (*s==' ' || *s=='\t')) s++;
00131   return s;
00132 }
00133 
00134 char *to_space(char *s)
00135 {
00136   while (*s && !isspace(*s)) s++;
00137   return s;
00138 }
00139 
00140 /* convert string like "^A" to integrate */
00141 int convert_octnum(buf)
00142      char buf[];
00143 {
00144   register char *p1 = buf, *p2 = buf;
00145   int bCtrlStatus = 0;
00146 
00147   while (*p1) {
00148     if (isspace(*p1) || (*p1&0x80)) {   
00149       p1++;
00150       continue;
00151     }
00152     if (*p1 == '^') {
00153       bCtrlStatus = 1;
00154       p1++;
00155       continue;
00156     }
00157     if (bCtrlStatus) {
00158       /*
00159        printf("Ctrl: %c, upper(%c): %c, 0x%x, 0x%x\n",
00160        *p1, *p1, toupper(*p1),
00161        toupper(*p1), toupper(*p1)|0x80); 
00162       */
00163       if (*p1 >= 'a' && *p1 <= 'z') {
00164        *p2++ = toupper(*p1) | 0x80;
00165       } else if (*p1 >= 'A' && *p1 <= 'Z') {
00166        *p2++ = *p1 | 0x80;
00167       } else if (index(",/;'[]-=", *p1)) {
00168        *p2++ = *p1 | 0x80;
00169       } else if (*p1 == '?') {
00170        *p2++ = '/' | 0x80;
00171       } else if (*p1 == '<') {
00172        *p2++ = ',' | 0x80;
00173       } else if (*p1 == '>') {
00174        *p2++ = '.' | 0x80;
00175       } else if (*p1 == ':') {
00176        *p2++ = ';' | 0x80;
00177       }
00178 
00179       p1++;
00180       bCtrlStatus = 0;
00181       continue;
00182     }
00183     *p2++ = *p1++;
00184   }
00185   *p2 = '\0';
00186 
00187   return(0);
00188 }
00189 
00190 static void Warning(str)
00191      char *str;
00192 {
00193   fprintf (stderr, "Warning: %s (at line %d)\n", str, lineno);
00194 }
00195 
00196 static void Error(str)
00197      char *str;
00198 {
00199   fprintf (stderr, "%s (at line %d)\n", str, lineno);
00200   exit (1);
00201 }
00202 
00203 static dynNode *NewNode(key, son, next)
00204      unsigned char key;
00205      dynNode *son;
00206      dynNode *next;
00207 {
00208   register dynNode *t = (dynNode *) malloc (sizeof(dynNode));
00209 
00210   if (t == NULL)
00211     Error ("Run out of memory");
00212   t->hzptr = NULL;
00213   t->key = key;
00214   t->son = son;
00215   t->next = next;
00216   if (key)
00217     totalTableNode++ ;
00218   return (t);
00219 }
00220 
00221 /* 
00222  * InsertNode -- insert the keys-HZs pair into dynNode structure
00223  */
00224 static void InsertNode(kptr, hzptr)
00225      char *kptr;
00226      char *hzptr;
00227 {
00228   register dynNode *tptr = root;
00229 
00230   while (*kptr) {
00231     unsigned char key = *kptr++;
00232 
00233     if (tptr->son == NULL) {
00234       tptr->son = NewNode(key, (dynNode *)NULL, (dynNode *)NULL);
00235       tptr = tptr->son;
00236     } else if (tptr->son->key > key) {
00237       /* new key should be the 1st son, the old one becomes the next */
00238       tptr->son = NewNode(key, (dynNode *)NULL, tptr->son);
00239       tptr = tptr->son;
00240     } else if (tptr->son->key == key) {
00241       tptr = tptr->son;
00242     } else {
00243       /* ASSERT: (tptr->son->key < key) */
00244       tptr = tptr->son;
00245       while ((tptr->next != NULL) && (tptr->next->key < key)) {
00246        tptr = tptr->next;   /* try next */
00247       }
00248       /* ASSERT: (tptr->next == NULL) || (tptr->next->key >= key) */
00249       if ((tptr->next == NULL) || (tptr->next->key > key)) {
00250        /* add it here (to keep it sorted) */
00251        tptr->next = NewNode(key, (dynNode *)NULL, tptr->next);
00252        tptr = tptr->next;
00253       } else {       /* tptr->next->key == key */
00254        tptr = tptr->next;
00255       }
00256     }
00257   }
00258 
00259   /* come to the end of the key string kptr */
00260 
00261   if (tptr->son == NULL) {
00262     tptr->son = NewNode ('\0', (dynNode *)NULL, (dynNode *)NULL);
00263     tptr->son->hzptr = (char *)malloc (strlen (hzptr) + 1);
00264     if (tptr->son->hzptr == NULL)
00265       Error ("Run out of memory");
00266     strcpy (tptr->son->hzptr, hzptr);
00267   } else if (tptr->son->key != '\0') {
00268     /* new key should be the 1st son, the old one becomes the next */
00269     tptr->son = NewNode('\0', (dynNode *)NULL, tptr->son);
00270     tptr->son->hzptr = (char *)malloc (strlen (hzptr) + 1);
00271     if (tptr->son->hzptr == NULL)
00272       Error ("Run out of memory");
00273     strcpy (tptr->son->hzptr, hzptr);
00274   } else {
00275     tptr->son->hzptr = (char *)realloc (tptr->son->hzptr,
00276                                    strlen (tptr->son->hzptr) + strlen (hzptr) + 1);
00277     if (tptr->son->hzptr == NULL)
00278       Error ("Run out of memory");
00279     strcat (tptr->son->hzptr, hzptr);
00280   }
00281   totalHZbytes += strlen (hzptr);
00282 }
00283 
00284 /*
00285  * Linearize -- make the node tree into a linear array, for I/O.
00286  *            returns the number of choices under the node.
00287  */
00288 static int Linearize(idxNode, tablenode)
00289      unsigned int idxNode;
00290      register dynNode *tablenode;
00291 {
00292   register dynNode *tptr = tablenode->son;
00293   register unsigned int i, hzlen;
00294   dynNode *tptr2;
00295   unsigned int bNodeList = pNodeList;
00296   unsigned int bHZList = pHZList;
00297   int numChoice = 0;
00298 
00299   /* if leaf node */
00300   if (tptr->key == '\0') {
00301     char *hzptr = tptr->hzptr;
00302 
00303     while (*hzptr) {
00304       if (*hzptr != HZ_PHRASE_TAG) {
00305        /* a single character */
00306        hzlen = get_char_len_by_encodeid(hzCodeTable.Encode, hzptr);
00307       } else {
00308        /* a phrase:  "PHRASE flag" | length | Phrase String */
00309        hzlen = *(hzptr+1) + 2;
00310       }
00311       for (i = 0; i < hzlen; i++) {
00312        hzList[pHZList++] = *hzptr++;
00313       }
00314 
00315       numChoice ++ ;
00316     }
00317     tptr = tptr->next;
00318   }
00319 
00320   tptr2 = tptr;      /* save for second pass */
00321   while (tptr) {
00322     nodeList[ pNodeList++ ].key = tptr->key;
00323     tptr = tptr->next;
00324   }
00325 
00326   nodeList[ idxNode ].pos_NextKey = bNodeList;
00327   nodeList[ idxNode ].num_NextKeys = pNodeList - bNodeList;
00328   nodeList[ idxNode ].pos_HZidx = bHZList;
00329   nodeList[ idxNode ].num_HZchoice = numChoice;
00330 
00331   /* linearize every sibling node */
00332   for (tptr = tptr2, i = bNodeList; tptr; i++, tptr = tptr->next) {
00333     numChoice += Linearize (i, tptr); 
00334   }
00335 
00336   /*
00337     printf("%c === num:%d\n", tptr2->key ,numChoice);
00338   */
00339   return (numChoice);
00340 }
00341 
00342 /*
00343  * BuildTableNode -- reorganize the dynNode into static tableNode structure
00344  */
00345 static void BuildTableNode()
00346 {
00347   nodeList = (tableNode *) calloc (totalTableNode, sizeof(tableNode));
00348   hzList = (unsigned char *) malloc (totalHZbytes);
00349   if ((! hzList) || (! nodeList)) {
00350     perror ("BuildTableNode");
00351     exit (1);
00352   }
00353 
00354   pNodeList = 1;     /* 0 is the root, start from index 1 */
00355   pHZList = 0;
00356 
00357   (void) Linearize(0, root);
00358   nodeList[0].num_HZchoice = 0;    /* no choice for the upmost node */
00359   nodeList[0].pos_HZidx = 0;
00360 
00361   /* ASSERT: pNodeList = totalTableNode, pHZList = totalHZbytes/2 */
00362   hzCodeTable.sizeNodeList = pNodeList;
00363   hzCodeTable.sizeHZList = pHZList;
00364 }
00365 
00366 void PrintNodeList()
00367 {
00368   int i;
00369 
00370   for (i=0; i<totalTableNode; i++)
00371     {
00372       printf("id :%d\n", i);
00373       printf("key: %c\n", nodeList[i].key);
00374       printf("num_NextKeys: %d\n", nodeList[i].num_NextKeys);
00375       printf("num_HZchoice: %d\n", nodeList[i].num_HZchoice);
00376       printf("pos_NextKey: %d\n", nodeList[i].pos_NextKey);
00377       printf("pos_HZidx: %d\n", nodeList[i].pos_HZidx);
00378       printf("\n");
00379     }
00380 }
00381 
00382 void PrintNode (tptr)
00383      dynNode *tptr;
00384 {
00385   if (tptr == NULL) return;
00386 
00387   if (tptr->key != '\0')
00388     printf("%c", tptr->key);
00389 
00390   if (tptr->hzptr)
00391     printf("%s=\n", tptr->hzptr);
00392 
00393   PrintNode(tptr->son);
00394   PrintNode(tptr->next);
00395   printf("\n");
00396 
00397 }
00398 
00399 void PrintTableInfo()
00400 {
00401   int i;
00402 
00403   printf("Lname:%s\n", hzCodeTable.Lname);
00404   printf("Cname:%s\n", hzCodeTable.Cname);
00405   printf("WildChar:%s\n", hzCodeTable.WildChar);
00406   printf("UsedCodes:%s\n", hzCodeTable.UsedCodes);
00407   printf("MaxCodes:%d\n", hzCodeTable.MaxCodes);
00408   printf("Encode:%d\n", hzCodeTable.Encode);
00409   printf("sizeNodeList:%d\n", hzCodeTable.sizeNodeList);
00410   printf("sizeHZList:%d\n", hzCodeTable.sizeHZList);
00411 
00412   printf("key_prompt\n");
00413   for (i=0; i<MAX_USEDCODES_NUM; i++)
00414     {
00415       if (keyprompt[i].prompt[0])
00416        printf("%c:  %s\n", i, keyprompt[i].prompt);
00417     }
00418 
00419   printf("function_key\n");
00420   for (i=0; i<MAX_FUNCTIONKEY_NUM; i++)
00421     {
00422       if (functionkey[i].keylist[0])
00423        printf("%d:  %d\n", i, functionkey[i].keylist[0]);
00424     }
00425   comment[clen] = '\0';
00426   printf("comment is \n%s\n", comment);
00427 }
00428 
00429 static void InitTable()
00430 {
00431   strcpy(hzCodeTable.Lname, DEFAULT_CODETABLE_NAME);
00432   strcpy(hzCodeTable.Cname, DEFAULT_CODETABLE_NAME);
00433   strcpy(hzCodeTable.UsedCodes, DEFAULT_USEDCODES);
00434   strcpy(hzCodeTable.WildChar, DEFAULT_WILDCHARS);
00435   hzCodeTable.Encode = 0;   
00436   hzCodeTable.MaxCodes = DEFAULT_MAXCODES & 0xff;       
00437 
00438   hzCodeTable.sizeHZList = 0;
00439   hzCodeTable.sizeNodeList = 0;
00440   hzCodeTable.bSectionsFlag = 0;
00441 
00442   hzCodeTable.nKeyByKeyMode = ON_MODE;
00443   hzCodeTable.nHelpInfoMode = OFF_MODE;
00444   hzCodeTable.nAutoSelectMode = OFF_MODE;
00445   hzCodeTable.nKeyPromptMode = ON_MODE;
00446   hzCodeTable.nDisplayOnSpotMode = ON_MODE;
00447   hzCodeTable.nSelectKeyMode = NUMBER_MODE;
00448 
00449   memset(&(keyprompt[0]), 0, sizeof(keyprompt));
00450   memset(&(functionkey[0]), 0, sizeof(functionkey));
00451 }
00452 
00453 /*
00454  * ReadInput -- read and parse Input Text CodeTable format file
00455  */
00456 static void ReadInput(ifile)
00457      FILE *ifile;
00458 {
00459 
00460   char line_buf[256], line[MAX_LINE_LEN];
00461   char keybuf[MAX_LINE_LEN], valuebuf[MAX_LINE_LEN];
00462   char *key, *value_str, *kptr, *sptr, *vptr;
00463   register char *ptr;
00464   int  endofstr, ret, len, line_index;
00465 
00466   int flag_section = DEFAULT_SECTION;
00467 
00468   while(fgets(line_buf, 255, ifile) != NULL) {
00469 
00470     lineno++;
00471 
00472     if((line_buf[0] == '#') && (line_buf[1] == '#')){
00473       /*
00474        printf("COMMENTS \n");
00475       */
00476       continue;
00477     }
00478 
00479     value_str = line_buf;
00480     ptr = skip_space(value_str);
00481 
00482     if (*ptr == '\0') break;
00483 
00484     /* if is space line, get new line */
00485     if (flag_section != COMMENT_SECTION) {
00486       if (*ptr == '\n')
00487        continue;
00488     }
00489 
00490     line_index = 0;
00491     while(*ptr != '\n' && *ptr != '\0' && line_index < MAX_LINE_LEN) 
00492       line[line_index++] = *ptr++;
00493 
00494     /* trim right space */
00495     while (line_index > 0 && isspace(line[line_index-1])) line_index--;
00496     line[line_index] = '\0';
00497 
00498     key = line;
00499     len = strlen(line);
00500     /*
00501       printf("len:%d, %s\n", strlen(line), line);
00502     */
00503     if (line[0] == '[' && line[len-1] == ']') {
00504 
00505       /* get section name of the item */
00506       ptr = line + 1;
00507       while(isspace(*ptr)) ptr++;
00508       key = ptr;
00509 
00510       ptr = line + len - 2;
00511       while(isspace(*ptr)) ptr--;
00512       *(ptr+1) = '\0';
00513 
00514       if (!*key) continue;
00515 
00516       if (!(strncasecmp(key, DESCRIPTION_STR, strlen(DESCRIPTION_STR)))) {
00517 
00518        flag_section = DESCRIPTION_SECTION;
00519        continue;
00520 
00521       } else if (!(strncasecmp(key, COMMENT_STR, strlen(COMMENT_STR)))) {
00522 
00523        BITSET(hzCodeTable.bSectionsFlag , COMMENT_SECTION);
00524        flag_section = COMMENT_SECTION;
00525        continue;
00526 
00527       } else if (!(strncasecmp(key, KEYPROMPT_STR, strlen(KEYPROMPT_STR)))) {
00528 
00529        BITSET(hzCodeTable.bSectionsFlag , KEYPROMPT_SECTION);
00530        flag_section = KEYPROMPT_SECTION;
00531        continue;
00532 
00533       } else if (!(strncasecmp(key, FUNCTIONKEY_STR, strlen(FUNCTIONKEY_STR)))) {
00534        
00535        BITSET(hzCodeTable.bSectionsFlag , FUNCTIONKEY_SECTION);
00536        flag_section = FUNCTIONKEY_SECTION;
00537        continue;
00538 
00539       } else if (!(strncasecmp(key, PHRASE_STR, strlen(PHRASE_STR)))) {
00540 
00541        BITSET(hzCodeTable.bSectionsFlag , PHRASE_SECTION);
00542        flag_section = PHRASE_SECTION;
00543        continue;
00544 
00545       } else if (!(strncasecmp(key, SINGLE_STR, strlen(SINGLE_STR)))) {
00546 
00547        BITSET(hzCodeTable.bSectionsFlag , SINGLE_SECTION);
00548        flag_section = SINGLE_SECTION;
00549        continue;
00550 
00551       }
00552       else if (!(strncasecmp(key, OPTIONS_STR, strlen(OPTIONS_STR)))) {
00553 
00554        BITSET(hzCodeTable.bSectionsFlag , OPTIONS_SECTION);
00555        flag_section = OPTIONS_SECTION;
00556        continue;
00557 
00558       }
00559     }
00560 
00561     switch (flag_section) {
00562               
00563     case DEFAULT_SECTION:
00564       break;
00565 
00566     case DESCRIPTION_SECTION:
00567       if (!(strncasecmp(key, LOCALE_STR, strlen(LOCALE_STR)))) {
00568        value_str = skip_space(key+strlen(LOCALE_STR));
00569        if ((*value_str == '\0') || (*value_str == '\n'))
00570          continue;
00571 
00572        strcpy(hzCodeTable.Lname, value_str);
00573        break;
00574       }
00575 
00576       if (!(strncasecmp(key, NAME_STR, strlen(NAME_STR)))) {
00577        value_str = skip_space(key+strlen(NAME_STR));
00578        if ((*value_str == '\0') || (*value_str == '\n'))
00579          continue;
00580 
00581        strcpy(hzCodeTable.Cname, value_str);
00582        break;
00583       }
00584 
00585       if (!(strncasecmp(key, ENCODE_STR, strlen(ENCODE_STR)))) {
00586        value_str = skip_space(key+strlen(ENCODE_STR));
00587        if ((*value_str == '\0') || (*value_str == '\n'))
00588          continue;
00589 
00590        hzCodeTable.Encode = get_encodeid_from_name(value_str);
00591        hzCodeTable.Output_Encode = hzCodeTable.Encode;
00592        break;
00593       }
00594 
00595       if (!(strncasecmp(key, USEDCODES_STR, strlen(USEDCODES_STR)))) {
00596        value_str = skip_space(key+strlen(USEDCODES_STR));
00597        if ((*value_str == '\0') || (*value_str == '\n'))
00598          continue;
00599 
00600        strncpy(hzCodeTable.UsedCodes, value_str, MAX_USEDCODES_NUM);
00601        break;
00602       }
00603 
00604       if (!(strncasecmp(key, WILDCHAR_STR, strlen(WILDCHAR_STR)))) {
00605        value_str = skip_space(key+strlen(WILDCHAR_STR));
00606        if ((*value_str == '\0') || (*value_str == '\n'))
00607          continue;
00608 
00609        strncpy(hzCodeTable.WildChar, value_str, MAX_WILDCHAR_NUM);
00610        break;
00611       }
00612 
00613       if (!(strncasecmp(key, MAXCODES_STR, strlen(MAXCODES_STR)))) {
00614        value_str = skip_space(key+strlen(MAXCODES_STR));
00615        if ((*value_str == '\0') || (*value_str == '\n'))
00616          continue;
00617 
00618        hzCodeTable.MaxCodes = atoi(value_str) & 0xff;
00619        break;
00620       }
00621 
00622       break;
00623 
00624     case OPTIONS_SECTION:
00625       /*
00626        printf("Options Section ====\n");
00627        printf("OPTION_OPEN_STR:%s\n", OPTION_OPEN_STR);
00628       */
00629 
00630       if (!(strncasecmp(key,KEYBYKEY_MODE_STR,strlen(KEYBYKEY_MODE_STR)))){
00631        value_str = skip_space(key+strlen(KEYBYKEY_MODE_STR));
00632        if ((*value_str == '\0') || (*value_str == '\n'))
00633          continue;
00634        /*
00635          printf("keybykey: %s\n", value_str);
00636        */
00637        if (!(strncasecmp(value_str,OPTION_OPEN_STR, strlen(OPTION_OPEN_STR))))
00638          hzCodeTable.nKeyByKeyMode = ON_MODE;
00639        else 
00640          hzCodeTable.nKeyByKeyMode = OFF_MODE;
00641        break;
00642       }
00643 
00644       if (!(strncasecmp(key,HELPINFO_MODE_STR,strlen(HELPINFO_MODE_STR)))){
00645        value_str = skip_space(key+strlen(HELPINFO_MODE_STR));
00646        if ((*value_str == '\0') || (*value_str == '\n'))
00647          continue;
00648        /*
00649          printf("HelpInfo: %s\n", value_str);
00650        */
00651        if (!(strncasecmp(value_str,OPTION_OPEN_STR, strlen(OPTION_OPEN_STR))))
00652          hzCodeTable.nHelpInfoMode = ON_MODE;
00653        else 
00654          hzCodeTable.nHelpInfoMode = OFF_MODE;
00655        break;
00656       }
00657 
00658       if (!(strncasecmp(key,AUTOSELECT_MODE_STR,strlen(AUTOSELECT_MODE_STR)))){
00659        value_str = skip_space(key+strlen(AUTOSELECT_MODE_STR));
00660        if ((*value_str == '\0') || (*value_str == '\n'))
00661          continue;
00662        /*
00663          printf("AutoSelect: %s\n", value_str);
00664        */
00665        if (!(strncasecmp(value_str,OPTION_OPEN_STR, strlen(OPTION_OPEN_STR))))
00666          hzCodeTable.nAutoSelectMode = ON_MODE;
00667        else 
00668          hzCodeTable.nAutoSelectMode = OFF_MODE;
00669        break;
00670       }
00671 
00672       if (!(strncasecmp(key,KEYPROMPT_MODE_STR,strlen(KEYPROMPT_MODE_STR)))){
00673        value_str = skip_space(key+strlen(KEYPROMPT_MODE_STR));
00674        if ((*value_str == '\0') || (*value_str == '\n'))
00675          continue;
00676        /*
00677          printf("KeyPromptMode: %s\n", value_str);
00678        */
00679        if (!(strncasecmp(value_str,OPTION_OPEN_STR, strlen(OPTION_OPEN_STR))))
00680          hzCodeTable.nKeyPromptMode = ON_MODE;
00681        else 
00682          hzCodeTable.nKeyPromptMode = OFF_MODE;
00683        break;
00684       }
00685 
00686       if (!(strncasecmp(key,DISPLAYONSPOT_MODE_STR,strlen(DISPLAYONSPOT_MODE_STR)))){
00687        value_str = skip_space(key+strlen(DISPLAYONSPOT_MODE_STR));
00688        if ((*value_str == '\0') || (*value_str == '\n'))
00689          continue;
00690        /*
00691          printf("DisplayOnSpotMode: %s\n", value_str);
00692        */
00693        if (!(strncasecmp(value_str,OPTION_OPEN_STR, strlen(OPTION_OPEN_STR))))
00694          hzCodeTable.nDisplayOnSpotMode = ON_MODE;
00695        else 
00696          hzCodeTable.nDisplayOnSpotMode = OFF_MODE;
00697        break;
00698       }
00699 
00700       if (!(strncasecmp(key,SELECTKEY_MODE_STR,strlen(SELECTKEY_MODE_STR)))){
00701        value_str = skip_space(key+strlen(SELECTKEY_MODE_STR));
00702        if ((*value_str == '\0') || (*value_str == '\n'))
00703          continue;
00704        /*
00705          printf("SelectKeyMode: %s\n", value_str);
00706        */
00707        hzCodeTable.nSelectKeyMode = str2val(selectkeymode_str_val, value_str);
00708        break;
00709       }
00710 
00711       break;
00712 
00713     case COMMENT_SECTION:
00714       ptr = line_buf;
00715       while (*ptr && clen < MAX_COMMENT_LEN)
00716        comment[clen++] = *ptr++;
00717       break;
00718               
00719     case FUNCTIONKEY_SECTION:
00720       if (!(strncasecmp(key,PAGEUP_KEY_STR,strlen(PAGEUP_KEY_STR)))){
00721        value_str = skip_space(key+strlen(PAGEUP_KEY_STR));
00722        if ((*value_str == '\0') || (*value_str == '\n'))
00723          continue;
00724 
00725        /*
00726          printf("pageup: %s\n", value_str);
00727        */
00728        ret = convert_octnum(value_str);
00729        if (ret == -1)
00730          Error("FunctionKey Error Defination");
00731 
00732        strncpy(functionkey[PAGEUP_KEY_ID].keylist, value_str, MAX_FUNCTIONKEY_LEN);
00733        break;
00734       }
00735 
00736       if (!(strncasecmp(key,PAGEDOWN_KEY_STR,strlen(PAGEDOWN_KEY_STR)))){
00737        value_str = skip_space(key+strlen(PAGEDOWN_KEY_STR));
00738        if ((*value_str == '\0') || (*value_str == '\n'))
00739          continue;
00740 
00741        /*
00742          printf("pagedown: %s\n", value_str);
00743        */
00744        ret = convert_octnum(value_str);
00745        if (ret == -1)
00746          Error("FunctionKey Error Defination");
00747 
00748        strncpy(functionkey[PAGEDOWN_KEY_ID].keylist, value_str, MAX_FUNCTIONKEY_LEN);
00749       }
00750 
00751       if (!(strncasecmp(key,BACKSPACE_KEY_STR,strlen(BACKSPACE_KEY_STR)))){
00752        value_str = skip_space(key+strlen(BACKSPACE_KEY_STR));
00753        if ((*value_str == '\0') || (*value_str == '\n'))
00754          continue;
00755 
00756        /*
00757          printf("backspace: %s\n", value_str);
00758        */
00759        ret = convert_octnum(value_str);
00760        if (ret == -1)
00761          Error("FunctionKey Error Defination");
00762 
00763        strncpy(functionkey[BACKSPACE_KEY_ID].keylist, value_str, MAX_FUNCTIONKEY_LEN);
00764        break;
00765       }
00766                      
00767       if (!(strncasecmp(key,CLEARALL_KEY_STR,strlen(CLEARALL_KEY_STR)))){
00768        value_str = skip_space(key+strlen(CLEARALL_KEY_STR));
00769        if ((*value_str == '\0') || (*value_str == '\n'))
00770          continue;
00771 
00772        /*
00773          printf("deleteall: %s\n", value_str);
00774        */
00775        ret = convert_octnum(value_str);
00776        if (ret == -1)
00777          Error("FunctionKey Error Defination");
00778 
00779        strncpy(functionkey[CLEARALL_KEY_ID].keylist, value_str, MAX_FUNCTIONKEY_LEN);
00780       }
00781 
00782       break;
00783 
00784     case KEYPROMPT_SECTION:
00785       ptr = key;
00786       kptr = keybuf;
00787 
00788       /* get key string */
00789       while (*ptr && (*ptr!=' ') && (*ptr!='\t') && (!(*ptr & 0x80))){
00790        *(kptr++) = *(ptr++);
00791       }
00792 
00793       *kptr = '\0';
00794 
00795       /* if no key string or no prompt string */
00796       if (!(*ptr) || !(keybuf[0])) break;
00797 
00798       /* get prompt characters string */
00799       value_str = skip_space(ptr);
00800                      
00801       /* if no single character string */
00802       if ((*value_str == '\0') || (*value_str == '\n'))
00803        break;
00804 
00805       /* only get first string */
00806       vptr = value_str;
00807       sptr = to_space(vptr);
00808       *sptr = '\0';
00809       /*
00810        printf("key:%s, keyprompt:%s====\n", keybuf, value_str);
00811       */
00812       strncpy(keyprompt[(int)keybuf[0]].prompt, value_str, MAX_KEYPROMPT_LEN);
00813       break;
00814 
00815     case SINGLE_SECTION:
00816       ptr = key;
00817       kptr = keybuf;
00818 
00819       /* get key string */
00820       while (*ptr && (*ptr!=' ') && (*ptr!='\t') && (!(*ptr & 0x80))){
00821        *(kptr++) = *(ptr++);
00822       }
00823 
00824       *kptr = '\0';
00825 
00826       /* if no key string or no single string */
00827       if (!(*ptr) || !(keybuf[0])) break;
00828 
00829       /* get single characters string */
00830       value_str = skip_space(ptr);
00831                      
00832       /* if no single character string */
00833       if ((*value_str == '\0') || (*value_str == '\n'))
00834        break;
00835 
00836       /* only get first string */
00837       vptr = value_str;
00838       sptr = to_space(vptr);
00839       *sptr = '\0';
00840       /*
00841        printf("key:%s, value:%s====\n", keybuf, value_str);
00842       */
00843       InsertNode(keybuf, value_str);      
00844 
00845       break;
00846 
00847     case PHRASE_SECTION:
00848       /*
00849        printf("line:%s====\n", key);
00850       */
00851       ptr = key;
00852       kptr = keybuf;
00853 
00854       /* get key string */
00855       while (*ptr && (*ptr!=' ') && (*ptr!='\t') && (!(*ptr & 0x80))){
00856        *(kptr++) = *(ptr++);
00857       }
00858 
00859       *kptr = '\0';
00860 
00861       /* if no key string or no phrase string */
00862       if (!(*ptr) || !(keybuf[0])) break;
00863 
00864       /* get phrase string */
00865       value_str = skip_space(ptr);
00866                      
00867       /* if no phrase character string */
00868       if ((*value_str == '\0') || (*value_str == '\n'))
00869        break;
00870 
00871       /*
00872        printf("key:%s, value:%s====\n", keybuf, value_str);
00873       */
00874       /* seperate the phrase string into single phrase */
00875       vptr = value_str;
00876       endofstr = 0;
00877       while (*vptr)
00878        {
00879          sptr = vptr;
00880          if ((*sptr == '#') && (*sptr++ == '#')){
00881            /*
00882              printf("Comment in the phrase line \n");
00883            */
00884            break; 
00885          }
00886 
00887          vptr = to_space(sptr);
00888 
00889          if (*vptr == '\0' || *vptr == '\n')
00890            endofstr = 1;
00891 
00892          *vptr = '\0';
00893          valuebuf[0] = HZ_PHRASE_TAG;
00894          valuebuf[1] = (unsigned char)(strlen(sptr));
00895          /*
00896            printf("str:%s, strlen:%d\n", sptr, strlen(sptr));
00897          */
00898          strcpy(valuebuf+2, sptr);
00899          InsertNode(keybuf, valuebuf);
00900                             
00901          if (endofstr)
00902            break;
00903 
00904          vptr = skip_space(vptr + 1);
00905          if (*vptr == '\n')
00906            break;
00907        }
00908       break;
00909     }
00910   } 
00911 }
00912 
00913 void Output (ofile)
00914      FILE *ofile;
00915 {
00916   int ver = CODETABLE_VERSION;
00917 
00918   /* write CodeTable File Flag */
00919   fwrite (CODETABLE_FLAG, strlen(CODETABLE_FLAG), 1, ofile);     
00920 
00921   /* write CodeTable Version Flag */
00922   fwrite((char *)(&ver), sizeof(int), 1, ofile); 
00923 
00924   /* write CodeTable Header Structure */
00925   if ((fwrite(&hzCodeTable, sizeof(CodeTableStruct), 1, ofile)) == 0)
00926     {
00927       perror ("Writing output file");
00928       exit (1);
00929     }
00930 
00931   /* write CodeTable Node List */
00932   if ((fwrite(nodeList, sizeof(tableNode), hzCodeTable.sizeNodeList, ofile))
00933       != hzCodeTable.sizeNodeList) 
00934     {
00935       perror ("Writing output file");
00936       exit (1);
00937     }
00938 
00939   /* write CodeTable HanZi List */
00940   if ((fwrite(hzList, sizeof(unsigned char), hzCodeTable.sizeHZList, ofile))
00941       != hzCodeTable.sizeHZList)
00942     {
00943       perror ("Writing output file");
00944       exit (1);
00945     }
00946 
00947   /* if [Key_Prompt] section exist, write CodeTable Key Prompt List */
00948   if (GETBIT(hzCodeTable.bSectionsFlag, KEYPROMPT_SECTION))
00949     {
00950       if ((fwrite(&(keyprompt[0]), MAX_USEDCODES_NUM, sizeof(keyPrompt), ofile))
00951          != sizeof(keyPrompt))
00952        {
00953          perror ("Writing output file");
00954          exit (1);
00955        }
00956     }
00957 
00958   /* if [Function_Key] section exist, write CodeTable Function Key List */
00959   if (GETBIT(hzCodeTable.bSectionsFlag, FUNCTIONKEY_SECTION))
00960     {
00961       if ((fwrite(&(functionkey[0]),MAX_FUNCTIONKEY_NUM,sizeof(functionKey), ofile))
00962          != sizeof(functionKey))
00963        {
00964          perror ("Writing output file");
00965          exit (1);
00966        }
00967     }
00968               
00969   /* if [Comment] section exist, write CodeTable Comment List */
00970   if (GETBIT(hzCodeTable.bSectionsFlag, COMMENT_SECTION))
00971     {
00972       if ((fwrite((char *)(&clen), sizeof(unsigned int), 1, ofile)) == 0) 
00973        {
00974          perror ("Writing output file");
00975          exit (1);
00976        }
00977 
00978       if ((fwrite(comment, 1, clen, ofile)) != clen)
00979        {
00980          perror ("Writing output file");
00981          exit (1);
00982        }
00983     }
00984 }
00985 
00986 int main(argc, argv)
00987      int argc;
00988      char *argv[];
00989 {
00990   FILE *ifile, *ofile;
00991   char *inputfile_name = "wbtest.txt";
00992   char *outputfile_name = "test.data";
00993 
00994   if (argc != 3)
00995     {
00996       printf("%s inputfile outputfile\n", argv[0]);
00997       exit(0);
00998     }
00999 
01000   inputfile_name = argv[1];
01001   outputfile_name = argv[2];
01002 
01003   /*
01004     printf("inputfile:%s, outputfile:%s\n",inputfile_name, outputfile_name);
01005   */
01006 
01007   ifile = fopen(inputfile_name, "r");
01008   if (! ifile) 
01009     {
01010       perror(inputfile_name);
01011       exit(1);
01012     }
01013 
01014   ofile = fopen(outputfile_name, "w+");
01015   if (! ofile) 
01016     {
01017       fclose(ifile);
01018       exit(1);
01019     }
01020 
01021   InitTable();
01022 
01023   ReadInput(ifile);
01024   fclose(ifile);
01025 
01026   /*
01027     PrintNode(root);
01028   */
01029   BuildTableNode();
01030   /*
01031     PrintTableInfo();
01032     PrintNodeList();
01033   */
01034   Output(ofile);
01035   fclose(ofile);
01036 
01037   exit(0);
01038 }
01039