#!/usr/bin/perl ## Checks entries in the indra/newview/gpu_table.txt file against sample data ## ## Copyright (c) 2011, Linden Research, Inc. ## ## Permission is hereby granted, free of charge, to any person obtaining a copy ## of this software and associated documentation files (the "Software"), to deal ## in the Software without restriction, including without limitation the rights ## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ## copies of the Software, and to permit persons to whom the Software is ## furnished to do so, subject to the following conditions: ## ## The above copyright notice and this permission notice shall be included in ## all copies or substantial portions of the Software. ## ## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ## THE SOFTWARE. use English; use Getopt::Long; ( $MyName = $0 ) =~ s|.*/||; my $mini_HELP = " $MyName {--gpu-table|-g} {--table-only|-t} Checks for duplicates and invalid lines in the gpu_table.txt file. $MyName {--gpu-table|-g} [ ... ] [{--unmatched|-u}] Tests the recognition of values in the gpu-strings-files (or standard input if no files are given). The results of attempting to match each input line are displayed in report form, showing: - NO MATCH, unsupported, or supported - the class of the GPU - the label for the recognizer line from the gpu_table that it matched If the --unmatched option is specified, then no output is produced for values that are matched. $MyName {--gpu-table|-g} {--diff|-d} [ ...] With the --diff option, the report compares the current results to , which should be the output from a previous run without --diff. The report shows each input value with the old result and the new result if it is different. "; &GetOptions("help" => \$Help ,"unmatched" => \$UnMatchedOnly ,"table-only" => \$TableOnly ,"gpu-table=s" => \$GpuTable ,"diff=s" => \$Diff ) || die "$mini_HELP"; if ($Help) { print $mini_HELP; exit 0; } $ErrorsSeen = 0; $NoMatch = 'NO MATCH'; # constant die "Must specify a --gpu-table value" unless $GpuTable; open(GPUS, "<$GpuTable") || die "Failed to open gpu table '$GpuTable':\n\t$!\n"; # Parse the GPU table into these tables, indexed by the name my %NameLine; # name -> line number on which a given name was found (catches duplicate names) my %RecognizerLine; # name -> line number on which a given name was found (catches duplicate names) my %Name; # recognizer -> name my %Recognizer; # name -> recognizer my %Class; # recognizer -> class my %Supported; # recognizer -> supported my @InOrder; # lowercased recognizers in file order - these are the ones really used to match $Name{$NoMatch} = $NoMatch; $NameLine{$NoMatch} = '(hard-coded)'; # use this for error messages in table parsing $Class{$NoMatch} = ''; $Supported{$NoMatch} = ''; while () { next if m|^//|; # skip comments next if m|^\s*$|; # skip blank lines chomp; my ($name, $regex, $class, $supported, $extra) = split('\t+'); my $errsOnLine = $ErrorsSeen; if (!$name) { print STDERR "No name found on $GpuTable line $INPUT_LINE_NUMBER\n"; $ErrorsSeen++; } elsif ( defined $NameLine{$name} ) { print STDERR "Duplicate name '$name' on $GpuTable lines $NameLine{$name} and $INPUT_LINE_NUMBER:\n"; print STDERR " $NameLine{$name}: /$Recognizer{$name}/ $Supported{$Recognizer{$name}} class $Class{$Recognizer{$name}}\n"; print STDERR " $INPUT_LINE_NUMBER: /$regex/ " . ($supported ? "supported" : "unsupported") . " class $class - ignored\n"; $ErrorsSeen++; } if (!$regex) { print STDERR "No recognizer found on $GpuTable line $INPUT_LINE_NUMBER\n"; $ErrorsSeen++; } elsif ( defined $RecognizerLine{$regex} ) { print STDERR "Duplicate recognizer /$regex/ found on $GpuTable lines $RecognizerLine{$regex} and $INPUT_LINE_NUMBER (ignored)\n"; print STDERR " $RecognizerLine{$regex}: name '$Name{$regex}' $Supported{$regex} class $Class{$regex}\n"; print STDERR " $INPUT_LINE_NUMBER: name '$name' " . ($supported ? "supported" : "unsupported") . " class $class - ignored\n"; $ErrorsSeen++; } if ($class !~ m/[0123]/) { print STDERR "Invalid class value '$class' on $GpuTable line $INPUT_LINE_NUMBER\n"; $ErrorsSeen++; } if ($supported !~ m/[0123]/) { print STDERR "Invalid supported value '$supported' on $GpuTable line $INPUT_LINE_NUMBER\n"; $ErrorsSeen++; } if ($extra) { print STDERR "Extra data '$extra' on $GpuTable line $INPUT_LINE_NUMBER\n"; $ErrorsSeen++; } if ($errsOnLine == $ErrorsSeen) # no errors found on this line { push @InOrder,$regex; $NameLine{$name} = $INPUT_LINE_NUMBER; $RecognizerLine{$regex} = $INPUT_LINE_NUMBER; $Name{$regex} = $name; $Recognizer{$name} = $regex; $Class{$regex} = $class; $Supported{$regex} = $supported ? "supported" : "unsupported"; } } close GPUS; print STDERR "\n" if $ErrorsSeen; exit $ErrorsSeen if $TableOnly; # Loop over input lines, find the results for each my %RecognizedBy; while (<>) { chomp; my $lcInput = lc $_; # the real gpu table parser lowercases the input string my $recognizer; $RecognizedBy{$_} = $NoMatch; foreach $recognizer ( @InOrder ) # note early exit if recognized { my $lcRecognizer = lc $recognizer; # the real gpu table parser lowercases the recognizer if ( $lcInput =~ m/$lcRecognizer/ ) { $RecognizedBy{$_} = $recognizer; last; # exit recognizer loop } } } format STDOUT_TOP = GPU String Supported? Class Recognizer ------------------------------------------------------------------------------------------------------ ----------- ----- ------------------------------------ . format STDOUT = @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<< @> @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<... $_, $Supported{$RecognizedBy{$_}},$Class{$RecognizedBy{$_}},$Name{$RecognizedBy{$_}} . my $ReportLineTemplate = "A102xxxA12xxxAA*"; # MUST match the format STDOUT above format DIFF_TOP = ------ OLD ------ ------ NEW ------ GPU String Supported? Class Supported? Class ------------------------------------------------------------------------------------------------------ ----------- ----- ----------- ----- . my ( $oldSupported, $oldClass, $newSupported, $newClass ); format DIFF = @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<... @<<<<<<<<<< @> @<<<<<<<<<< @> $_, $oldSupported, $oldClass, $newSupported, $newClass . if ( ! $Diff ) { ## Print results. ## For each input, show supported or unsupported, the class, and the recognizer name foreach ( sort keys %RecognizedBy ) { write if ! $UnMatchedOnly || $Name{$RecognizedBy{$_}} eq $NoMatch; $-++; # suppresses pagination } } else { open OLD, "<$Diff" || die "Failed to open --diff file '$Diff'\n\t$!\n"; my $discard = 2; while ( ) { if ( $discard > 0 ) { my ( $gpu, $supported, $class ) = unpack $ReportLineTemplate; $gpu =~ s/\s*$//; ( $OldSupported{$gpu} = $supported ) =~ s/\s*$//; ( $OldClass{$gpu} = $class ) =~ s/\s*$//; } else { $discard--; } } close OLD; $FORMAT_TOP_NAME = DIFF_TOP; $FORMAT_NAME = DIFF; foreach ( sort keys %RecognizedBy ) { $newSupported = $Supported{$RecognizedBy{$_}} || $NoMatch; $newClass = $Class{$RecognizedBy{$_}}; if ( ! defined $OldSupported{$_} ) { $oldSupported = 'NEW'; $oldClass = '-'; } else { $oldSupported = $OldSupported{$_} || $NoMatch; $oldClass = $OldClass{$_}; if ( ( $oldSupported eq $newSupported ) && ( $oldClass eq $newClass ) ) { $newSupported = ''; $newClass = ''; } } write; $-++; # suppresses pagination } } exit $ErrorsSeen;