sl@0
|
1 |
# Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
|
sl@0
|
2 |
# All rights reserved.
|
sl@0
|
3 |
# This component and the accompanying materials are made available
|
sl@0
|
4 |
# under the terms of "Eclipse Public License v1.0"
|
sl@0
|
5 |
# which accompanies this distribution, and is available
|
sl@0
|
6 |
# at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
sl@0
|
7 |
#
|
sl@0
|
8 |
# Initial Contributors:
|
sl@0
|
9 |
# Nokia Corporation - initial contribution.
|
sl@0
|
10 |
#
|
sl@0
|
11 |
# Contributors:
|
sl@0
|
12 |
#
|
sl@0
|
13 |
# Description:
|
sl@0
|
14 |
#
|
sl@0
|
15 |
|
sl@0
|
16 |
use strict;
|
sl@0
|
17 |
|
sl@0
|
18 |
## Used as global variables, probably need to change and pass variables through as parameters.
|
sl@0
|
19 |
my %globalValues=();
|
sl@0
|
20 |
##initialise filenames
|
sl@0
|
21 |
$globalValues{'inputFile'} = 'mglyphs.txt';
|
sl@0
|
22 |
$globalValues{'outputFileName'} = 'mglyphs.inl';
|
sl@0
|
23 |
$globalValues{'htmlFileName'} = 'mglyphs.html';
|
sl@0
|
24 |
$globalValues{'lgtablesize'} = 9; # Default tablesize value is 512
|
sl@0
|
25 |
$globalValues{'tablesize'} = 1 << $globalValues{'lgtablesize'};
|
sl@0
|
26 |
$globalValues{'storeashex'} = 0;
|
sl@0
|
27 |
$globalValues{'stepOffset'} = 72;
|
sl@0
|
28 |
$globalValues{'stepShift'} = 0;
|
sl@0
|
29 |
|
sl@0
|
30 |
## die if the correct number of argumements have not been entered
|
sl@0
|
31 |
&extractFlags(\@ARGV, \%globalValues);
|
sl@0
|
32 |
&printDebug("Remainder:$globalValues{'tablesize'}\n");
|
sl@0
|
33 |
&printDebug("StoreAsHex:$globalValues{'storeashex'}\n");
|
sl@0
|
34 |
|
sl@0
|
35 |
if ($globalValues{"information"})
|
sl@0
|
36 |
{
|
sl@0
|
37 |
&dieShowingUsage();
|
sl@0
|
38 |
}
|
sl@0
|
39 |
|
sl@0
|
40 |
&printDebug("Creating HashTable....\n");
|
sl@0
|
41 |
my %hashTable = &createHashTable($globalValues{'inputFile'});
|
sl@0
|
42 |
if (!defined(%hashTable))
|
sl@0
|
43 |
{
|
sl@0
|
44 |
die("ERROR: Hash table was not created\n");
|
sl@0
|
45 |
}
|
sl@0
|
46 |
if ($globalValues{"outputtohtml"})
|
sl@0
|
47 |
{
|
sl@0
|
48 |
my $htmlFileName = $globalValues{'htmlFileName'};
|
sl@0
|
49 |
&printDebug("Creating HTML output to file: $htmlFileName\n");
|
sl@0
|
50 |
&createHTMLOfMappings($htmlFileName, %hashTable);
|
sl@0
|
51 |
}
|
sl@0
|
52 |
my $outputFileName = $globalValues{'outputFileName'};
|
sl@0
|
53 |
&printDebug("Writing Hash table to file: $outputFileName\n");
|
sl@0
|
54 |
&writeHashTableToFile($outputFileName, %hashTable);
|
sl@0
|
55 |
&printDebug("$outputFileName created.");
|
sl@0
|
56 |
|
sl@0
|
57 |
##################### end of main section
|
sl@0
|
58 |
sub extractFlags
|
sl@0
|
59 |
{
|
sl@0
|
60 |
my $aArgumentArray=shift;
|
sl@0
|
61 |
my $aArguments=shift;
|
sl@0
|
62 |
my $expectedArg = 'lgtablesize';
|
sl@0
|
63 |
my $expectedExtension;
|
sl@0
|
64 |
foreach my $argument (@$aArgumentArray)
|
sl@0
|
65 |
{
|
sl@0
|
66 |
if ($argument =~ m!^[-/]([a-zA-Z].*)$!)
|
sl@0
|
67 |
{
|
sl@0
|
68 |
my $switch = $1;
|
sl@0
|
69 |
$expectedArg = 'lgtablesize';
|
sl@0
|
70 |
$expectedExtension = undef;
|
sl@0
|
71 |
if ($switch=~/^(x|hexoutput)$/i)
|
sl@0
|
72 |
{
|
sl@0
|
73 |
$$aArguments{'storeashex'}=1;
|
sl@0
|
74 |
}
|
sl@0
|
75 |
elsif ($switch=~/^(\?|help)$/i)
|
sl@0
|
76 |
{
|
sl@0
|
77 |
$$aArguments{'information'}=1;
|
sl@0
|
78 |
}
|
sl@0
|
79 |
elsif ($switch=~/^(v|verbose)$/i)
|
sl@0
|
80 |
{
|
sl@0
|
81 |
$$aArguments{'verbose'}=1;
|
sl@0
|
82 |
}
|
sl@0
|
83 |
elsif ($switch=~/^(h|outputtohtml)$/i)
|
sl@0
|
84 |
{
|
sl@0
|
85 |
$$aArguments{'outputtohtml'}=1;
|
sl@0
|
86 |
$expectedArg = 'htmlFileName';
|
sl@0
|
87 |
$expectedExtension = '.html';
|
sl@0
|
88 |
}
|
sl@0
|
89 |
elsif ($switch=~/^(i|input)$/i)
|
sl@0
|
90 |
{
|
sl@0
|
91 |
$expectedArg = 'inputFile';
|
sl@0
|
92 |
}
|
sl@0
|
93 |
elsif ($switch=~/^(o|output)$/i)
|
sl@0
|
94 |
{
|
sl@0
|
95 |
$expectedArg = 'outputFileName';
|
sl@0
|
96 |
$expectedExtension = '.inl';
|
sl@0
|
97 |
}
|
sl@0
|
98 |
elsif ($switch=~/^(offset)$/i)
|
sl@0
|
99 |
{
|
sl@0
|
100 |
$expectedArg = 'stepOffset';
|
sl@0
|
101 |
}
|
sl@0
|
102 |
elsif ($switch=~/^(shift)$/i)
|
sl@0
|
103 |
{
|
sl@0
|
104 |
$expectedArg = 'stepShift';
|
sl@0
|
105 |
}
|
sl@0
|
106 |
}
|
sl@0
|
107 |
else
|
sl@0
|
108 |
{
|
sl@0
|
109 |
if (defined $expectedExtension && $argument !~ m!\.[^/\\]*$!)
|
sl@0
|
110 |
{
|
sl@0
|
111 |
$argument .= $expectedExtension;
|
sl@0
|
112 |
}
|
sl@0
|
113 |
$$aArguments{$expectedArg} = $argument;
|
sl@0
|
114 |
$expectedArg = 'lgtablesize';
|
sl@0
|
115 |
}
|
sl@0
|
116 |
}
|
sl@0
|
117 |
$globalValues{'tablesize'} = 1 << $globalValues{'lgtablesize'};
|
sl@0
|
118 |
$globalValues{'stepOffset'} &= 0xFFFFFE;
|
sl@0
|
119 |
}
|
sl@0
|
120 |
#####################
|
sl@0
|
121 |
sub dieShowingUsage
|
sl@0
|
122 |
{
|
sl@0
|
123 |
print <<USAGE_EOF;
|
sl@0
|
124 |
|
sl@0
|
125 |
Usage:
|
sl@0
|
126 |
|
sl@0
|
127 |
perl -w mglyphtool.pl [-?] [<lg-table-size>] [-x] [-i <input-file-name>]
|
sl@0
|
128 |
[-o <output-file-name>] [-h [<output-html-file-name]]
|
sl@0
|
129 |
[-offset <value-for-offset>] [-shift <value-for-shift>]
|
sl@0
|
130 |
|
sl@0
|
131 |
<lg-table-size> the default log(base 2) table size is 9. This gives a table
|
sl@0
|
132 |
size of 512 entries (2 to the power 9). So 7 gives a size of 128, 8 gives
|
sl@0
|
133 |
256, 9 gives 512, 10 gives 1024 and so on.
|
sl@0
|
134 |
|
sl@0
|
135 |
options: -x -o -i -h
|
sl@0
|
136 |
|
sl@0
|
137 |
-? Shows help
|
sl@0
|
138 |
|
sl@0
|
139 |
The -x flag stores values into the .inl file in hex format:
|
sl@0
|
140 |
hex(OriginalKeyCodeMirrorGlyphCode),
|
sl@0
|
141 |
By default the values are stored in string hex format i.e 0x220C2209
|
sl@0
|
142 |
|
sl@0
|
143 |
The -h flag generates a html file displaying hash table information.
|
sl@0
|
144 |
This may be followed by the filename to be output.
|
sl@0
|
145 |
Default is 'mglyphs.html'
|
sl@0
|
146 |
|
sl@0
|
147 |
The -i file specifies input file name. Default is 'mglyphs.txt'.
|
sl@0
|
148 |
|
sl@0
|
149 |
The -o file specifies output file name. Default is 'mglyphs.inl'.
|
sl@0
|
150 |
|
sl@0
|
151 |
-shift and -offset alter the "step" hash algorithm.
|
sl@0
|
152 |
|
sl@0
|
153 |
USAGE_EOF
|
sl@0
|
154 |
exit 0;
|
sl@0
|
155 |
}
|
sl@0
|
156 |
#########
|
sl@0
|
157 |
#
|
sl@0
|
158 |
# Writes a hash table to file.
|
sl@0
|
159 |
# Current format:
|
sl@0
|
160 |
# Hex mode: "hex number created"
|
sl@0
|
161 |
# Hex string mode: "Original keyMapped key"
|
sl@0
|
162 |
#####################
|
sl@0
|
163 |
sub writeHashTableToFile
|
sl@0
|
164 |
{
|
sl@0
|
165 |
&printDebug("Writing to .inl file");
|
sl@0
|
166 |
my ($aOutputFileName, %aHashTable) = @_;
|
sl@0
|
167 |
open(OUTPUT_FILE, '> ' . $aOutputFileName) or die('Error: could not open $aOutputFileName to write to\n');
|
sl@0
|
168 |
## Print comments at top of .inl file
|
sl@0
|
169 |
printf(OUTPUT_FILE "\/\/ mGlyphs.inl\n");
|
sl@0
|
170 |
printf(OUTPUT_FILE "\/\/\n");
|
sl@0
|
171 |
printf(OUTPUT_FILE "\/\/ Generated by mglyphtool.pl from '$globalValues{'inputFile'}'\n");
|
sl@0
|
172 |
printf(OUTPUT_FILE "\/\/\n\n");
|
sl@0
|
173 |
## Declare array and fill in values
|
sl@0
|
174 |
printf(OUTPUT_FILE "const unsigned long mGlyphArray[] = {\n\t");
|
sl@0
|
175 |
for (my $counter = 0; $counter < $globalValues{'tablesize'}; $counter++)
|
sl@0
|
176 |
{
|
sl@0
|
177 |
my $storeValue = "00000000";
|
sl@0
|
178 |
if (defined($aHashTable{$counter}))
|
sl@0
|
179 |
{
|
sl@0
|
180 |
$storeValue = $aHashTable{$counter};
|
sl@0
|
181 |
}
|
sl@0
|
182 |
$storeValue = ($globalValues{'storeashex'}) ? hex($storeValue) : "0x$storeValue";
|
sl@0
|
183 |
print OUTPUT_FILE $storeValue;
|
sl@0
|
184 |
if (($counter+1) < $globalValues{'tablesize'})
|
sl@0
|
185 |
{
|
sl@0
|
186 |
print OUTPUT_FILE (($counter + 1) % 8 == 0? ",\n\t" : ', ');
|
sl@0
|
187 |
}
|
sl@0
|
188 |
}
|
sl@0
|
189 |
print(OUTPUT_FILE "};\n");
|
sl@0
|
190 |
print(OUTPUT_FILE "\nconst int KLgMirrorTableSize=$globalValues{'lgtablesize'};\n");
|
sl@0
|
191 |
print(OUTPUT_FILE "const int KMirrorTableSize=$globalValues{'tablesize'};\n");
|
sl@0
|
192 |
# Inline functions
|
sl@0
|
193 |
# Get a Hash value from a given key
|
sl@0
|
194 |
print(OUTPUT_FILE "\n// Returns the first index to probe for character aKey.\n");
|
sl@0
|
195 |
print(OUTPUT_FILE "inline long MirrorStart(long aKey)\n");
|
sl@0
|
196 |
print(OUTPUT_FILE "\t{ return aKey \& (KMirrorTableSize-1); }\n");
|
sl@0
|
197 |
print(OUTPUT_FILE "\n// Returns the offset for further probes for character aKey.\n");
|
sl@0
|
198 |
print(OUTPUT_FILE "inline long MirrorStep(long aKey)\n");
|
sl@0
|
199 |
my $stepShift = $globalValues{'stepShift'};
|
sl@0
|
200 |
print(OUTPUT_FILE "\t{ return (");
|
sl@0
|
201 |
if ($stepShift == 0)
|
sl@0
|
202 |
{
|
sl@0
|
203 |
print(OUTPUT_FILE "aKey");
|
sl@0
|
204 |
}
|
sl@0
|
205 |
elsif (0 < $stepShift)
|
sl@0
|
206 |
{
|
sl@0
|
207 |
print(OUTPUT_FILE "(aKey >> $stepShift)");
|
sl@0
|
208 |
}
|
sl@0
|
209 |
else
|
sl@0
|
210 |
{
|
sl@0
|
211 |
$stepShift = -$stepShift;
|
sl@0
|
212 |
print(OUTPUT_FILE "(aKey << $stepShift)");
|
sl@0
|
213 |
}
|
sl@0
|
214 |
print(OUTPUT_FILE " | 1) + $globalValues{'stepOffset'}; }\n\n");
|
sl@0
|
215 |
|
sl@0
|
216 |
close(OUTPUT_FILE);
|
sl@0
|
217 |
}
|
sl@0
|
218 |
##################### listing of hash indexes values for original and mirrored glyphs
|
sl@0
|
219 |
sub createHTMLOfMappings
|
sl@0
|
220 |
{
|
sl@0
|
221 |
my ($aOutputFileName, %aHashTable )= @_;
|
sl@0
|
222 |
open(OUTPUT_FILE, '> ' . $aOutputFileName) or die('Error: could not open $aOutputFileName to create HTML output');
|
sl@0
|
223 |
printf(OUTPUT_FILE "<HTML><HEAD><TITLE>MirrorGlyph Hash Output<\/TITLE><\/HEAD><BODY>");
|
sl@0
|
224 |
## print hash table details
|
sl@0
|
225 |
printf(OUTPUT_FILE "<P>Values in hash Table - <B>(Hash Function: Key mod $globalValues{'tablesize'})<\/B><\/P><TABLE border=1>");
|
sl@0
|
226 |
printf(OUTPUT_FILE "<TR><TD><B>---<\/B><\/TD><TD BGCOLOR=\#8888FF><B>Character code:<\/B><\/TD><TD><B>Hash Index:<\/B><\/TD><TD BGCOLOR=\#8888FF><B>Mirror Glyph Value:<\/B><\/TD><TD><b>Search Jump Count<\/b>");
|
sl@0
|
227 |
my %keySet;
|
sl@0
|
228 |
foreach my $value (values %aHashTable)
|
sl@0
|
229 |
{
|
sl@0
|
230 |
$keySet{&getLower(hex $value)} = 1;
|
sl@0
|
231 |
}
|
sl@0
|
232 |
foreach my $key (32..127)
|
sl@0
|
233 |
{
|
sl@0
|
234 |
$keySet{$key} = 1;
|
sl@0
|
235 |
}
|
sl@0
|
236 |
my @keys = sort {$a <=> $b} (keys %keySet);
|
sl@0
|
237 |
foreach my $key (@keys)
|
sl@0
|
238 |
{
|
sl@0
|
239 |
my $counter = 0;
|
sl@0
|
240 |
my $HKey = &findHashTableIndex($key, \$counter, \%aHashTable);
|
sl@0
|
241 |
my $stored = $aHashTable{$HKey};
|
sl@0
|
242 |
my $storedValue = 'no change';
|
sl@0
|
243 |
my $storedKey = $key;
|
sl@0
|
244 |
if (defined $stored)
|
sl@0
|
245 |
{
|
sl@0
|
246 |
$storedValue = sprintf('%02x', &getLower(hex $stored));
|
sl@0
|
247 |
$storedKey = &getUpper(hex $stored);
|
sl@0
|
248 |
}
|
sl@0
|
249 |
if ($storedKey)
|
sl@0
|
250 |
{
|
sl@0
|
251 |
die('incorrect key found in hash table') unless ($storedKey == $key);
|
sl@0
|
252 |
printf(OUTPUT_FILE "<TR><TD>---<\/TD><TD BGCOLOR=\#8888FF><B>%02x<\/B><\/TD><TD>%02x<\/TD><TD BGCOLOR=\#8888FF><B>%s<\/B><\/TD><TD>%d<\/TD><\/TR>", $key, $HKey, $storedValue, $counter);
|
sl@0
|
253 |
}
|
sl@0
|
254 |
}
|
sl@0
|
255 |
printf(OUTPUT_FILE "<\/TABLE>");
|
sl@0
|
256 |
printf(OUTPUT_FILE "<\/BODY><\/HTML>");
|
sl@0
|
257 |
close(OUTPUT_FILE);
|
sl@0
|
258 |
}
|
sl@0
|
259 |
#####################
|
sl@0
|
260 |
# Hash Table functions
|
sl@0
|
261 |
#####################
|
sl@0
|
262 |
|
sl@0
|
263 |
#####################
|
sl@0
|
264 |
#Returns a new Hash Table
|
sl@0
|
265 |
#####################
|
sl@0
|
266 |
sub createHashTable
|
sl@0
|
267 |
{
|
sl@0
|
268 |
my $aInputFileName = shift;
|
sl@0
|
269 |
my $lineNumber = 1;
|
sl@0
|
270 |
my %newHashTable = ();
|
sl@0
|
271 |
open(INPUT_FILE, '< ' . $aInputFileName) or die('ERROR: Could not open $aInputFileName to read from');
|
sl@0
|
272 |
while (my $line=<INPUT_FILE>)
|
sl@0
|
273 |
{
|
sl@0
|
274 |
if ($line=~/^(.*);\s(.*\w)\s\W.*$/) ## Grab Original glyph value and mirrored glyph value
|
sl@0
|
275 |
{
|
sl@0
|
276 |
&updateHashTable($1, $2, \%newHashTable);
|
sl@0
|
277 |
}
|
sl@0
|
278 |
$lineNumber++;
|
sl@0
|
279 |
}
|
sl@0
|
280 |
close(INPUT_FILE);
|
sl@0
|
281 |
return %newHashTable;
|
sl@0
|
282 |
}
|
sl@0
|
283 |
#####################
|
sl@0
|
284 |
#
|
sl@0
|
285 |
# Retrieves a HashKey which is not currently being used in a given HashTable
|
sl@0
|
286 |
#
|
sl@0
|
287 |
#####################
|
sl@0
|
288 |
sub findHashTableIndex
|
sl@0
|
289 |
{
|
sl@0
|
290 |
my ($aHashKey, $aCounter, $aHashTable) = @_;
|
sl@0
|
291 |
my $current = &hashFunction($aHashKey);
|
sl@0
|
292 |
my $step = &hashStepFunction($aHashKey);
|
sl@0
|
293 |
my $tableSize = $globalValues{'tablesize'};
|
sl@0
|
294 |
while (defined($$aHashTable{$current}) && &getUpper(hex($$aHashTable{$current})) != $aHashKey)
|
sl@0
|
295 |
{
|
sl@0
|
296 |
++$$aCounter;
|
sl@0
|
297 |
$current += $step;
|
sl@0
|
298 |
$current &= $tableSize - 1;
|
sl@0
|
299 |
}
|
sl@0
|
300 |
if (2 < $$aCounter)
|
sl@0
|
301 |
{
|
sl@0
|
302 |
printf STDERR ("WARNING: Jumped $$aCounter times, inefficient hash for %02x ($current, $step)\n", $aHashKey);
|
sl@0
|
303 |
}
|
sl@0
|
304 |
return $current;
|
sl@0
|
305 |
}
|
sl@0
|
306 |
|
sl@0
|
307 |
#####################
|
sl@0
|
308 |
sub updateHashTable
|
sl@0
|
309 |
{
|
sl@0
|
310 |
my ($aKey, $aValueToStore, $aHashTable) = @_;
|
sl@0
|
311 |
my $counter = 0;
|
sl@0
|
312 |
my $key = hex($aKey);
|
sl@0
|
313 |
my $hashKey = &findHashTableIndex($key, \$counter, $aHashTable);
|
sl@0
|
314 |
$$aHashTable{$hashKey} = "$aKey$aValueToStore";
|
sl@0
|
315 |
return $hashKey;
|
sl@0
|
316 |
}
|
sl@0
|
317 |
#####################
|
sl@0
|
318 |
# Returns a hash key for a given key
|
sl@0
|
319 |
# Currently using a simple hash function
|
sl@0
|
320 |
#####################
|
sl@0
|
321 |
sub hashFunction
|
sl@0
|
322 |
{
|
sl@0
|
323 |
my $aKey = shift;
|
sl@0
|
324 |
return $aKey & ($globalValues{'tablesize'}-1);
|
sl@0
|
325 |
}
|
sl@0
|
326 |
|
sl@0
|
327 |
# Returns second hash value: used for the step size
|
sl@0
|
328 |
sub hashStepFunction
|
sl@0
|
329 |
{
|
sl@0
|
330 |
my $aKey = shift;
|
sl@0
|
331 |
my $stepShift = $globalValues{'stepShift'};
|
sl@0
|
332 |
if ($stepShift < 0)
|
sl@0
|
333 |
{
|
sl@0
|
334 |
$aKey <<= -$stepShift;
|
sl@0
|
335 |
}
|
sl@0
|
336 |
elsif (0 < $stepShift)
|
sl@0
|
337 |
{
|
sl@0
|
338 |
$aKey >>= $stepShift;
|
sl@0
|
339 |
}
|
sl@0
|
340 |
return ($aKey | 1) + $globalValues{'stepOffset'};
|
sl@0
|
341 |
}
|
sl@0
|
342 |
|
sl@0
|
343 |
#####################
|
sl@0
|
344 |
# Utility functions
|
sl@0
|
345 |
#####################
|
sl@0
|
346 |
sub getLower
|
sl@0
|
347 |
{
|
sl@0
|
348 |
my $aValue = shift;
|
sl@0
|
349 |
return $aValue & hex("0000FFFF");
|
sl@0
|
350 |
}
|
sl@0
|
351 |
sub getUpper
|
sl@0
|
352 |
{
|
sl@0
|
353 |
my $aValue = shift;
|
sl@0
|
354 |
return ($aValue & hex("FFFF0000")) >> 16;
|
sl@0
|
355 |
}
|
sl@0
|
356 |
sub printDebug
|
sl@0
|
357 |
{
|
sl@0
|
358 |
my $string = shift;
|
sl@0
|
359 |
if ($globalValues{'verbose'})
|
sl@0
|
360 |
{
|
sl@0
|
361 |
print $string;
|
sl@0
|
362 |
}
|
sl@0
|
363 |
}
|
sl@0
|
364 |
|