diff -r 889504eac4fb -r 604ca70b6235 xml/cxmllibrary/dictionary/dict_creator.c --- 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 -#include -#include -#include -#include -#include - - -/* ----------------------------------------------------------------------- ** - 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 [NO_STRINGS]\n" - "\n" - " 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 [NO_STRINGS]\n" - " \n" - " 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" - " \n" - "\n" - " 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" - " 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(×tamp))); /* 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(×tamp); - 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(×tamp); - 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; -}