1 # ======================================================================
3 # Customization Variable Tool
4 # Copyright 2003, Sony Online Entertainment, Inc.
6 # ======================================================================
11 use POSIX
qw(strftime);
13 # ======================================================================
16 my $maxAllowableVariableId = 127;
17 my $dataFormatVersionNumber = 1;
18 my $firstAssignableId = 1;
20 # Names of customization variables.
21 my %countsByVariableName;
23 # Name to id assignment.
24 my %idsByVariableName;
25 my $newVariableCount = 0;
28 my $doPrintReport = 0;
29 my $doGenerateMifMapFile = 0;
31 # Report printing options.
32 my $printTpfFileNames = 0;
33 my $printSortByCount = 0;
34 my $printSortByName = 0;
37 # Id map file generation options.
39 my $mifFileMustExist = 1;
43 # ======================================================================
45 # ======================================================================
47 # ======================================================================
51 # Process args. Args must come first.
52 while (defined($ARGV[0]) && ($ARGV[0] =~ m/^-([a-zA-Z]*)$/))
60 $doGenerateMifMapFile = 1;
64 # Support first-time mif file generation, but force it to be a flag
65 # so the default is to die if not explicity specified and the mif
67 $mifFileMustExist = 0;
71 die "-o option requires a filename to be specified after it (e.g. -o customization_id_manager.mif)\n" if !defined($ARGV[1]);
72 $mifFileName = $ARGV[1];
75 die "filename [$mifFileName] should end in extension \".mif\"\n" if !($mifFileName =~ m/\.mif$/);
79 $printTpfFileNames = 1;
83 $printSortByCount = 1;
101 #-- Ensure we do at least some activity. Assume report generation is default.
102 if (($doPrintReport == 0) && ($doGenerateMifMapFile == 0))
107 #-- Ensure we'll print at least some output. Default is print-by-count if no printing option is specified.
108 if (($printSortByCount == 0) && ($printSortByName == 0))
110 $printSortByCount = 1;
114 # ======================================================================
118 #-- Check if this is a TPF file.
121 #-- Indicate file we're testing.
122 print "Processing [$File::Find::name].\n" if $printTpfFileNames;
124 #-- Open the TPF file.
127 #-- Scan all variable names within the TPF file.
131 if (m/variableName="([^"]*)\"/) # last double-quote escaped for Emacs font-lock mode.
133 $countsByVariableName{$1}++;
142 # ======================================================================
144 sub collectCustomizationVariableData
146 # Setup directories to check.
147 @ARGV = ('.') if !defined($ARGV[0]);
149 # Do the find to scan in all TPF filenames.
150 find
(\
&findFileHandler
, @ARGV);
153 # ======================================================================
157 # Handle printing sorted by name.
158 if ($printSortByName)
160 my @sortedKeys = sort keys(%countsByVariableName);
161 @sortedKeys = reverse @sortedKeys if $reverseSort;
163 print "Variable names sorted by name (" . @sortedKeys . " unique variable names):\n";
164 print "variable name\tcount\n";
165 foreach my $variableName (@sortedKeys)
167 my $count = $countsByVariableName{$variableName};
168 print "$variableName\t$count\n";
173 if ($printSortByCount)
175 my @sortedKeys = sort {$countsByVariableName{$b} <=> $countsByVariableName{$a}} keys(%countsByVariableName);
176 @sortedKeys = reverse @sortedKeys if $reverseSort;
178 print "Variable names sorted by name (" . @sortedKeys . " unique variable names):\n";
179 print "count\tvariable name\n";
180 foreach my $variableName (@sortedKeys)
182 my $count = $countsByVariableName{$variableName};
183 print "$count\t$variableName\n";
189 # ======================================================================
191 sub collectExistingVariableNameAssignments
193 open(MIF_FILE
, $mifFileName) or die "failed to open specified mif file [$mifFileName]: $!";
195 my $nextAssignmentId = $firstAssignableId;
201 if (m/int16\s+(\d+)\s*$/)
203 # Ensure we're expecting a new id.
204 die "error: file [$mifFileName] appears malformed, out of order int16/cstring declarations.\n" if !$expectingId;
207 $nextAssignmentId = $1;
209 elsif (m/cstring\s+\"([^\"]+)\"\s*$/)
211 # Ensure we're expecting a variable name.
212 die "error: file [$mifFileName] appears malformed, out of order int16/cstring declarations.\n" if $expectingId;
215 # Add new variable name. It is associated with $nextAssignmentId collected previously.
216 $idsByVariableName{$1} = $nextAssignmentId;
217 print "<existing: mapping variable name [$1] to [$nextAssignmentId]>\n" if $debug;
224 # ======================================================================
228 open(MIF_FILE
, ">$mifFileName") or die "failed to open mif file [$mifFileName] for writing: $!";
230 my $timeString = strftime
"%a %b %e %H:%M:%S %Y", localtime(time());
232 print MIF_FILE
"// ======================================================================\n";
233 print MIF_FILE
"// Output generated by Perl script \"$0\"\n";
234 print MIF_FILE
"// Generation time: $timeString\n";
235 print MIF_FILE
"//\n";
236 print MIF_FILE
"// Do not hand-edit this file! It is generated by the build process.\n";
237 print MIF_FILE
"// Changing values from a previous run without a database update will\n";
238 print MIF_FILE
"// invalidate database-stored customization data.\n";
239 print MIF_FILE
"// ======================================================================\n\n";
241 print MIF_FILE
"form \"CIDM\"\n";
242 print MIF_FILE
"{\n";
243 print MIF_FILE
"\tform \"0001\"\n";
244 print MIF_FILE
"\t{\n";
245 print MIF_FILE
"\t\tchunk \"DATA\"\n";
246 print MIF_FILE
"\t\t{\n";
248 foreach my $variableName (sort { $idsByVariableName{$a} <=> $idsByVariableName{$b} } keys %idsByVariableName)
250 print MIF_FILE
"\t\t\tint16\t$idsByVariableName{$variableName}\n";
251 print MIF_FILE
"\t\t\tcstring\t\"$variableName\"\n\n";
254 print MIF_FILE
"\t\t}\n";
255 print MIF_FILE
"\t}\n";
256 print MIF_FILE
"}\n";
260 print "<success: wrote new customization id manager data file [$mifFileName]>\n" if $debug;
263 # ======================================================================
265 sub assignNewVariableIds
267 # Setup starting id: should be the same as # entries in assignment map.
268 my @sortedValues = sort {$b <=> $a} values %idsByVariableName;
269 my $nextAssignmentId = $firstAssignableId;
271 $nextAssignmentId = ($sortedValues[0] + 1) if defined($sortedValues[0]);
272 print "<firstNewId: $nextAssignmentId>\n" if $debug;
275 # Process new IDs sorted by frequency from most to least, causing
276 # lower ID values to be assigned to higher-frequency items. This
277 # could be useful if some of the lower frequency items are really
278 # typos and need to be shuffled around.
279 foreach my $variableName (sort {$countsByVariableName{$b} <=> $countsByVariableName{$a}} keys %countsByVariableName)
281 # Check if variable is assigned yet.
282 if (!defined($idsByVariableName{$variableName}))
284 $idsByVariableName{$variableName} = $nextAssignmentId;
285 print "<new: mapping variable name [$variableName] to [$nextAssignmentId]>\n" if $debug;
293 # ======================================================================
295 sub generateMifMapFile
297 # Collect existing mif map assignments.
300 collectExistingVariableNameAssignments
();
302 elsif ($mifFileMustExist)
304 if (length($mifFileName) < 1)
306 die "error: must specify filename for existing and output mif file with the -o flag.\n";
310 die "error: Customization id manager file must exist to preserve existing mappings.\nerror: Failed to find [$mifFileName].\nerror: Use -F for first-time file generation, don't do this unless you know what you're doing!\n";
314 # Generate assignments for non-populated but existing customization variables.
315 assignNewVariableIds
();
317 # Check if we've exceeded the max assignable id value.
318 my @sortedAssignedIds = sort {$a <=> $b} values %idsByVariableName;
319 my $idCount = @sortedAssignedIds;
322 my $maxAssignedId = $sortedAssignedIds[$idCount - 1];
323 print "<maxAssignedId: $maxAssignedId>\n" if $debug;
325 if ($maxAssignedId > $maxAllowableVariableId)
327 die "error: new unassigned customization variable ids needed but no more room.\nerror: Either unused names must be removed with database remapping or a new data format must be implemented.\nNeed id of $maxAssignedId but max allowable is $maxAllowableVariableId for format version $dataFormatVersionNumber.\n";
331 # Write new mif file if any changes.
332 if ($newVariableCount > 0)
338 print "skipping file generation: no new customization variable names found.\n";
342 # ======================================================================
343 # PROGRAM STARTING POINT.
344 # ======================================================================
346 # Program starts here.
351 # Collect customization variable data.
352 collectCustomizationVariableData
();
354 # Handle report generation.
360 # Handle mif file generation.
361 if ($doGenerateMifMapFile)
363 generateMifMapFile
();
367 # ======================================================================