mirror of https://github.com/nirenjan/libx52.git
Convert character map generator to Python script
The conversion makes it simpler to allow cross-compilation, since we should be using the host Python interpreter to build the generated character map, rather than relying on the automake infrastructure.pull/10/head
parent
abaa36f35e
commit
bc9001705d
|
@ -1,8 +1,9 @@
|
||||||
AC_INIT([x52pro-linux], [0.1.0], [nirenjan@gmail.com])
|
AC_INIT([x52pro-linux], [0.1.1], [nirenjan@gmail.com])
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
|
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
AM_PROG_AR
|
AM_PROG_AR
|
||||||
|
AM_PATH_PYTHON([2.6])
|
||||||
LT_INIT
|
LT_INIT
|
||||||
|
|
||||||
# Check for libusb-1.0
|
# Check for libusb-1.0
|
||||||
|
|
|
@ -10,17 +10,14 @@ libx52util_la_LDFLAGS = -version-info 1:0:0
|
||||||
libx52util_la_LIBADD = ../libx52/libx52.la
|
libx52util_la_LIBADD = ../libx52/libx52.la
|
||||||
|
|
||||||
# Header files that need to be copied
|
# Header files that need to be copied
|
||||||
# pkginclude_HEADERS =
|
pkginclude_HEADERS = libx52util.h
|
||||||
|
|
||||||
# Extra files that need to be in the distribution
|
# Extra files that need to be in the distribution
|
||||||
EXTRA_DIST = x52_char_map.cfg \
|
EXTRA_DIST = x52_char_map.cfg \
|
||||||
x52_char_map.h
|
x52_char_map.h \
|
||||||
|
x52_char_map_gen.py
|
||||||
# Character map generator
|
|
||||||
noinst_PROGRAMS = x52charmapgen
|
|
||||||
x52charmapgen_SOURCES = char_map_parser_gen.c
|
|
||||||
|
|
||||||
# Autogenerated file that needs to be cleaned up
|
# Autogenerated file that needs to be cleaned up
|
||||||
CLEANFILES = util_char_map.c
|
CLEANFILES = util_char_map.c
|
||||||
util_char_map.c: $(srcdir)/x52_char_map.cfg x52charmapgen$(EXEEXT)
|
util_char_map.c: $(srcdir)/x52_char_map.cfg x52_char_map_gen.py
|
||||||
$(AM_V_GEN) ./x52charmapgen$(EXEEXT) $(srcdir)/x52_char_map.cfg $@
|
$(AM_V_GEN) ./x52_char_map_gen.py $(srcdir)/x52_char_map.cfg $@
|
||||||
|
|
|
@ -1,309 +0,0 @@
|
||||||
/*
|
|
||||||
* Saitek X52 Pro Character Map Parser and Generator
|
|
||||||
*
|
|
||||||
* This file takes in an input map and converts it to a C file which implements
|
|
||||||
* a lookup table to match the input UTF-8 character to the corresponding
|
|
||||||
* character map value.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2015 Nirenjan Krishnan (nirenjan@nirenjan.org)
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License as
|
|
||||||
* published by the Free Software Foundation, version 2.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#include "x52_char_map.h"
|
|
||||||
|
|
||||||
struct map_table {
|
|
||||||
struct map_table *next;
|
|
||||||
uint32_t value_so_far;
|
|
||||||
uint16_t type;
|
|
||||||
uint8_t value;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct map_table *root;
|
|
||||||
|
|
||||||
struct stack_node {
|
|
||||||
struct stack_node *next;
|
|
||||||
struct map_table *entry;
|
|
||||||
uint32_t value;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct stack_node *stack;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Convert Unicode code point to UTF-8 bytearray. The bytearray should be
|
|
||||||
* at least 8 bytes long to accomodate for the longest possible value of
|
|
||||||
* Unicode code point and a terminating NUL byte.
|
|
||||||
*/
|
|
||||||
static void convert_unichr_to_utf8(int unicode_cp, char *utf8_bytearray)
|
|
||||||
{
|
|
||||||
if (unicode_cp <= 0x7F) {
|
|
||||||
utf8_bytearray[0] = unicode_cp;
|
|
||||||
utf8_bytearray[1] = 0;
|
|
||||||
} else if (unicode_cp <= 0x7FF) {
|
|
||||||
utf8_bytearray[0] = 0xC0 | ((unicode_cp & 0x7C0) >> 6);
|
|
||||||
utf8_bytearray[1] = 0x80 | (unicode_cp & 0x03F);
|
|
||||||
utf8_bytearray[2] = 0;
|
|
||||||
} else if (unicode_cp <= 0xFFFF) {
|
|
||||||
utf8_bytearray[0] = 0xE0 | ((unicode_cp & 0xF000) >> 12);
|
|
||||||
utf8_bytearray[1] = 0x80 | ((unicode_cp & 0x0FC0) >> 6);
|
|
||||||
utf8_bytearray[2] = 0x80 | (unicode_cp & 0x003F);
|
|
||||||
utf8_bytearray[3] = 0;
|
|
||||||
} else if (unicode_cp <= 0x1FFFFF) {
|
|
||||||
utf8_bytearray[0] = 0xF0 | ((unicode_cp & 0x1C0000) >> 18);
|
|
||||||
utf8_bytearray[1] = 0x80 | ((unicode_cp & 0x03F000) >> 12);
|
|
||||||
utf8_bytearray[2] = 0x80 | ((unicode_cp & 0x000FC0) >> 6);
|
|
||||||
utf8_bytearray[3] = 0x80 | (unicode_cp & 0x00003F);
|
|
||||||
utf8_bytearray[4] = 0;
|
|
||||||
} else if (unicode_cp <= 0x3FFFFFF) {
|
|
||||||
utf8_bytearray[0] = 0xF8 | ((unicode_cp & 0x3000000) >> 24);
|
|
||||||
utf8_bytearray[1] = 0x80 | ((unicode_cp & 0x0FC0000) >> 18);
|
|
||||||
utf8_bytearray[2] = 0x80 | ((unicode_cp & 0x003F000) >> 12);
|
|
||||||
utf8_bytearray[3] = 0x80 | ((unicode_cp & 0x0000FC0) >> 6);
|
|
||||||
utf8_bytearray[4] = 0x80 | (unicode_cp & 0x000003F);
|
|
||||||
utf8_bytearray[5] = 0;
|
|
||||||
} else /* if (unicode_cp <= 0x7FFFFFFF) */ {
|
|
||||||
utf8_bytearray[0] = 0xFC | ((unicode_cp & 0x40000000) >> 30);
|
|
||||||
utf8_bytearray[1] = 0x80 | ((unicode_cp & 0x3F000000) >> 24);
|
|
||||||
utf8_bytearray[2] = 0x80 | ((unicode_cp & 0x00FC0000) >> 18);
|
|
||||||
utf8_bytearray[3] = 0x80 | ((unicode_cp & 0x0003F000) >> 12);
|
|
||||||
utf8_bytearray[4] = 0x80 | ((unicode_cp & 0x00000FC0) >> 6);
|
|
||||||
utf8_bytearray[5] = 0x80 | (unicode_cp & 0x0000003F);
|
|
||||||
utf8_bytearray[6] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int stack_push(struct map_table *entry, int value)
|
|
||||||
{
|
|
||||||
struct stack_node *node = calloc(1, sizeof(*node));
|
|
||||||
|
|
||||||
if (!node) {
|
|
||||||
fprintf(stderr, "Cannot allocate memory for stack node!\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
node->entry = entry;
|
|
||||||
node->value = value;
|
|
||||||
node->next = stack;
|
|
||||||
stack = node;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int stack_pop(struct stack_node *node)
|
|
||||||
{
|
|
||||||
struct stack_node *temp;
|
|
||||||
|
|
||||||
if (stack) {
|
|
||||||
*node = *stack;
|
|
||||||
|
|
||||||
temp = stack;
|
|
||||||
stack = stack->next;
|
|
||||||
free(temp);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int add_to_mem(int input_val, int map_val)
|
|
||||||
{
|
|
||||||
uint8_t bytearray[8];
|
|
||||||
int i;
|
|
||||||
int value_so_far = 0;
|
|
||||||
uint8_t c;
|
|
||||||
struct map_table *level;
|
|
||||||
struct map_table *temp;
|
|
||||||
|
|
||||||
if (!root) {
|
|
||||||
root = calloc(256, sizeof(*root));
|
|
||||||
if (!root) {
|
|
||||||
fprintf(stderr, "Cannot allocate memory for root node!\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!stack_push(root, 0)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
convert_unichr_to_utf8(input_val, bytearray);
|
|
||||||
level = root;
|
|
||||||
for (i = 0; bytearray[i]; i++) {
|
|
||||||
c = bytearray[i];
|
|
||||||
value_so_far <<= 8;
|
|
||||||
value_so_far |= c;
|
|
||||||
if (bytearray[i+1]) {
|
|
||||||
level[c].type = TYPE_POINTER;
|
|
||||||
if (!level[c].next) {
|
|
||||||
temp = calloc(256, sizeof(*temp));
|
|
||||||
if (!temp) {
|
|
||||||
fprintf(stderr, "Cannot allocate memory for entry table!\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (!stack_push(temp, value_so_far)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
level[c].value_so_far = value_so_far;
|
|
||||||
level[c].next = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
level = level[c].next;
|
|
||||||
} else {
|
|
||||||
level[c].type = TYPE_ENTRY;
|
|
||||||
level[c].value = map_val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Parse an input line and return the input value and map value
|
|
||||||
* For comment lines, or invalid lines, returned input value is 0.
|
|
||||||
*
|
|
||||||
* For invalid lines, return value is 0
|
|
||||||
* For valid lines, return value is 1
|
|
||||||
* For comment lines, return value is 2
|
|
||||||
*/
|
|
||||||
static int parse_line(char *line, int *input_value, int *map_value)
|
|
||||||
{
|
|
||||||
const char *format_str1 = " 0x%x 0x%x";
|
|
||||||
const char *format_str2 = " 0x%x %c";
|
|
||||||
int ret;
|
|
||||||
int val1;
|
|
||||||
int val2;
|
|
||||||
char c;
|
|
||||||
|
|
||||||
/* Strip off leading whitespace */
|
|
||||||
while (*line && isspace(*line)) line++;
|
|
||||||
|
|
||||||
/* If line begins with # or is empty, it's a comment line */
|
|
||||||
if (line[0] == '#' || line[0] == '\0') {
|
|
||||||
/* Comment line */
|
|
||||||
*input_value = 0;
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Try to match input against format_str1 */
|
|
||||||
ret = sscanf(line, format_str1, &val1, &val2);
|
|
||||||
if (ret == 2) {
|
|
||||||
/* We have a match! */
|
|
||||||
*input_value = val1;
|
|
||||||
*map_value = val2;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Try to match input against format_str2 */
|
|
||||||
ret = sscanf(line, format_str2, &val1, &c);
|
|
||||||
if (ret == 2) {
|
|
||||||
/* We have a match! */
|
|
||||||
*input_value = val1;
|
|
||||||
*map_value = c;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Neither format string matched, and it's not a comment line. Abort */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void write_output(FILE *dest)
|
|
||||||
{
|
|
||||||
struct stack_node node;
|
|
||||||
int i;
|
|
||||||
int start;
|
|
||||||
int end;
|
|
||||||
|
|
||||||
while (stack_pop(&node)) {
|
|
||||||
if (node.value) {
|
|
||||||
fprintf(dest, "static struct map_entry table_%x[64] = {\n", node.value);
|
|
||||||
start = 0x80;
|
|
||||||
end = 0xC0;
|
|
||||||
} else {
|
|
||||||
fprintf(dest, "struct map_entry map_root[256] = {\n");
|
|
||||||
start = 0;
|
|
||||||
end = 256;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = start; i < end; i++) {
|
|
||||||
if (node.entry[i].next) {
|
|
||||||
fprintf(dest, "\t[0x%02x] = { table_%x, TYPE_POINTER, 0 },\n",
|
|
||||||
i - start, node.entry[i].value_so_far);
|
|
||||||
} else if (node.entry[i].type == TYPE_ENTRY) {
|
|
||||||
fprintf(dest, "\t[0x%02x] = { NULL, TYPE_ENTRY, 0x%02x },\n",
|
|
||||||
i - start, node.entry[i].value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(dest, "};\n\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dummy(void)
|
|
||||||
{
|
|
||||||
printf("Dummy function for breakpoint trap\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
FILE *input = NULL;
|
|
||||||
FILE *output = NULL;
|
|
||||||
char buffer[512];
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
#define EXIT(v) do { rc = (v); goto exit_handler; } while (0)
|
|
||||||
|
|
||||||
if (argc < 3) {
|
|
||||||
fprintf(stderr, "Usage: %s <input-map> <output-c-file>\n", argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
input = fopen(argv[1], "r");
|
|
||||||
if (!input) {
|
|
||||||
fprintf(stderr, "Unable to read input file %s\n", argv[1]);
|
|
||||||
EXIT(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
output = fopen(argv[2], "w");
|
|
||||||
if (!output) {
|
|
||||||
fprintf(stderr, "Unable to write output file %s\n", argv[2]);
|
|
||||||
EXIT(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (fgets(buffer, sizeof(buffer), input)) {
|
|
||||||
int input_val;
|
|
||||||
int map_val;
|
|
||||||
if (!parse_line(buffer, &input_val, &map_val)) {
|
|
||||||
fprintf(stderr, "Invalid line: %s\n", buffer);
|
|
||||||
EXIT(3);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!add_to_mem(input_val, map_val)) {
|
|
||||||
EXIT(4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write header for output file */
|
|
||||||
fputs("/*\n", output);
|
|
||||||
fputs(" * Autogenerated character map file for Saitek X52 Pro\n", output);
|
|
||||||
fputs(" * Generated from ", output);
|
|
||||||
fputs(argv[1], output);
|
|
||||||
fputs("\n */\n\n", output);
|
|
||||||
fputs("#include \"x52_char_map.h\"\n", output);
|
|
||||||
fputs("\n\n", output);
|
|
||||||
|
|
||||||
write_output(output);
|
|
||||||
|
|
||||||
exit_handler:
|
|
||||||
if (output) fclose(output);
|
|
||||||
if (input) fclose(input);
|
|
||||||
return rc;
|
|
||||||
}
|
|
|
@ -26,7 +26,7 @@
|
||||||
0x0020 0x20
|
0x0020 0x20
|
||||||
0x0021 !
|
0x0021 !
|
||||||
0x0022 "
|
0x0022 "
|
||||||
0x0023 #
|
0x0023 0x23 # Can't really use the # character as the parser strips it out
|
||||||
0x0024 $
|
0x0024 $
|
||||||
0x0025 %
|
0x0025 %
|
||||||
0x0026 &
|
0x0026 &
|
||||||
|
|
|
@ -0,0 +1,166 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# Character map generator
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
import inspect
|
||||||
|
|
||||||
|
autogen_header = """
|
||||||
|
/*
|
||||||
|
* Autogenerated character map file for Saitek X52 Pro
|
||||||
|
* Generated from %s
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "x52_char_map.h"
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
class MapTable():
|
||||||
|
"""
|
||||||
|
Defines a MapTable entry, with each entry storing the value seen so far,
|
||||||
|
the type of the entry, and the value, if it's a value node.
|
||||||
|
"""
|
||||||
|
# Empty list
|
||||||
|
root = [None] * 256
|
||||||
|
|
||||||
|
def __init__(self, value_so_far, map_value = None):
|
||||||
|
self.next_level = [None] * 256
|
||||||
|
self.value_so_far = value_so_far
|
||||||
|
self.map_value = map_value
|
||||||
|
|
||||||
|
def output_nodes(self):
|
||||||
|
output_lines = []
|
||||||
|
output_count = 0
|
||||||
|
for node in self.next_level:
|
||||||
|
if node is not None:
|
||||||
|
output_lines.extend(node.output_nodes())
|
||||||
|
output_count += 1
|
||||||
|
|
||||||
|
if output_count != 0:
|
||||||
|
struct_header = 'static struct map_entry table_%x[64] = {' % self.value_so_far
|
||||||
|
output_lines.append(struct_header)
|
||||||
|
|
||||||
|
for node_index in range(0,256):
|
||||||
|
node = self.next_level[node_index]
|
||||||
|
if node is not None:
|
||||||
|
output_lines.append(self.dump_entry_line(0x80, node_index,
|
||||||
|
node.value_so_far, node.map_value))
|
||||||
|
|
||||||
|
output_lines.extend(['};', ''])
|
||||||
|
|
||||||
|
return output_lines
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def dump_entry_line(offset, node_index, value_so_far, map_value):
|
||||||
|
if map_value is None:
|
||||||
|
node_entry_line = '\t[0x%02x] = { table_%x, TYPE_POINTER, 0 },' % \
|
||||||
|
(node_index - offset, value_so_far)
|
||||||
|
else:
|
||||||
|
node_entry_line = '\t[0x%02x] = { NULL, TYPE_ENTRY, 0x%02x },' % \
|
||||||
|
(node_index - offset, map_value)
|
||||||
|
|
||||||
|
return node_entry_line
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add_to_table(cls, input_val, map_val):
|
||||||
|
utf8_str = unichr(input_val).encode('utf-8')
|
||||||
|
utf8_vals = [ord(c) for c in utf8_str]
|
||||||
|
|
||||||
|
value_so_far = 0
|
||||||
|
level = cls.root
|
||||||
|
for i in range(len(utf8_vals)):
|
||||||
|
c = utf8_vals[i]
|
||||||
|
value_so_far = (value_so_far << 8) | c
|
||||||
|
if i < (len(utf8_vals) - 1):
|
||||||
|
node = level[c]
|
||||||
|
if node is None:
|
||||||
|
node = cls(value_so_far)
|
||||||
|
level[c] = node
|
||||||
|
|
||||||
|
level = level[c].next_level
|
||||||
|
else:
|
||||||
|
node = cls(value_so_far, map_val)
|
||||||
|
level[c] = node
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def output_table_as_list(cls):
|
||||||
|
output_lines = []
|
||||||
|
for node in cls.root:
|
||||||
|
if node is not None:
|
||||||
|
output_lines.extend(node.output_nodes())
|
||||||
|
|
||||||
|
output_lines.append('struct map_entry map_root[256] = {')
|
||||||
|
|
||||||
|
for node_index in range(0,256):
|
||||||
|
node = cls.root[node_index]
|
||||||
|
if node is not None:
|
||||||
|
output_lines.append(cls.dump_entry_line(0x0, node_index,
|
||||||
|
node.value_so_far, node.map_value))
|
||||||
|
|
||||||
|
output_lines.extend(['};', ''])
|
||||||
|
|
||||||
|
return output_lines
|
||||||
|
|
||||||
|
class LineFormatError(ValueError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def parse_line(line):
|
||||||
|
"""
|
||||||
|
Parse a line containing a mapping descriptor. The mapping descriptor
|
||||||
|
must start with a hexadecimal unicode code point, followed by either a
|
||||||
|
single character, or a hexadecimal integer that corresponds to the map
|
||||||
|
value.
|
||||||
|
"""
|
||||||
|
# Strip off comments
|
||||||
|
line = re.sub(re.compile('#.*$'), '', line)
|
||||||
|
|
||||||
|
# Strip off leading and trailing whitespace
|
||||||
|
line = line.strip()
|
||||||
|
|
||||||
|
# If the line is empty, it is a comment line
|
||||||
|
if len(line) == 0:
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
# Find the code point and the target value
|
||||||
|
try:
|
||||||
|
code_point, target = line.strip().split()
|
||||||
|
except ValueError:
|
||||||
|
# Raised when there are either too many, or not enough values in
|
||||||
|
# the string
|
||||||
|
raise LineFormatError('Invalid descriptor format "%s"' % line)
|
||||||
|
|
||||||
|
# Convert the string to its equivalent numeric value
|
||||||
|
try:
|
||||||
|
code_point = int(code_point, 0)
|
||||||
|
except ValueError:
|
||||||
|
raise LineFormatError('Invalid code point "%s"' % code_point)
|
||||||
|
|
||||||
|
# Check if the target is a single character
|
||||||
|
if len(target) == 1:
|
||||||
|
target = ord(target)
|
||||||
|
else:
|
||||||
|
# Try parsing the target as an integer
|
||||||
|
try:
|
||||||
|
target = int(target, 0)
|
||||||
|
except ValueError:
|
||||||
|
raise LineFormatError('Invalid map value "%s"' % target)
|
||||||
|
|
||||||
|
return code_point, target
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) != 3:
|
||||||
|
sys.stderr.write('Usage: %s <input-map> <output-c-file>\n' % sys.argv[0])
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
with open(sys.argv[1], 'r') as infile:
|
||||||
|
for line in infile:
|
||||||
|
src, dst = parse_line(line)
|
||||||
|
if src is not None:
|
||||||
|
MapTable.add_to_table(src,dst)
|
||||||
|
|
||||||
|
with open(sys.argv[2], 'w') as outfile:
|
||||||
|
outfile.write(autogen_header % sys.argv[1])
|
||||||
|
|
||||||
|
for line in MapTable.output_table_as_list():
|
||||||
|
outfile.write(line + '\n')
|
||||||
|
|
Loading…
Reference in New Issue