xml/cxmllibrary/dictionary/dict_creator.c
branchRCL_3
changeset 33 604ca70b6235
parent 32 889504eac4fb
child 40 80a0ad972c63
--- a/xml/cxmllibrary/dictionary/dict_creator.c	Tue Aug 31 17:02:56 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1051 +0,0 @@
-/*
-* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the License "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:   
-* Author:       Frank Richichi
-* Created:      Thu Apr 25 10:34:06 2002
-* Modified:     Thu Apr 25 11:12:35 2002 (Frank Richichi) richichi@D5250215
-* Language:     C
-* Subsystem:    N/A
-* RCS:          $Id$
-*
-*/
-
-
-/* ****************************************************************
-**          Copyright 2000 - Nokia Corporation  All rights reserved.
-**          Nokia Americas
-**          6000 Connection Drive
-**          Irving, Texas 75039
-**
-**          Restricted Rights: Use, duplication, or disclosure by the
-**          U.S. Government is subject to restrictions as set forth in
-**          subparagraph (c)(1)(ii) of DFARS 252.227-7013, or in FAR
-**          52.227-19, or in FAR 52.227-14 Alt. III, as applicable.
-**
-**          This software is proprietary to and embodies the confidential
-**          technology of Nokia  Possession, use, or copying of this software 
-**          and media is authorized only pursuant to a valid written license
-**          from Nokia or an authorized sublicensor.
-**
-**          Nokia  - Wireless Software Solutions
-*****************************************************************/
-
-#include <stdio.h>
-#include <io.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <time.h>
-
-
-/* ----------------------------------------------------------------------- **
-   The following strings are used to identify the beginning of a tag or 
-   attribute list in the input file.
-** ----------------------------------------------------------------------- **/
-
-#define TAG_TABLE_HEADING   "TAGS_FOR_CODE_PAGE"
-#define ATTR_TABLE_HEADING  "ATTRIBUTES_FOR_CODE_PAGE"
-#define NO_STRINGS "NO_STRINGS"
-
-/* ----------------------------------------------------------------------- **
-   Types for various tables.
-** ----------------------------------------------------------------------- **/
-#define NAME_TABLE_T    "NW_Byte"
-#define TOKEN_TABLE_T   "NW_WBXML_DictEntry_t"
-#define CODEPAGE_TABLE_T  "NW_WBXML_Codepage_t"
-#define DICTIONARY_TABLE_T  "NW_WBXML_Dictionary_t"
-#define NAMES_T     "NW_String_UCS2Buff_t"
-#define ELEMENT_T "NW_%s_Element"
-#define ATTRIBUTE_T "NW_%s_Attribute"
-#define ELEMENT_TOKEN_T "NW_%s_ElementToken"
-#define ATTRIBUTE_TOKEN_T "NW_%s_AttributeToken"
-
-/* ----------------------------------------------------------------------- **
-   Misc array limits
-** ----------------------------------------------------------------------- **/
-#define TABLE_SIZE      255
-#define MAX_LINE        255
-#define MAX_NAME        255
-#define MAX_TOKEN       4
-#define MAX_DICT_NAME   255
-#define MAX_PUBLIC_ID   255
-#define MAX_DOC_TYPE    255
-#define MAX_START_NAME  255
-#define MAX_TYPE_NAME   255
-
-/* ----------------------------------------------------------------------- **
-  Names used in the generated tables
-** ----------------------------------------------------------------------- **/
-#define TAG_NAME    "tag"
-#define ATTR_NAME   "attribute"
-
-
-/* ----------------------------------------------------------------------- **
-   Define a type for codepage storage
-** ----------------------------------------------------------------------- **/
-typedef struct codepage_s {
-  int   num;    /* the code page number */
-  int   size;   /* the number of entries in table */
-} codepage_t;
-
-
-/* ----------------------------------------------------------------------- **
-   Header information
-** ----------------------------------------------------------------------- **/
-char dict_name[MAX_DICT_NAME];
-char doc_type[MAX_DOC_TYPE];
-char public_id[10];
-
-/* ----------------------------------------------------------------------- **
-   Scratch tables
-** ----------------------------------------------------------------------- **/
-char * tokens[TABLE_SIZE];
-char * names[TABLE_SIZE];
-int sorted_indexes[TABLE_SIZE];
-codepage_t tag_codepages[TABLE_SIZE];
-codepage_t attr_codepages[TABLE_SIZE];
-
-
-/* ----------------------------------------------------------------------- **
-   Records time of program execution and command line arguments
-** ----------------------------------------------------------------------- **/
-static time_t timestamp;
-static int main_argc = 1;
-static char** main_argv;
-
-/* ----------------------------------------------------------------------- **
-   Globals so error clean up is easy
-** ----------------------------------------------------------------------- **/
-static FILE* input_dict;
-static FILE* output_c;
-static FILE* output_h;
-
-static void exit_error(int exit_code) {
-  static char errmsg[]
-  = "#error \"Bad input dictionary data cannot complete code generation\"\n";
-  if (input_dict) fclose(input_dict);
-  if (output_c) {
-    fprintf(output_c, errmsg);
-    fclose(output_c);
-  }
-  if (output_h) {
-    fprintf(output_h, errmsg);
-    fclose(output_h);
-  }
-  exit(exit_code);
-}
-
-void print_usage(char* progname)
-{
-  fprintf(stderr,
-  "Dictionary creator - creates a .c and .h source file for a\n"
-  "NW_Wbxml_Dictionary_t structure from a dictionary data file.\n"
-  "\n"
-  "Usage: %s data_input_file dot_c_output_file dot_h_output_file\n"
-  "\n"
-  " - all args are required\n"
-  "\n"
-  "Comments are defined to be:\n"
-  "\n"
-  " - A line whose first non-whitespace char is '#'\n"
-  " - A blank line or line with only whitespace\n"
-  " Note: Comments are NOT permitted at the end of other lines.\n"
-  "\n"
-  "Input format:\n"
-  "\n"
-  " - Dictionary name = the first non-comment line.  The dictionary\n"
-  "   that will be created will use this string in the dictionary \n"
-  "   name.  For example, if the dictionary name is \"wml\", the\n"
-  "   following dictionary will be created:\n"
-  "\n"
-  "     NW_Wbxml_Dictionary_t NW_wml_dictionary = { ... }\n"
-  "\n"
-  " - Public id = the second non-comment line.  This is the Public \n"
-  "   Identifier as specified in section 7.2 of the WBML spec.  If\n"
-  "   a public id has not been defined, use \"1\".\n"
-  "\n"
-  " - Doc Type = the third non-comment line.  This is the source\n"
-  "   document's Document Type Declaration.\n"
-  "\n"
-  " - The beginning of a Tag table has the following syntax:\n"
-  "\n"
-  "     TAGS_FOR_CODE_PAGE <codepage_number> [NO_STRINGS]\n"
-  "\n"
-  "     <codepage_number> is required and is a base 10 number\n"
-  "\n"
-  "     [NO_STRINGS] is an optional keyword which means output only\n"
-  "     the token structures, treat all token names as empty strings\n"
-  "\n"
-  " - The beginning of an Attribute table has the following syntax:\n"
-  "\n"
-  "     ATTRIBUTES_FOR_CODE_PAGE <codepage_number> [NO_STRINGS]\n"
-  "     \n"
-  "     <codepage_number> is required and is a base 10 number\n"
-  "\n"
-  "     [NO_STRINGS] is an optional keyword which means output only\n"
-  "     the token structures, treat all token names as empty strings\n"
-  "\n"
-  " - The syntax for an entry is the same for both Tag and Attribute \n"
-  "   tables\n"
-  "\n"
-  "     <token> <name>\n"
-  "\n"
-  "     <token> must be a hexadecimal number written as 0x?? (e.g., 0x07)\n"
-  "     NOTE: Tokens are sorted as strings so 0x7 MUST be entered as 0x07\n"
-  "           or the sorting won't work!  It is ok to mix case as all hex\n"
-  "           digits are converted to lower case before the sort.\n"
-  "\n"
-  "     <name> is any sequence of printable characters without whitespace\n"
-  "\n"
-  " - The input tables do NOT have to be sorted \n"
-  "\n"
-  " - If a language has \"Attribute Value Tokens\", they should be included\n"
-  "   in the Attribute table\n"
-  "\n"
-  "Example input file (example.dict):\n"
-  "\n"
-  "  #\n"
-  "  # Sample dictionary for the WML language\n"
-  "  #\n"
-  "  wml\n"
-  "  #\n"
-  "  # WML version 1.2 has a public id of 9\n"
-  "  #\n"
-  "  9\n"
-  "  #\n"
-  "  # WML 1.2 doc type\n"
-  "  #\n"
-  "  -//WAPFORUM//DTD WML 1.1//EN\n"
-  "  #\n"
-  "  # Tags\n"
-  "  #\n"
-  "  TAGS_FOR_CODE_PAGE 0\n"
-  "  0x2b go\n"
-  "  0x1d td\n"
-  "  #\n"
-  "  # Attributes\n"
-  "  #\n"
-  "  ATTRIBUTES_FOR_CODE_PAGE 0\n"
-  "  0x12 format\n"
-  "  0xA0 wrap\n"
-  "  0x23 newcontext=true\n"
-  "  0x8F http://www.\n"
-  "\n"
-  "Example run command:\n"
-  "\n"
-  "  %s example.dict example.c example.h\n",
-  progname, progname);
-}
-
-static void print_automaticallyGeneratedCodeWarning(FILE *f)
-{
-  int i;
-  static char automaticallyGeneratedCodeWarning[] =
-  "/*\n"
-  "** WARNING\n"
-  "**\n"
-  "** DO NOT EDIT - THIS CODE IS AUTOMATICALLY GENERATED\n"
-  "**               FROM A DATA FILE BY THE DICTIONARY CREATION PROGRAM";
-
-  fprintf(f, "%s\n", automaticallyGeneratedCodeWarning);
-  fprintf(f,
-          "**\n"
-          "** This file generated on %s"
-          "**                        (coordinated universal time)\n"
-          "**\n"
-          "** Command line: ",
-          asctime(gmtime(&timestamp))); /* asctime() generates a newline at the end */
-  fprintf(f, "%s", main_argv[0]);
-  for (i = 1; i < main_argc; i++) {
-    fprintf(f, " %s", main_argv[i]);
-  }
-  fprintf(f, "\n*/");
-}
-
-static void print_copyright(FILE *f)
-{
-  struct tm* tm_time;
-  static const char copyright[] =
-  "/* ****************************************************************\n"
-  "**          Copyright %d - Nokia Corporation  All rights reserved.\n"
-  "**          Nokia Americas\n"
-  "**          6000 Connection Drive\n"
-  "**          Irving, Texas 75039\n"
-  "**\n"
-  "**          Restricted Rights: Use, duplication, or disclosure by the\n"
-  "**          U.S. Government is subject to restrictions as set forth in\n"
-  "**          subparagraph (c)(1)(ii) of DFARS 252.227-7013, or in FAR\n"
-  "**          52.227-19, or in FAR 52.227-14 Alt. III, as applicable.\n"
-  "**\n"
-  "**          This software is proprietary to and embodies the confidential\n"
-  "**          technology of Nokia  Possession, use, or copying of this software\n"
-  "**          and media is authorized only pursuant to a valid written license\n"
-  "**          from Nokia or an authorized sublicensor.\n"
-  "**\n"
-  "**          Nokia  - Wireless Software Solutions\n"
-  "*****************************************************************/";
-
-  tm_time = gmtime(&timestamp);
-  fprintf(f, copyright,
-          tm_time->tm_year + 1900);
-}
-
-static FILE * open_file(char* fn, char *perms){
-  FILE* f;
-  
-  if ((fn == 0)||((f = fopen(fn, perms)) == 0)){    
-    return 0;
-  }else{    
-    return f;
-  }
-  
-}
-
-static init() {
-  int i;
-
-  for (i=0; i < TABLE_SIZE; i++) {
-    tag_codepages[i].num = -1;
-    attr_codepages[i].num = -1;
-  }
-}
-
-
-/* ----------------------------------------------------------------------- **
-  Read the next line of input and store it in s.  
- 
-  NOTE: s will have the new-line character stripped
- 
-  RETURN: 1 for success and 0 for EOF or failure 
-** ----------------------------------------------------------------------- **/
-static int get_line(FILE *f, char s[], int n){
-  int i = 0, j, indx, len;
-  char line[MAX_LINE];
-
-  for(;;) {
-    if ((fgets(line, n, f)) == 0) {
-      /* Either EOF or an error occurred */
-      return 0;
-    }
-    len = (int) strlen(line);
-    /* Skip any preceeding whitespace */
-    for (i=0; i < len; i++) {
-      if (isspace(line[i]))
-      continue;
-      break;
-    }
-    if (i >= len || line[i] == '#')
-      continue;
-    break;
-  }
-
-  /* Fill in s */
-  for (j=i, indx = 0; j < (int) strlen(line); i++, j++, indx++) {
-    if (line[j] == '\n') {
-      break;
-    }
-    if (line[j] == '\t') {
-      /* convert tab to space for isprint() test */
-      line[j] = ' ';
-    }
-    if (!isprint(line[j])) {
-      /* stops on bogus char */
-      fprintf(stderr,
-              "ERROR: Illegal character (may be control char) in input text "
-              "near file byte offset %ld\n",
-              ftell(f));
-      exit_error(1);
-    }
-    s[indx] = line[j];
-    if (indx + 1 == MAX_LINE) break;
-  }
-
-  if (indx > 0)
-    s[indx] = '\000';
-
-  return 1;
-}
-
-
-/* ----------------------------------------------------------------------- **
-   Read the a line of input and break it into three items:
-   For table header
-      1. Table type name
-      2. Code page number
-      3. Optional "NO_STRINGS"
-   For table entry
-      1. 0x?? token value
-      2. token string (optional, extends from first nonspace to eol)
-      3. null
- 
-  RETURN: 1 for success and 0 for EOF or failure
- ** ----------------------------------------------------------------------- **/
-static int get_tuple(FILE *f, char item1[], char item2[], char item3[])
-{
-  char line[MAX_LINE];
-  int i;
-  int j;
-  int len;
-
-  if ((get_line(f, line, MAX_LINE)) != 1) {
-    return 0;
-  }
-
-  len = (int)strlen(line);
-
-  /* tablename or token hex value */
-  j = 0;
-  for (i = 0; i < len; i++) {
-    if (isspace(line[i])) break;
-    if (item1[0] == '0' && j == MAX_TOKEN) {
-      /* have to check for leading '0' because this func is called to process
-      TAG_TABLE_HEADING lines too where length could be longer than MAX_TOKEN */
-      fprintf(stderr, "ERROR: token value too long near input file byte offset %ld\n",
-              ftell(f));
-      exit_error(1);
-      break;
-    }
-    item1[j++] = line[i];
-  }
-  item1[j] = '\0';
-
-  /* whitespace */
-  for (; i < len; i++) {
-    if (!isspace(line[i])) break;
-  }
-
-  /* codepage or token string */
-  j = 0;
-  for (/* continue with i */; i < len; i++) {
-    if (item1[0] != '0' && isspace(line[i])) break;
-    if (j == MAX_NAME) {
-      fprintf(stderr, "ERROR: token string too long near input file byte offset %ld\n",
-              ftell(f));
-      exit_error(1);
-      break;
-    }
-    item2[j++] = line[i];
-  }
-  item2[j] = '\0';
-
-  /* whitespace */
-  for (; i < len; i++) {
-    if (!isspace(line[i])) break;
-  }
-
-  /* nostrings or nothing */
-  j = 0;
-  for (/* continue with i */; i < len; i++) {
-    item3[j++] = line[i];
-  }
-  item3[j] = '\0';
-
-  return 1;
-}
-
-static void process_header(FILE *f)
-{
-  if ((get_line(f, dict_name, MAX_DICT_NAME)) != 1) {
-    fprintf(stderr, "ERROR: reading dictionary name\n");
-    exit_error(1);
-  }
-
-  if ((get_line(f, public_id, MAX_PUBLIC_ID)) != 1) {
-    fprintf(stderr, "ERROR: reading public id\n");
-    exit_error(1);
-  }
-
-  if ((get_line(f, doc_type, MAX_DOC_TYPE)) != 1) {
-    fprintf(stderr, "ERROR: reading doc type\n");
-    exit_error(1);
-  }
-}
-
-static void print_file_header(FILE *output, FILE *outputHeader)
-{
-  fprintf(output, "/*\n");
-  fprintf(output, " * Dictionary = %s\n", dict_name);
-  fprintf(output, " * Public id = %s\n", public_id);
-  fprintf(output, " * Doc Type = %s\n", doc_type);
-  fprintf(output, " */\n");
-  fprintf(output, "\n");
-
-  fprintf(output, "#include \"%s\"\n", main_argv[3]);
-  fprintf(output, "#include \"xml\/cxml\/nw_wbxml_dictionary.h\"\n");
-
-  fprintf(output, "\n");
-
-  /* Including the typedef for public id */
-  fprintf(outputHeader, "#define NW_%s_PublicId %s\n", dict_name, public_id);
-}
-
-static void print_table_header(FILE *output, char * table_type, char *type, char *key, char *code_page, int n)
-{
-  print_automaticallyGeneratedCodeWarning(output);
-  fprintf(output, "\n\n");
-  fprintf(output, "/*\n");
-  fprintf(output, " * %s entries - sorted by %s\n", type, key);
-  fprintf(output, " */\n");
-  fprintf(output, "static const\n");
-  fprintf(output, "%s NW_%s_%s_%s_%s[%d] = {\n", table_type, dict_name, type, key, code_page, n);
-}
-
-static void process_entry(int i, char *token, char *name) 
-{
-  tokens[i] = strdup(token);
-  names[i] = strdup(name);
-  sorted_indexes[i] = i;
-}
-
-
-/* ----------------------------------------------------------------------- **
-   Print the table of tokens and names - sorted by token
-   Also create a list of the items, sorted by name 
- ** ----------------------------------------------------------------------- **/
-static void print_token_table(FILE *output, FILE* outputHeader,
-                              char *type, char *key, char *code_page, int n,
-                              int use_strings)
-{
-  static char tagTypeString[MAX_TYPE_NAME];
-  static char tokenTypeString[MAX_TYPE_NAME];
-
-  /* Must first sort by token */
-  int i, j;
-  char *tmp_token;
-  char *tmp_name;
-  char *tagType = &tagTypeString[0];
-
-  if (strcmp("tag", type) == 0)
-  {
-    (void)sprintf(tagTypeString, ELEMENT_T, dict_name);
-    (void)sprintf(tokenTypeString, ELEMENT_TOKEN_T, dict_name);
-  }
-  else if (strcmp("attribute", type) == 0)
-  {
-    (void)sprintf(tagTypeString, ATTRIBUTE_T, dict_name);
-    (void)sprintf(tokenTypeString, ATTRIBUTE_TOKEN_T, dict_name);
-  }
-  else {
-    fprintf(stderr, "ERROR: internal error\n");
-    exit_error(1);
-  }
-
-  /* make all the tokens lower case */
-  for (i=0; i < n; i++) {
-    int l = (int)strlen(tokens[i]);
-    if (l != 4) {
-      fprintf(stderr, 
-              "ERROR: Badly formatted token %s\n"
-              "All token values must be in the form 0x?? (e.g., 0x07) "
-              "or the sorting algorithm won't work.\n"
-              , tokens[i]);
-      exit_error(1);
-    }
-    for (j=0; j < l; j++) {
-      if (isupper(tokens[i][j])) {
-        tokens[i][j] = (char)tolower(tokens[i][j]);
-      }
-      if ((tokens[i][j] != 'x') && isalpha(tokens[i][j])) {
-        if ((tokens[i][j] < 'a') || (tokens[i][j] > 'f')) {
-          fprintf(stderr, 
-                  "ERROR: Illegal hex digit in token %s\n"
-                  , tokens[i]);
-          exit_error(1);
-        }
-      }
-    }
-  }
-
-  for (i=0; i < n-1; i++) {
-    for (j=0; j < n-1; j++) {
-      /* 
-       * Sort by token 
-       */
-      if ((strcmp(tokens[j], tokens[j+1])) > 0) {
-        /* Swap the two elements */
-        tmp_token = tokens[j];
-        tmp_name = names[j];
-        tokens[j] = tokens[j+1];
-        names[j] = names[j+1];
-        tokens[j+1] = tmp_token;
-        names[j+1] = tmp_name;
-      }
-    }
-  }
-
-  /*
-   * print variables
-   */
-  fprintf(output, "\n");
-  for (i=0; i < n; i++) {
-    char tempName[MAX_NAME+1];
-    int l;
-    if (isdigit(names[i][0])) {
-      tempName[0] = '_';
-      strcpy(tempName+1, names[i]);
-    } else {
-      strcpy(tempName, names[i]);
-    }
-    l = (int)strlen(tempName);
-    for (j = 0; j < l; j++) {
-      if (isdigit(tempName[j])
-          || isalpha(tempName[j])
-          || (tempName[j] == '_')) {
-        continue;
-      }
-      tempName[j] = '_';
-    }
-    if (use_strings) {
-      fprintf(output, 
-              "static const NW_Ucs2 %sTag_%s[] = {"
-              , tagType, tempName);
-      for (j=0; j < (int) strlen(names[i]); j++) {
-        if (names[i][j] == '\\') {
-          fprintf(output, "\'\\\\\',");
-        } else {
-          fprintf(output, "\'%c\',", names[i][j]);
-        }
-      }
-      fprintf(output, "\'\\0\'};\n");
-    }
-  }
-  if (!use_strings) {
-    fprintf(output,
-            "static const NW_Ucs2 %sTag_emptyString_%s[] = { \'\\0\' };\n"
-            , tagType, code_page);
-  }
-  fprintf(output, "\n");
-
-  print_table_header(output, TOKEN_TABLE_T, type, key, code_page, n);
-  if (use_strings) {
-    fprintf(outputHeader, 
-            "\ntypedef enum %sToken_%s_e{\n", 
-            tagType, code_page);
-  }
- /*
-  * Print the table
-  */
-  for (i=0; i < n; i++) {
-    char tempName[MAX_NAME+1] ;
-    char tempToken[6] ;
-    char *token;
-    int l;
-    if (isdigit(names[i][0])) {
-      tempName[0] = '_';
-      strcpy(tempName+1, names[i]);
-    } else {
-      strcpy(tempName, names[i]);
-    }
-    l = (int)strlen(tempName);
-    for (j = 0; j < l; j++) {
-      if (isdigit(tempName[j])
-          || isalpha(tempName[j])
-          || (tempName[j] == '_')) {
-        continue;
-      }
-      tempName[j] = '_';
-    }
-    strcpy(tempToken, tokens[i]);
-    token = strchr(tempToken, 'x');
-    token++;
-    if (use_strings) {
-      fprintf(output, "\t{%s, (%s *) %sTag_%s", tokens[i], NAMES_T, tagType, tempName);
-      fprintf(outputHeader, "\t%s_%s = 0x0%s%s", tokenTypeString, tempName, code_page, token);
-    } else {
-      fprintf(output, "\t{%s, &%sTag_emptyString_%s", tokens[i], tagType, code_page);
-    }
-    
-    if (i == (n-1))
-    {
-      fprintf(output, "}\n");
-      if (use_strings) {
-        fprintf(outputHeader, "\n");
-      }
-    }
-    else
-    {
-      fprintf(output, "},\n");
-      if (use_strings) {
-        fprintf(outputHeader, ",\n");
-      }
-    }
-  }
-  fprintf(output, "};\n\n");
-  if (use_strings) {
-    fprintf(outputHeader, "}%sToken_%s_t;\n\n", tagType, code_page);
-  }
-
-  if (use_strings) {
-    /*
-    * Create an array of the names sorted by index
-    */
-    for (i=0; i < n-1; i++) {
-      for (j=0; j < n-1; j++) {
-        /*
-        * Since we will need an array of the names sorted by index,
-        * generate that arrary now.
-        */
-        if ((strcmp(names[j], names[j+1])) > 0) {
-          /* Swap the two names */
-          int tmp_token;
-          tmp_name = names[j];
-          tmp_token = sorted_indexes[j];
-          names[j] = names[j+1];
-          names[j+1] = tmp_name;
-          sorted_indexes[j] = sorted_indexes[j+1];
-          sorted_indexes[j+1] = tmp_token;
-        }
-      }
-    }
-  }
-}
-
-static void cache_codepage(codepage_t table[], char *cp_num, int n)
-{
-  int num = atoi(cp_num);
-
-  if (num >= TABLE_SIZE) {
-    fprintf(stderr, "ERROR: Codepage '%d' is too large!\n", num);
-    exit(1);
-  }
-
-  table[num].num = num; 
-  table[num].size = n; 
-}
-
-/*
- * Print a table of the names 
- */
-static void print_name_table(FILE *output, char *type, char *key, char *code_page, int n,
-                             int use_strings)
-{
-  int i;
-
-  print_table_header(output, NAME_TABLE_T, type, key, code_page, n);
-
-  for (i=0; i < n; i++) {
-    if (use_strings) {
-      fprintf(output, "\t%d,\n", sorted_indexes[i]);
-    } else {
-      fprintf(output, "\t0,\n");
-    }
-  }
-
-  fprintf(output, "};\n");
-}
-
-static process_content(FILE *f, FILE *output, FILE* outputHeader)
-{
-  char token[MAX_START_NAME+1]; /* Must be big enough to hold a 
-                                   tag/attr start string */
-  char name[MAX_NAME+1];
-  char optional[MAX_LINE+1];
-  char *tag_code_page = "";
-  char *attr_code_page = "";
-  char processing_tag = 2;  /* processing state: 1 = tag, 0 = attribute, 2 = init */
-  int n = 0;
-  int use_strings = 1;
-
-  for(;;) {
-
-    if ((get_tuple(f, token, name, optional)) != 1) {
-      break;
-    }
-
-    if (!strcmp(token, TAG_TABLE_HEADING)) {
-      use_strings = strcmp(optional, NO_STRINGS);
-      if (processing_tag == 1) {
-        /* Process the current tag table */
-        print_token_table(output, outputHeader, TAG_NAME, "token", tag_code_page, n, use_strings);
-        print_name_table(output, TAG_NAME, "name", tag_code_page, n, use_strings);
-        cache_codepage(tag_codepages, tag_code_page, n);
-        n = 0;
-      } else if (processing_tag == 0) {
-        /* Process the current attribute table */
-        print_token_table(output, outputHeader, ATTR_NAME, "token", attr_code_page, n, use_strings);
-        print_name_table(output, ATTR_NAME, "name", attr_code_page, n, use_strings);
-        cache_codepage(attr_codepages, attr_code_page, n);
-        n = 0;
-      }
-      tag_code_page = strdup(name);
-      processing_tag = 1;
-    }
-    else if (!strcmp(token, ATTR_TABLE_HEADING)) {
-      use_strings = strcmp(optional, NO_STRINGS);
-      if (processing_tag == 1) {
-        /* Process the current tag table */
-        print_token_table(output, outputHeader, TAG_NAME, "token", tag_code_page, n, use_strings);
-        print_name_table(output, TAG_NAME, "name", tag_code_page, n, use_strings);
-        cache_codepage(tag_codepages, tag_code_page, n);
-        n = 0;
-      } else if (processing_tag == 0) {
-        /* Process the current attribute table */
-        print_token_table(output, outputHeader, ATTR_NAME, "token", attr_code_page, n, use_strings);
-        print_name_table(output, ATTR_NAME, "name", attr_code_page, n, use_strings);
-        cache_codepage(attr_codepages, attr_code_page, n);
-        n = 0;
-      }
-      attr_code_page = strdup(name);
-      processing_tag = 0;
-    } else {
-      process_entry(n, token, name);
-      n++;
-    }
-  }
-
-  if (processing_tag == 2) {
-    fprintf(stderr, 
-            "ERROR: Could not find tag or attribute table starts in file.\n"
-            "       Input file syntax has changed.\n"
-            "       See usage by executing this program with no arguments.\n");
-    exit_error(1);
-  }
-
-  /*
-   * If anything is left, process it
-   */
-  if (n > 0) {
-    if (processing_tag == 1) {
-      print_token_table(output, outputHeader, TAG_NAME, "token", tag_code_page, n, use_strings);
-      print_name_table(output, TAG_NAME, "name", tag_code_page, n, use_strings);
-      cache_codepage(tag_codepages, tag_code_page, n);
-    } else if (processing_tag == 0) {
-      print_token_table(output, outputHeader, ATTR_NAME, "token", attr_code_page, n, use_strings);
-      print_name_table(output, ATTR_NAME, "name", attr_code_page, n, use_strings);
-      cache_codepage(attr_codepages, attr_code_page, n);
-    }
-  }
-}
-
-static void get_num_codepages(codepage_t cp[], int *n, int *max)
-{
-  int i;
-  /* Determine the number of codepages */
-  for (i=0; i < TABLE_SIZE; i++) {
-    if (cp[i].num != -1) {
-      *max = i;
-      (*n)++;
-    }
-  }
-}
-
-static void print_codepage_table(FILE *output, codepage_t cp[], int n, int max, char *type)
-{
-  int i;
-
-  if (n == 0)
-  return;
-
-  fprintf(output, "static const\n");
-  fprintf(output, "%s NW_%s_%s_codepages[%d] = {\n", CODEPAGE_TABLE_T, 
-      dict_name, type, max + 1);
-
-  for (i=0; i <= max && i < TABLE_SIZE; i++) {
-    if (cp[i].num == -1) {
-      fprintf(output, "\t{0, 0, 0},\n");
-    } else {
-      fprintf(output, "\t{%d, (%s*)&NW_%s_%s_token_%d[0], ", 
-      cp[i].size, TOKEN_TABLE_T, dict_name, type, cp[i].num);
-      fprintf(output, "(NW_Byte *)&NW_%s_%s_name_%d[0]},\n", 
-      dict_name, type, cp[i].num);
-    }
-  }
-  fprintf(output, "};\n");
-}
-
-static void print_codepage_tables(FILE *output) 
-{
-  int n=0, max=0;
-
-  /* Tag tables */
-  fprintf(output, 
-          "\n"
-          "/*\n"
-          " * Tag codepage table\n"
-          " */\n"
-          );
-
-  get_num_codepages(tag_codepages, &n, &max);
-  print_codepage_table(output, tag_codepages, n, max, TAG_NAME);
-
-  /* Attr tables */
-  fprintf(output, 
-          "\n"
-          "/*\n"
-          " * Attribute codepage table\n"
-          " */\n"
-          );
-
-  n = max = 0;
-  get_num_codepages(attr_codepages, &n, &max);
-  print_codepage_table(output, attr_codepages, n, max, ATTR_NAME);
-}
-
-static void add_codepage(FILE *output, codepage_t cp[], char *type)
-{
-  int n=0, max=0;
-
-  get_num_codepages(cp, &n, &max);
-
-  if (n == 0)
-    fprintf(output, "\t0, 0,\n");
-  else
-    fprintf(output, "\t%d, (%s*)&NW_%s_%s_codepages[0],\n", max + 1, CODEPAGE_TABLE_T, dict_name, type);
-}
-
-static void print_dictionary_table(FILE *output, FILE *outputHeader)
-{
-  int i;
-  if (strlen(doc_type) > 0)
-  {
-    fprintf(output, "\nstatic const NW_Ucs2 NW_%s_docType[] = {", dict_name);
-    for (i=0; i < (int) strlen(doc_type); i++)
-      fprintf(output, "\'%c\',", doc_type[i]);
-    fprintf(output, "\'\\0\'};\n");
-  }
-
-  fprintf(output, 
-          "\n"
-          "/*\n"
-          " * Dictionary\n"
-          " */\n"
-          );
-
-  fprintf(outputHeader, "extern const %s NW_%s_WBXMLDictionary\n",
-          DICTIONARY_TABLE_T, dict_name);
-  fprintf(output, "%s NW_%s_WBXMLDictionary = {\n", DICTIONARY_TABLE_T, dict_name);
-  fprintf(output, "\tNW_%s_PublicId,\n", dict_name);
-
-  /* Print the doc type as a UCS2 string */
-  fprintf(output, "\t(%s *)NW_%s_docType,\n", "NW_Ucs2", dict_name);
-
-  /* Add the tag and attribute code page */
-  add_codepage(output, tag_codepages, TAG_NAME);
-  add_codepage(output, attr_codepages, ATTR_NAME);
-
-  fprintf(output, "};\n");
-}
-
-static void process_file(FILE *f, FILE *output, FILE* outputHeader)
-{
-  process_header(f);
-
-  print_file_header(output, outputHeader);
-
-  process_content(f, output, outputHeader);
-
-  print_codepage_tables(output);
-
-  print_dictionary_table(output, outputHeader);
-}
-
-int main(int argc, char ** argv){
-  if (argc < 4) {
-    print_usage(argv[0]);
-    exit_error(1);
-  }
-
-  init();
-
-  input_dict = NULL;
-  output_c = NULL;
-  output_h = NULL;
-
-  /* ----------------------------------------------------------------------- **
-     Save info used in print_automaticallyGeneratedCodeWarning()   
-  ** ----------------------------------------------------------------------- **/
-  (void)time(&timestamp);
-  main_argc = argc;
-  main_argv = argv;
-
-
-  /* ----------------------------------------------------------------------- **
-     Work on files in text mode to ease end-of-line processing in DOS.  
-  ** ----------------------------------------------------------------------- **/
-  if ((input_dict = open_file(argv[1], "rt")) == NULL) {
-    fprintf(stderr, "ERROR: Input File '%s' could NOT be opened!\n", argv[1]);
-    exit_error(1);
-  }
-
-  if ((output_c = open_file(argv[2], "wt")) == NULL) {
-    fprintf(stderr, "ERROR: Output .c File '%s' could NOT be opened!\n", argv[2]);
-    exit_error(1);
-  }
-
-  if ((output_h = open_file(argv[3], "wt")) == NULL) {
-    fprintf(stderr, "ERROR: Output .h File '%s' could NOT be opened!\n", argv[3]);
-    exit_error(1);
-  }
-
-  print_copyright(output_c);
-  fprintf(output_c, "\n\n");
-  print_automaticallyGeneratedCodeWarning(output_c);
-  fprintf(output_c, "\n\n");
-
-  print_copyright(output_h);
-  fprintf(output_h, "\n\n");
-  print_automaticallyGeneratedCodeWarning(output_h);
-  fprintf(output_h, "\n\n");
-
-  {
-    int l;
-    char* p = strrchr(argv[3], '.');
-    l = (p == NULL) ? (int)strlen(argv[3]) : p - argv[3];
-
-    fprintf(output_h, "#ifndef HEADER_GUARD_%.*s", l, argv[3]);
-    if (p != NULL) fprintf(output_h, "_%s", p+1);
-    fprintf(output_h,
-            "\n"
-            "#define HEADER_GUARD_%.*s"
-            , l, argv[3]);
-    if (p != NULL) fprintf(output_h, "_%s", p+1);
-    fprintf(output_h, 
-            "\n"
-            "\n"
-            "#ifdef __cplusplus\n"
-            "extern \"C\"\n"
-            "{\n"
-            "#endif\n"
-            "\n"
-            "\n"
-            );
-  }
-
-  /* process input */
-  process_file(input_dict, output_c, output_h);
-
-  fprintf(output_c, "\n");
-  print_automaticallyGeneratedCodeWarning(output_c);
-
-  fprintf(output_c, "\n");
-  fprintf(output_h, "\n");
-  print_automaticallyGeneratedCodeWarning(output_h);
-
-  fprintf(output_h,
-          "\n"
-          "\n"
-          "#ifdef __cplusplus\n"
-          "} /* extern \"C\" */\n"
-          "#endif\n"
-          "\n"
-          "#endif\n"
-          );
-  
-  /* close files */
-  fclose(input_dict);
-  fclose(output_c);
-  fclose(output_h);
-
-  return 0;
-}