First public contribution.
1 # Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
3 # This component and the accompanying materials are made available
4 # under the terms of "Eclipse Public License v1.0"
5 # which accompanies this distribution, and is available
6 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 # Initial Contributors:
9 # Nokia Corporation - initial contribution.
18 ## Used as global variables, probably need to change and pass variables through as parameters.
20 ##initialise filenames
21 $globalValues{'inputFile'} = 'mglyphs.txt';
22 $globalValues{'outputFileName'} = 'mglyphs.inl';
23 $globalValues{'htmlFileName'} = 'mglyphs.html';
24 $globalValues{'lgtablesize'} = 9; # Default tablesize value is 512
25 $globalValues{'tablesize'} = 1 << $globalValues{'lgtablesize'};
26 $globalValues{'storeashex'} = 0;
27 $globalValues{'stepOffset'} = 72;
28 $globalValues{'stepShift'} = 0;
30 ## die if the correct number of argumements have not been entered
31 &extractFlags(\@ARGV, \%globalValues);
32 &printDebug("Remainder:$globalValues{'tablesize'}\n");
33 &printDebug("StoreAsHex:$globalValues{'storeashex'}\n");
35 if ($globalValues{"information"})
40 &printDebug("Creating HashTable....\n");
41 my %hashTable = &createHashTable($globalValues{'inputFile'});
42 if (!defined(%hashTable))
44 die("ERROR: Hash table was not created\n");
46 if ($globalValues{"outputtohtml"})
48 my $htmlFileName = $globalValues{'htmlFileName'};
49 &printDebug("Creating HTML output to file: $htmlFileName\n");
50 &createHTMLOfMappings($htmlFileName, %hashTable);
52 my $outputFileName = $globalValues{'outputFileName'};
53 &printDebug("Writing Hash table to file: $outputFileName\n");
54 &writeHashTableToFile($outputFileName, %hashTable);
55 &printDebug("$outputFileName created.");
57 ##################### end of main section
60 my $aArgumentArray=shift;
62 my $expectedArg = 'lgtablesize';
63 my $expectedExtension;
64 foreach my $argument (@$aArgumentArray)
66 if ($argument =~ m!^[-/]([a-zA-Z].*)$!)
69 $expectedArg = 'lgtablesize';
70 $expectedExtension = undef;
71 if ($switch=~/^(x|hexoutput)$/i)
73 $$aArguments{'storeashex'}=1;
75 elsif ($switch=~/^(\?|help)$/i)
77 $$aArguments{'information'}=1;
79 elsif ($switch=~/^(v|verbose)$/i)
81 $$aArguments{'verbose'}=1;
83 elsif ($switch=~/^(h|outputtohtml)$/i)
85 $$aArguments{'outputtohtml'}=1;
86 $expectedArg = 'htmlFileName';
87 $expectedExtension = '.html';
89 elsif ($switch=~/^(i|input)$/i)
91 $expectedArg = 'inputFile';
93 elsif ($switch=~/^(o|output)$/i)
95 $expectedArg = 'outputFileName';
96 $expectedExtension = '.inl';
98 elsif ($switch=~/^(offset)$/i)
100 $expectedArg = 'stepOffset';
102 elsif ($switch=~/^(shift)$/i)
104 $expectedArg = 'stepShift';
109 if (defined $expectedExtension && $argument !~ m!\.[^/\\]*$!)
111 $argument .= $expectedExtension;
113 $$aArguments{$expectedArg} = $argument;
114 $expectedArg = 'lgtablesize';
117 $globalValues{'tablesize'} = 1 << $globalValues{'lgtablesize'};
118 $globalValues{'stepOffset'} &= 0xFFFFFE;
120 #####################
127 perl -w mglyphtool.pl [-?] [<lg-table-size>] [-x] [-i <input-file-name>]
128 [-o <output-file-name>] [-h [<output-html-file-name]]
129 [-offset <value-for-offset>] [-shift <value-for-shift>]
131 <lg-table-size> the default log(base 2) table size is 9. This gives a table
132 size of 512 entries (2 to the power 9). So 7 gives a size of 128, 8 gives
133 256, 9 gives 512, 10 gives 1024 and so on.
139 The -x flag stores values into the .inl file in hex format:
140 hex(OriginalKeyCodeMirrorGlyphCode),
141 By default the values are stored in string hex format i.e 0x220C2209
143 The -h flag generates a html file displaying hash table information.
144 This may be followed by the filename to be output.
145 Default is 'mglyphs.html'
147 The -i file specifies input file name. Default is 'mglyphs.txt'.
149 The -o file specifies output file name. Default is 'mglyphs.inl'.
151 -shift and -offset alter the "step" hash algorithm.
158 # Writes a hash table to file.
160 # Hex mode: "hex number created"
161 # Hex string mode: "Original keyMapped key"
162 #####################
163 sub writeHashTableToFile
165 &printDebug("Writing to .inl file");
166 my ($aOutputFileName, %aHashTable) = @_;
167 open(OUTPUT_FILE, '> ' . $aOutputFileName) or die('Error: could not open $aOutputFileName to write to\n');
168 ## Print comments at top of .inl file
169 printf(OUTPUT_FILE "\/\/ mGlyphs.inl\n");
170 printf(OUTPUT_FILE "\/\/\n");
171 printf(OUTPUT_FILE "\/\/ Generated by mglyphtool.pl from '$globalValues{'inputFile'}'\n");
172 printf(OUTPUT_FILE "\/\/\n\n");
173 ## Declare array and fill in values
174 printf(OUTPUT_FILE "const unsigned long mGlyphArray[] = {\n\t");
175 for (my $counter = 0; $counter < $globalValues{'tablesize'}; $counter++)
177 my $storeValue = "00000000";
178 if (defined($aHashTable{$counter}))
180 $storeValue = $aHashTable{$counter};
182 $storeValue = ($globalValues{'storeashex'}) ? hex($storeValue) : "0x$storeValue";
183 print OUTPUT_FILE $storeValue;
184 if (($counter+1) < $globalValues{'tablesize'})
186 print OUTPUT_FILE (($counter + 1) % 8 == 0? ",\n\t" : ', ');
189 print(OUTPUT_FILE "};\n");
190 print(OUTPUT_FILE "\nconst int KLgMirrorTableSize=$globalValues{'lgtablesize'};\n");
191 print(OUTPUT_FILE "const int KMirrorTableSize=$globalValues{'tablesize'};\n");
193 # Get a Hash value from a given key
194 print(OUTPUT_FILE "\n// Returns the first index to probe for character aKey.\n");
195 print(OUTPUT_FILE "inline long MirrorStart(long aKey)\n");
196 print(OUTPUT_FILE "\t{ return aKey \& (KMirrorTableSize-1); }\n");
197 print(OUTPUT_FILE "\n// Returns the offset for further probes for character aKey.\n");
198 print(OUTPUT_FILE "inline long MirrorStep(long aKey)\n");
199 my $stepShift = $globalValues{'stepShift'};
200 print(OUTPUT_FILE "\t{ return (");
203 print(OUTPUT_FILE "aKey");
205 elsif (0 < $stepShift)
207 print(OUTPUT_FILE "(aKey >> $stepShift)");
211 $stepShift = -$stepShift;
212 print(OUTPUT_FILE "(aKey << $stepShift)");
214 print(OUTPUT_FILE " | 1) + $globalValues{'stepOffset'}; }\n\n");
218 ##################### listing of hash indexes values for original and mirrored glyphs
219 sub createHTMLOfMappings
221 my ($aOutputFileName, %aHashTable )= @_;
222 open(OUTPUT_FILE, '> ' . $aOutputFileName) or die('Error: could not open $aOutputFileName to create HTML output');
223 printf(OUTPUT_FILE "<HTML><HEAD><TITLE>MirrorGlyph Hash Output<\/TITLE><\/HEAD><BODY>");
224 ## print hash table details
225 printf(OUTPUT_FILE "<P>Values in hash Table - <B>(Hash Function: Key mod $globalValues{'tablesize'})<\/B><\/P><TABLE border=1>");
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>");
228 foreach my $value (values %aHashTable)
230 $keySet{&getLower(hex $value)} = 1;
232 foreach my $key (32..127)
236 my @keys = sort {$a <=> $b} (keys %keySet);
237 foreach my $key (@keys)
240 my $HKey = &findHashTableIndex($key, \$counter, \%aHashTable);
241 my $stored = $aHashTable{$HKey};
242 my $storedValue = 'no change';
243 my $storedKey = $key;
246 $storedValue = sprintf('%02x', &getLower(hex $stored));
247 $storedKey = &getUpper(hex $stored);
251 die('incorrect key found in hash table') unless ($storedKey == $key);
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);
255 printf(OUTPUT_FILE "<\/TABLE>");
256 printf(OUTPUT_FILE "<\/BODY><\/HTML>");
259 #####################
260 # Hash Table functions
261 #####################
263 #####################
264 #Returns a new Hash Table
265 #####################
268 my $aInputFileName = shift;
270 my %newHashTable = ();
271 open(INPUT_FILE, '< ' . $aInputFileName) or die('ERROR: Could not open $aInputFileName to read from');
272 while (my $line=<INPUT_FILE>)
274 if ($line=~/^(.*);\s(.*\w)\s\W.*$/) ## Grab Original glyph value and mirrored glyph value
276 &updateHashTable($1, $2, \%newHashTable);
281 return %newHashTable;
283 #####################
285 # Retrieves a HashKey which is not currently being used in a given HashTable
287 #####################
288 sub findHashTableIndex
290 my ($aHashKey, $aCounter, $aHashTable) = @_;
291 my $current = &hashFunction($aHashKey);
292 my $step = &hashStepFunction($aHashKey);
293 my $tableSize = $globalValues{'tablesize'};
294 while (defined($$aHashTable{$current}) && &getUpper(hex($$aHashTable{$current})) != $aHashKey)
298 $current &= $tableSize - 1;
302 printf STDERR ("WARNING: Jumped $$aCounter times, inefficient hash for %02x ($current, $step)\n", $aHashKey);
307 #####################
310 my ($aKey, $aValueToStore, $aHashTable) = @_;
312 my $key = hex($aKey);
313 my $hashKey = &findHashTableIndex($key, \$counter, $aHashTable);
314 $$aHashTable{$hashKey} = "$aKey$aValueToStore";
317 #####################
318 # Returns a hash key for a given key
319 # Currently using a simple hash function
320 #####################
324 return $aKey & ($globalValues{'tablesize'}-1);
327 # Returns second hash value: used for the step size
331 my $stepShift = $globalValues{'stepShift'};
334 $aKey <<= -$stepShift;
336 elsif (0 < $stepShift)
338 $aKey >>= $stepShift;
340 return ($aKey | 1) + $globalValues{'stepOffset'};
343 #####################
345 #####################
349 return $aValue & hex("0000FFFF");
354 return ($aValue & hex("FFFF0000")) >> 16;
359 if ($globalValues{'verbose'})