summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/automated_build_scripts/opensrc-build.sh391
-rwxr-xr-xscripts/build_version.py54
-rwxr-xr-xscripts/gpu_table_tester293
-rwxr-xr-xscripts/install.py1162
-rwxr-xr-xscripts/md5check.py56
-rwxr-xr-x[-rw-r--r--]scripts/messages/message_template.msg70
-rwxr-xr-xscripts/messages/message_template.msg.sha11
-rwxr-xr-xscripts/packages-formatter.py93
-rwxr-xr-xscripts/setup-path.py42
-rwxr-xr-xscripts/template_verifier.py66
-rwxr-xr-xscripts/templates/template-cpp.cpp30
-rwxr-xr-xscripts/templates/template-h.h31
-rwxr-xr-xscripts/update_version_files.py331
13 files changed, 631 insertions, 1989 deletions
diff --git a/scripts/automated_build_scripts/opensrc-build.sh b/scripts/automated_build_scripts/opensrc-build.sh
deleted file mode 100755
index c1b592a972..0000000000
--- a/scripts/automated_build_scripts/opensrc-build.sh
+++ /dev/null
@@ -1,391 +0,0 @@
-#!/bin/sh
-
-# This is the build script used by Linden Lab's autmated build system.
-#
-
-set -x
-
-export PATH=/bin:/usr/bin:$PATH
-arch=`uname | cut -b-6`
-here=`echo $0 | sed 's:[^/]*$:.:'`
-year=`date +%Y`
-branch=`svn info | grep '^URL:' | sed 's:.*/::'`
-revision=`svn info | grep '^Revision:' | sed 's/.*: //'`
-
-[ x"$WGET_CACHE" = x ] && export WGET_CACHE=/var/tmp/parabuild/wget
-[ x"$S3GET_URL" = x ] && export S3GET_URL=http://viewer-source-downloads.s3.amazonaws.com/$year
-[ x"$S3PUT_URL" = x ] && export S3PUT_URL=https://s3.amazonaws.com/viewer-source-downloads/$year
-[ x"$PUBLIC_URL" = x ] && export PUBLIC_URL=http://secondlife.com/developers/opensource/downloads/$year
-[ x"$PUBLIC_EMAIL" = x ] && export PUBLIC_EMAIL=sldev-commits@lists.secondlife.com
-
-# Make sure command worked and bail out if not, reporting failure to parabuild
-fail()
-{
- release_lock
- echo "BUILD FAILED" $@
- exit 1
-}
-
-pass()
-{
- release_lock
- echo "BUILD SUCCESSFUL"
- exit 0
-}
-
-# Locking to avoid contention with u-s-c
-LOCK_CREATE=/usr/bin/lockfile-create
-LOCK_TOUCH=/usr/bin/lockfile-touch
-LOCK_REMOVE=/usr/bin/lockfile-remove
-LOCK_PROCESS=
-
-locking_available()
-{
- test -x "$LOCK_CREATE"\
- -a -x "$LOCK_TOUCH"\
- -a -x "$LOCK_REMOVE"
-}
-
-acquire_lock()
-{
- if locking_available
- then
- if "$LOCK_CREATE" /var/lock/update-system-config --retry 99
- then
- "$LOCK_TOUCH" /var/lock/update-system-config &
- LOCK_PROCESS="$!"
- else
- fail acquire lock
- fi
- else
- true
- fi
-}
-
-release_lock()
-{
- if locking_available
- then
- if test x"$LOCK_PROCESS" != x
- then
- kill "$LOCK_PROCESS"
- "$LOCK_REMOVE" /var/lock/update-system-config
- else
- echo No Lock Acquired >&2
- fi
- else
- true
- fi
-}
-
-get_asset()
-{
- mkdir -p "$WGET_CACHE" || fail creating WGET_CACHE
- local tarball=`basename "$1"`
- test -r "$WGET_CACHE/$tarball" || ( cd "$WGET_CACHE" && curl --location --remote-name "$1" || fail getting $1 )
- case "$tarball" in
- *.zip) unzip -qq -d .. -o "$WGET_CACHE/$tarball" || fail unzip $tarball ;;
- *.tar.gz|*.tgz) tar -C .. -xzf "$WGET_CACHE/$tarball" || fail untar $tarball ;;
- *) fail unrecognized filetype: $tarball ;;
- esac
-}
-
-s3_available()
-{
- test -x "$helpers/s3get.sh" -a -x "$helpers/s3put.sh" -a -r "$helpers/s3curl.pl"
-}
-
-build_dir_Darwin()
-{
- echo build-darwin-universal
-}
-
-build_dir_Linux()
-{
- echo viewer-linux-i686-`echo $1 | tr A-Z a-z`
-}
-
-build_dir_CYGWIN()
-{
- echo build-vc80
-}
-
-installer_Darwin()
-{
- ls -1td "`build_dir_Darwin Release`/newview/"*.dmg 2>/dev/null | sed 1q
-}
-
-installer_Linux()
-{
- ls -1td "`build_dir_Linux Release`/newview/"*.tar.bz2 2>/dev/null | sed 1q
-}
-
-installer_CYGWIN()
-{
- d=`build_dir_CYGWIN Release`
- p=`sed 's:.*=::' "$d/newview/Release/touched.bat"`
- echo "$d/newview/Release/$p"
-}
-
-# deal with aborts etc..
-trap fail 1 2 3 14 15
-
-# Check location
-cd "$here/../.."
-
-test -x ../linden/scripts/automated_build_scripts/opensrc-build.sh\
- || fail 'The parent dir of your checkout needs to be named "linden"'
-
-. doc/asset_urls.txt
-get_asset "$SLASSET_ART"
-
-
-# Set up platform specific stuff
-case "$arch" in
-
-# Note that we can only build the "Release" variant for Darwin, because of a compiler bug:
-# ld: bl out of range (-16777272 max is +/-16M)
-# from __static_initialization_and_destruction_0(int, int)at 0x033D319C
-# in __StaticInit of
-# indra/build-darwin-universal/newview/SecondLife.build/Debug/Second Life.build/Objects-normal/ppc/llvoicevisualizer.o
-# to ___cxa_atexit$island_2 at 0x023D50F8
-# in __text of
-# indra/build-darwin-universal/newview/SecondLife.build/Debug/Second Life.build/Objects-normal/ppc/Second Life
-# in __static_initialization_and_destruction_0(int, int)
-# from indra/build-darwin-universal/newview/SecondLife.build/Debug/Second Life.build/Objects-normal/ppc/llvoicevisualizer.o
-
-Darwin)
- helpers=/usr/local/buildscripts/generic_vc
- variants="Release"
- cmake_generator="Xcode"
- fmod=fmodapi375mac
- fmod_tar="$fmod.zip"
- fmod_so=libfmod.a
- fmod_lib=lib
- target_dirs="libraries/universal-darwin/lib_debug
- libraries/universal-darwin/lib_release
- libraries/universal-darwin/lib_release_client"
- other_archs="$S3GET_URL/$branch/$revision/CYGWIN $S3GET_URL/$branch/$revision/Linux"
- mail="$helpers"/mail.py
- all_done="$helpers"/all_done.py
- get_asset "$SLASSET_LIBS_DARWIN"
- ;;
-
-CYGWIN)
- helpers=/cygdrive/c/buildscripts
- variants="Debug RelWithDebInfo Release"
- #variants="Release"
- cmake_generator="vc80"
- fmod=fmodapi375win
- fmod_tar=fmodapi375win.zip
- fmod_so=fmodvc.lib
- fmod_lib=lib
- target_dirs="libraries/i686-win32/lib/debug
- libraries/i686-win32/lib/release"
- other_archs="$S3GET_URL/$branch/$revision/Darwin $S3GET_URL/$branch/$revision/Linux"
- export PATH="/cygdrive/c/Python25:/cygdrive/c/Program Files/Cmake 2.6/bin":$PATH
- export PERL="/cygdrive/c/Perl/bin/perl.exe"
- export S3CURL="C:\\buildscripts\s3curl.pl"
- export CURL="C:\\cygwin\\bin\\curl.exe"
- mail="C:\\buildscripts\\mail.py"
- all_done="C:\\buildscripts\\all_done.py"
- get_asset "$SLASSET_LIBS_WIN32"
- ;;
-
-Linux)
- helpers=/var/opt/parabuild/buildscripts/generic_vc
- [ x"$CXX" = x ] && test -x /usr/bin/g++-4.1 && export CXX=/usr/bin/g++-4.1
- acquire_lock
- variants="Debug RelWithDebInfo Release"
- #variants="Release"
- cmake_generator="Unix Makefiles"
- fmod=fmodapi375linux
- fmod_tar="$fmod".tar.gz
- fmod_so=libfmod-3.75.so
- fmod_lib=.
- target_dirs="libraries/i686-linux/lib_debug
- libraries/i686-linux/lib_release
- libraries/i686-linux/lib_release_client"
- other_archs="$S3GET_URL/$branch/$revision/Darwin $S3GET_URL/$branch/$revision/CYGWIN"
- mail="$helpers"/mail.py
- all_done="$helpers"/all_done.py
- # Change the DISTCC_DIR to be somewhere that the parabuild process can write to
- if test -r /etc/debian_version
- then
- [ x"$DISTCC_DIR" = x ] && export DISTCC_DIR=/var/tmp/parabuild
- case `cat /etc/debian_version` in
- 3.*) [ x"$DISTCC_HOSTS" = x ]\
- && export DISTCC_HOSTS="build-linux-1
- build-linux-2
- build-linux-3
- build-linux-4
- build-linux-5" ;;
- 4.*) [ x"$DISTCC_HOSTS" = x ]\
- && export DISTCC_HOSTS="build-linux-6
- build-linux-7
- build-linux-8
- build-linux-9" ;;
- esac
- fi
-
- get_asset "$SLASSET_LIBS_LINUXI386"
- ;;
-
-*) fail undefined $arch ;;
-esac
-
-get_asset "http://www.fmod.org/index.php/release/version/$fmod_tar"
-
-# Special case for Mac...
-case "$arch" in
-
-Darwin)
- if lipo -create -output "../$fmod"/api/$fmod_lib/libfmod-universal.a\
- "../$fmod"/api/$fmod_lib/libfmod.a\
- "../$fmod"/api/$fmod_lib/libfmodx86.a
- then
- mv "../$fmod"/api/$fmod_lib/libfmod.a "../$fmod"/api/$fmod_lib/libfmodppc.a
- mv "../$fmod"/api/$fmod_lib/libfmod-universal.a "../$fmod"/api/$fmod_lib/libfmod.a
- echo Created fat binary
- else
- fail running lipo
- fi
- ;;
-
-esac
-
-# ensure helpers are up to date
-( cd "$helpers" && svn up )
-
-# First, go into the directory where the code was checked out by Parabuild
-cd indra
-
-# This is the way it works now, but it will soon work on a variant dependent way
-for target_dir in $target_dirs
-do
- mkdir -p "../$target_dir"
- cp -f "../../$fmod/api/$fmod_lib/$fmod_so" "../$target_dir"
-done
-mkdir -p "../libraries/include"
-cp -f "../../$fmod/api/inc/"* "../libraries/include"
-
-# Special Windows case
-test -r "../../$fmod/api/fmod.dll" && cp -f "../../$fmod/api/fmod.dll" newview
-
-# Now run the build command over all variants
-succeeded=true
-cp /dev/null build.log
-
-### TEST CODE - remove when done
-### variants=
-### echo "Artificial build failure to test notifications" > build.log
-### succeeded=false
-### END TEST CODE
-
-for variant in $variants
-do
- build_dir=`build_dir_$arch $variant`
- rm -rf "$build_dir"
- # This is the way it will work in future
- #for target_dir in $target_dirs
- #do
- # mkdir -p "$build_dir/$target_dir"
- # cp "../../$fmod/api/$fmod_lib/$fmod_so" "$build_dir/$target_dir"
- #done
- #mkdir -p "$build_dir/libraries/include"
- #cp "../../$fmod/api/inc/"* "$build_dir/libraries/include"
- echo "==== $variant ====" >> build.log
- if ./develop.py \
- --unattended \
- --incredibuild \
- -t $variant \
- -G "$cmake_generator" \
- configure \
- -DPACKAGE:BOOL=ON >>build.log 2>&1
- then
- if ./develop.py\
- --unattended\
- --incredibuild \
- -t $variant\
- -G "$cmake_generator" \
- build package >>build.log 2>&1
- then
- # run tests if needed
- true
- else
- succeeded=false
- fi
- else
- succeeded=false
- fi
-done
-
-# check statuis and upload results to S3
-subject=
-if $succeeded
-then
- package=`installer_$arch`
- test -r "$package" || fail not found: $package
- package_file=`echo $package | sed 's:.*/::'`
- if s3_available
- then
- echo "$PUBLIC_URL/$branch/$revision/$package_file" > "$arch"
- echo "$PUBLIC_URL/$branch/$revision/good-build.$arch" >> "$arch"
- "$helpers/s3put.sh" "$package" "$S3PUT_URL/$branch/$revision/$package_file" binary/octet-stream\
- || fail Uploading "$package"
- "$helpers/s3put.sh" build.log "$S3PUT_URL/$branch/$revision/good-build.$arch" text/plain\
- || fail Uploading build.log
- "$helpers/s3put.sh" "$arch" "$S3PUT_URL/$branch/$revision/$arch" text/plain\
- || fail Uploading token file
- if python "$all_done"\
- curl\
- "$S3GET_URL/$branch/$revision/$arch"\
- $other_archs > message
- then
- subject="Successful Build for $branch ($revision)"
- fi
- else
- true s3 is not available
- fi
-else
- if s3_available
- then
- "$helpers/s3put.sh" build.log "$S3PUT_URL/$branch/$revision/failed-build.$arch" text/plain\
- || fail Uploading build.log
- subject="Failed Build for $branch ($revision) on $arch"
- cat >message <<EOF
-Build for $branch ($revision) failed for $arch.
-Please see the build log for details:
-
-$PUBLIC_URL/$branch/$revision/failed-build.$arch
-
-EOF
- else
- true s3 is not available
- fi
-fi
-
-# We have something to say...
-if [ x"$subject" != x ]
-then
- # Extract change list since last build
- if [ x"$PARABUILD_CHANGE_LIST_NUMBER" = x ]
- then
- echo "No change information available" >> message
- elif [ x"$PARABUILD_PREVIOUS_CHANGE_LIST_NUMBER" = x ]
- then
- ( cd .. && svn log --verbose --stop-on-copy --limit 50 ) >>message
- else
- ( cd .. && svn log --verbose -r"$PARABUILD_PREVIOUS_CHANGE_LIST_NUMBER":"$PARABUILD_CHANGE_LIST_NUMBER" ) >>message
- fi
- # $PUBLIC_EMAIL can be a list, so no quotes
- python "$mail" "$subject" $PUBLIC_EMAIL <message
-fi
-
-if $succeeded
-then
- pass
-else
- fail
-fi
-
diff --git a/scripts/build_version.py b/scripts/build_version.py
deleted file mode 100755
index 4bef290b7d..0000000000
--- a/scripts/build_version.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env python
-#
-# Print the build information embedded in a header file.
-#
-# Expects to be invoked from the command line with a file name and a
-# list of directories to search. The file name will be one of the
-# following:
-#
-# llversionserver.h
-# llversionviewer.h
-#
-# The directory list that follows will include indra/llcommon, where
-# these files live.
-
-import errno, os, re
-
-def get_version(filename):
- fp = open(filename)
- data = fp.read()
- fp.close()
-
- vals = {}
- m = re.search('const S32 LL_VERSION_MAJOR = (\d+);', data)
- vals['major'] = m.group(1)
- m = re.search('const S32 LL_VERSION_MINOR = (\d+);', data)
- vals['minor'] = m.group(1)
- m = re.search('const S32 LL_VERSION_PATCH = (\d+);', data)
- vals['patch'] = m.group(1)
- m = re.search('const S32 LL_VERSION_BUILD = (\d+);', data)
- vals['build'] = m.group(1)
-
- return "%(major)s.%(minor)s.%(patch)s.%(build)s" % vals
-
-if __name__ == '__main__':
- import sys
-
- try:
- for path in sys.argv[2:]:
- name = os.path.join(path, sys.argv[1])
- try:
- print get_version(name)
- break
- except OSError, err:
- if err.errno != errno.ENOENT:
- raise
- else:
- print >> sys.stderr, 'File not found:', sys.argv[1]
- sys.exit(1)
- except AttributeError:
- print >> sys.stderr, 'Error: malformatted file: ', name
- sys.exit(1)
- except IndexError:
- print >> sys.stderr, ('Usage: %s llversion[...].h [directories]' %
- sys.argv[0])
diff --git a/scripts/gpu_table_tester b/scripts/gpu_table_tester
new file mode 100755
index 0000000000..af0678000d
--- /dev/null
+++ b/scripts/gpu_table_tester
@@ -0,0 +1,293 @@
+#!/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} <gpu_table.txt> {--table-only|-t}
+
+ Checks for duplicates and invalid lines in the gpu_table.txt file.
+
+ $MyName {--gpu-table|-g} <gpu_table.txt> [ <gpu-strings-file> ... ]
+ [{--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} <gpu_table.txt> {--diff|-d} <old_results> [ <gpu-strings-file> ...]
+
+ With the --diff option, the report compares the current results to <old-results>,
+ 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 <gpu_table.txt> value"
+ unless $GpuTable;
+
+open(GPUS, "<$GpuTable")
+ || die "Failed to open gpu table '$GpuTable':\n\t$!\n";
+
+my $FirstLine = <GPUS>;
+die "First line of gpu table does not begin with '//GPU_TABLE'"
+ unless $FirstLine =~ m|^//GPU_TABLE|;
+
+# 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
+my %StatsBased;
+my %ExpectedOpenGL;
+
+$Name{$NoMatch} = $NoMatch;
+$NameLine{$NoMatch} = '(hard-coded)'; # use this for error messages in table parsing
+$Class{$NoMatch} = '';
+$Supported{$NoMatch} = '';
+$StatsBased{$NoMatch} = '';
+$ExpectedOpenGL{$NoMatch} = '';
+
+while (<GPUS>)
+{
+ next if m|^//|; # skip comments
+ next if m|^\s*$|; # skip blank lines
+
+ chomp;
+ my ($name, $regex, $class, $supported, $stats_based, $expected_opengl, $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/[012345]/)
+ {
+ 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 ($stats_based !~ m/[01]/)
+ {
+ print STDERR "Invalid stats_based value '$stats_based' on $GpuTable line $INPUT_LINE_NUMBER\n";
+ $ErrorsSeen++;
+ }
+ if ($expected_opengl !~ m/\d+(\.\d+)?/)
+ {
+ print STDERR "Invalid expected_opengl value '$expected_opengl' 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";
+ $StatsBased{$regex} = $stats_based;
+ $ExpectedOpenGL{$regex} = $expected_opengl;
+ }
+}
+
+close GPUS;
+
+print STDERR "\n" if $ErrorsSeen;
+
+exit $ErrorsSeen if $TableOnly;
+
+
+# Loop over input lines, find the results for each
+my %RecognizedBy;
+while (<>)
+{
+ chomp;
+ $_ = substr($_,0,100);
+ 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 Stats OpenGL Recognizer
+------------------------------------------------------------------------------------------------------ ----------- ----- ----- ------ ------------------------------------
+.
+format STDOUT =
+@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<< @> @> @<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<...
+$_, $Supported{$RecognizedBy{$_}},$Class{$RecognizedBy{$_}},$StatsBased{$RecognizedBy{$_}},$ExpectedOpenGL{$RecognizedBy{$_}},$Name{$RecognizedBy{$_}}
+.
+
+my $ReportLineTemplate = "A102xxxA12xxxA2xxxxA2xxxxA5A*"; # Used to read a previous report - MUST match the format STDOUT above
+
+my ( $oldSupported, $oldClass, $newSupported, $newClass );
+
+format DIFF_TOP =
+ ------------- OLD ------------- ----------- NEW --------------------
+GPU String Supported? Class Stats OpenGL Supported? Class Stats OpenGL Line
+------------------------------------------------------------------------------------------------------ ----------- ----- ----- ------ ----------- ----- ----- ------ -----
+.
+format DIFF =
+@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<< @> @> @<<<< @<<<<<<<<<< @> @> @<<<< @>>>>
+$_, $oldSupported, $oldClass, $oldStatsBased, $oldExpectedOpenGL, $newSupported, $newClass, $newStatsBased, $newExpectedOpenGL, $newRecognizedLine
+.
+
+if ( ! $Diff )
+{
+ ## Print results of testing each input line and how it was recognized.
+ foreach ( sort keys %RecognizedBy )
+ {
+ write if ! $UnMatchedOnly || $Name{$RecognizedBy{$_}} eq $NoMatch;
+ $-++; # suppresses pagination
+ }
+}
+else
+{
+ ## Print a comparison of how the recognition this time compared to the results from the $Diff file
+ open OLD, "<$Diff"
+ || die "Failed to open --diff file '$Diff'\n\t$!\n";
+ my $discard = 2;
+ while ( <OLD> )
+ {
+ if ( $discard <= 0 )
+ {
+ my ( $gpu, $supported, $class, $stats, $opengl ) = unpack $ReportLineTemplate;
+ $gpu =~ s/\s*$//;
+ ( $OldSupported{$gpu} = $supported ) =~ s/\s*$//;
+ ( $OldClass{$gpu} = $class ) =~ s/\s*$//;
+ ( $OldStatsBased{$gpu} = $stats ) =~ s/\s*$//;
+ ( $OldExpectedOpenGL{$gpu} = $opengl ) =~ 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{$_}};
+ $newStatsBased = $StatsBased{$RecognizedBy{$_}};
+ $newExpectedOpenGL = $ExpectedOpenGL{$RecognizedBy{$_}};
+ $newRecognizedLine = $RecognizerLine{$RecognizedBy{$_}};
+
+ if ( ! defined $OldSupported{$_} )
+ {
+ $oldSupported = 'NEW';
+ $oldClass = '-';
+ $oldStatsBased = '-';
+ $oldExpectedOpenGL = '-';
+ write;
+ $-++; # suppresses pagination
+ }
+ else
+ {
+ $oldSupported = $OldSupported{$_} || $NoMatch;
+ $oldClass = $OldClass{$_};
+ $oldStatsBased = $OldStatsBased{$_};
+ $oldExpectedOpenGL = $OldExpectedOpenGL{$_};
+
+ if ( ( $oldSupported ne $newSupported )
+ || ( $oldClass ne $newClass )
+ || ( $oldStatsBased ne $newStatsBased )
+ || ( $oldExpectedOpenGL ne $newExpectedOpenGL )
+ )
+ {
+ write;
+ $-++; # suppresses pagination
+ }
+ }
+
+ }
+}
+
+exit $ErrorsSeen;
diff --git a/scripts/install.py b/scripts/install.py
deleted file mode 100755
index 7368af0b37..0000000000
--- a/scripts/install.py
+++ /dev/null
@@ -1,1162 +0,0 @@
-#!/usr/bin/env python
-"""\
-@file install.py
-@author Phoenix
-@date 2008-01-27
-@brief Install files into an indra checkout.
-
-Install files as specified by:
-https://wiki.lindenlab.com/wiki/User:Phoenix/Library_Installation
-
-
-$LicenseInfo:firstyear=2007&license=mit$
-
-Copyright (c) 2007-2009, 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.
-$/LicenseInfo$
-"""
-
-import sys
-import os.path
-
-# Look for indra/lib/python in all possible parent directories ...
-# This is an improvement over the setup-path.py method used previously:
-# * the script may blocated anywhere inside the source tree
-# * it doesn't depend on the current directory
-# * it doesn't depend on another file being present.
-
-def add_indra_lib_path():
- root = os.path.realpath(__file__)
- # always insert the directory of the script in the search path
- dir = os.path.dirname(root)
- if dir not in sys.path:
- sys.path.insert(0, dir)
-
- # Now go look for indra/lib/python in the parent dies
- while root != os.path.sep:
- root = os.path.dirname(root)
- dir = os.path.join(root, 'indra', 'lib', 'python')
- if os.path.isdir(dir):
- if dir not in sys.path:
- sys.path.insert(0, dir)
- return root
- else:
- print >>sys.stderr, "This script is not inside a valid installation."
- sys.exit(1)
-
-base_dir = add_indra_lib_path()
-
-import copy
-import optparse
-import os
-import platform
-import pprint
-import shutil
-import tarfile
-import tempfile
-import urllib2
-import urlparse
-
-try:
- # Python 2.6
- from hashlib import md5
-except ImportError:
- # Python 2.5 and earlier
- from md5 import new as md5
-
-from indra.base import llsd
-from indra.util import helpformatter
-
-# *HACK: Necessary for python 2.3. Consider removing this code wart
-# after etch has deployed everywhere. 2008-12-23 Phoenix
-try:
- sorted = sorted
-except NameError:
- def sorted(in_list):
- "Return a list which is a sorted copy of in_list."
- # Copy the source to be more functional and side-effect free.
- out_list = copy.copy(in_list)
- out_list.sort()
- return out_list
-
-class InstallFile(object):
- "This is just a handy way to throw around details on a file in memory."
- def __init__(self, pkgname, url, md5sum, cache_dir, platform_path):
- self.pkgname = pkgname
- self.url = url
- self.md5sum = md5sum
- filename = urlparse.urlparse(url)[2].split('/')[-1]
- self.filename = os.path.join(cache_dir, filename)
- self.platform_path = platform_path
-
- def __str__(self):
- return "ifile{%s:%s}" % (self.pkgname, self.url)
-
- def _is_md5sum_match(self):
- hasher = md5(file(self.filename, 'rb').read())
- if hasher.hexdigest() == self.md5sum:
- return True
- return False
-
- def is_match(self, platform):
- """@brief Test to see if this ifile is part of platform
- @param platform The target platform. Eg, windows or linux/i686/gcc/3.3
- @return Returns True if the ifile is in the platform.
- """
- if self.platform_path[0] == 'common':
- return True
- req_platform_path = platform.split('/')
- #print "platform:",req_platform_path
- #print "path:",self.platform_path
- # to match, every path part much match
- match_count = min(len(req_platform_path), len(self.platform_path))
- for ii in range(0, match_count):
- if req_platform_path[ii] != self.platform_path[ii]:
- return False
- #print "match!"
- return True
-
- def fetch_local(self):
- #print "Looking for:",self.filename
- if not os.path.exists(self.filename):
- pass
- elif self.md5sum and not self._is_md5sum_match():
- print "md5 mismatch:", self.filename
- os.remove(self.filename)
- else:
- print "Found matching package:", self.filename
- return
- print "Downloading",self.url,"to local file",self.filename
- file(self.filename, 'wb').write(urllib2.urlopen(self.url).read())
- if self.md5sum and not self._is_md5sum_match():
- raise RuntimeError("Error matching md5 for %s" % self.url)
-
-class LicenseDefinition(object):
- def __init__(self, definition):
- #probably looks like:
- # { text : ...,
- # url : ...
- # blessed : ...
- # }
- self._definition = definition
-
-
-class InstallableDefinition(object):
- def __init__(self, definition):
- #probably looks like:
- # { packages : {platform...},
- # copyright : ...
- # license : ...
- # description: ...
- # }
- self._definition = definition
-
- def _ifiles_from(self, tree, pkgname, cache_dir):
- return self._ifiles_from_path(tree, pkgname, cache_dir, [])
-
- def _ifiles_from_path(self, tree, pkgname, cache_dir, path):
- ifiles = []
- if 'url' in tree:
- ifiles.append(InstallFile(
- pkgname,
- tree['url'],
- tree.get('md5sum', None),
- cache_dir,
- path))
- else:
- for key in tree:
- platform_path = copy.copy(path)
- platform_path.append(key)
- ifiles.extend(
- self._ifiles_from_path(
- tree[key],
- pkgname,
- cache_dir,
- platform_path))
- return ifiles
-
- def ifiles(self, pkgname, platform, cache_dir):
- """@brief return a list of appropriate InstallFile instances to install
- @param pkgname The name of the package to be installed, eg 'tut'
- @param platform The target platform. Eg, windows or linux/i686/gcc/3.3
- @param cache_dir The directory to cache downloads.
- @return Returns a list of InstallFiles which are part of this install
- """
- if 'packages' not in self._definition:
- return []
- all_ifiles = self._ifiles_from(
- self._definition['packages'],
- pkgname,
- cache_dir)
- if platform == 'all':
- return all_ifiles
- #print "Considering", len(all_ifiles), "packages for", pkgname
- # split into 2 lines because pychecker thinks it might return none.
- files = [ifile for ifile in all_ifiles if ifile.is_match(platform)]
- return files
-
-class InstalledPackage(object):
- def __init__(self, definition):
- # looks like:
- # { url1 : { files: [file1,file2,...], md5sum:... },
- # url2 : { files: [file1,file2,...], md5sum:... },...
- # }
- self._installed = {}
- for url in definition:
- self._installed[url] = definition[url]
-
- def urls(self):
- return self._installed.keys()
-
- def files_in(self, url):
- return self._installed[url].get('files', [])
-
- def get_md5sum(self, url):
- return self._installed[url].get('md5sum', None)
-
- def remove(self, url):
- self._installed.pop(url)
-
- def add_files(self, url, files):
- if url not in self._installed:
- self._installed[url] = {}
- self._installed[url]['files'] = files
-
- def set_md5sum(self, url, md5sum):
- if url not in self._installed:
- self._installed[url] = {}
- self._installed[url]['md5sum'] = md5sum
-
-class Installer(object):
- def __init__(self, install_filename, installed_filename, dryrun):
- self._install_filename = install_filename
- self._install_changed = False
- self._installed_filename = installed_filename
- self._installed_changed = False
- self._dryrun = dryrun
- self._installables = {}
- self._licenses = {}
- self._installed = {}
- self.load()
-
- def load(self):
- if os.path.exists(self._install_filename):
- install = llsd.parse(file(self._install_filename, 'rb').read())
- try:
- for name in install['installables']:
- self._installables[name] = InstallableDefinition(
- install['installables'][name])
- except KeyError:
- pass
- try:
- for name in install['licenses']:
- self._licenses[name] = LicenseDefinition(install['licenses'][name])
- except KeyError:
- pass
- if os.path.exists(self._installed_filename):
- installed = llsd.parse(file(self._installed_filename, 'rb').read())
- try:
- bins = installed['installables']
- for name in bins:
- self._installed[name] = InstalledPackage(bins[name])
- except KeyError:
- pass
-
- def _write(self, filename, state):
- print "Writing state to",filename
- if not self._dryrun:
- file(filename, 'wb').write(llsd.format_pretty_xml(state))
-
- def save(self):
- if self._install_changed:
- state = {}
- state['licenses'] = {}
- for name in self._licenses:
- state['licenses'][name] = self._licenses[name]._definition
- #print "self._installables:",self._installables
- state['installables'] = {}
- for name in self._installables:
- state['installables'][name] = \
- self._installables[name]._definition
- self._write(self._install_filename, state)
- if self._installed_changed:
- state = {}
- state['installables'] = {}
- bin = state['installables']
- for name in self._installed:
- #print "installed:",name,self._installed[name]._installed
- bin[name] = self._installed[name]._installed
- self._write(self._installed_filename, state)
-
- def is_valid_license(self, bin):
- "@brief retrun true if we have valid license info for installable."
- installable = self._installables[bin]._definition
- if 'license' not in installable:
- print >>sys.stderr, "No license info found for", bin
- print >>sys.stderr, 'Please add the license with the',
- print >>sys.stderr, '--add-installable option. See', \
- sys.argv[0], '--help'
- return False
- if installable['license'] not in self._licenses:
- lic = installable['license']
- print >>sys.stderr, "Missing license info for '" + lic + "'.",
- print >>sys.stderr, 'Please add the license with the',
- print >>sys.stderr, '--add-license option. See', sys.argv[0],
- print >>sys.stderr, '--help'
- return False
- return True
-
- def list_installables(self):
- "Return a list of all known installables."
- return sorted(self._installables.keys())
-
- def detail_installable(self, name):
- "Return a installable definition detail"
- return self._installables[name]._definition
-
- def list_licenses(self):
- "Return a list of all known licenses."
- return sorted(self._licenses.keys())
-
- def detail_license(self, name):
- "Return a license definition detail"
- return self._licenses[name]._definition
-
- def list_installed(self):
- "Return a list of installed packages."
- return sorted(self._installed.keys())
-
- def detail_installed(self, name):
- "Return file list for specific installed package."
- filelist = []
- for url in self._installed[name]._installed.keys():
- filelist.extend(self._installed[name].files_in(url))
- return filelist
-
- def _update_field(self, description, field, value, multiline=False):
- """Given a block and a field name, add or update it.
- @param description a dict containing all the details of a description.
- @param field the name of the field to update.
- @param value the value of the field to update; if omitted, interview
- will ask for value.
- @param multiline boolean specifying whether field is multiline or not.
- """
- if value:
- description[field] = value
- else:
- if field in description:
- print "Update value for '" + field + "'"
- print "(Leave blank to keep current value)"
- print "Current Value: '" + description[field] + "'"
- else:
- print "Specify value for '" + field + "'"
- if not multiline:
- new_value = raw_input("Enter New Value: ")
- else:
- print "Please enter " + field + ". End input with EOF (^D)."
- new_value = sys.stdin.read()
-
- if field in description and not new_value:
- pass
- elif new_value:
- description[field] = new_value
-
- self._install_changed = True
- return True
-
- def _update_installable(self, name, platform, url, md5sum):
- """Update installable entry with specific package information.
- @param installable[in,out] a dict containing installable details.
- @param platform Platform info, i.e. linux/i686, windows/i686 etc.
- @param url URL of tar file
- @param md5sum md5sum of tar file
- """
- installable = self._installables[name]._definition
- path = platform.split('/')
- if 'packages' not in installable:
- installable['packages'] = {}
- update = installable['packages']
- for child in path:
- if child not in update:
- update[child] = {}
- parent = update
- update = update[child]
- parent[child]['url'] = llsd.uri(url)
- parent[child]['md5sum'] = md5sum
-
- self._install_changed = True
- return True
-
-
- def add_installable_package(self, name, **kwargs):
- """Add an url for a platform path to the installable.
- @param installable[in,out] a dict containing installable details.
- """
- platform_help_str = """\
-Please enter a new package location and url. Some examples:
-common -- specify a package for all platforms
-linux -- specify a package for all arch and compilers on linux
-darwin/universal -- specify a mac os x universal
-windows/i686/vs/2003 -- specify a windows visual studio 2003 package"""
- if name not in self._installables:
- print "Error: must add library with --add-installable or " \
- +"--add-installable-metadata before using " \
- +"--add-installable-package option"
- return False
- else:
- print "Updating installable '" + name + "'."
- for arg in ('platform', 'url', 'md5sum'):
- if not kwargs[arg]:
- if arg == 'platform':
- print platform_help_str
- kwargs[arg] = raw_input("Package "+arg+":")
- #path = kwargs['platform'].split('/')
-
- return self._update_installable(name, kwargs['platform'],
- kwargs['url'], kwargs['md5sum'])
-
- def add_installable_metadata(self, name, **kwargs):
- """Interactively add (only) library metadata into install,
- w/o adding installable"""
- if name not in self._installables:
- print "Adding installable '" + name + "'."
- self._installables[name] = InstallableDefinition({})
- else:
- print "Updating installable '" + name + "'."
- installable = self._installables[name]._definition
- for field in ('copyright', 'license', 'description'):
- self._update_field(installable, field, kwargs[field])
- print "Added installable '" + name + "':"
- pprint.pprint(self._installables[name])
-
- return True
-
- def add_installable(self, name, **kwargs):
- "Interactively pull a new installable into the install"
- ret_a = self.add_installable_metadata(name, **kwargs)
- ret_b = self.add_installable_package(name, **kwargs)
- return (ret_a and ret_b)
-
- def remove_installable(self, name):
- self._installables.pop(name)
- self._install_changed = True
-
- def add_license(self, name, **kwargs):
- if name not in self._licenses:
- print "Adding license '" + name + "'."
- self._licenses[name] = LicenseDefinition({})
- else:
- print "Updating license '" + name + "'."
- the_license = self._licenses[name]._definition
- for field in ('url', 'text'):
- multiline = False
- if field == 'text':
- multiline = True
- self._update_field(the_license, field, kwargs[field], multiline)
- self._install_changed = True
- return True
-
- def remove_license(self, name):
- self._licenses.pop(name)
- self._install_changed = True
-
- def _uninstall(self, installables):
- """@brief Do the actual removal of files work.
- *NOTE: This method is not transactionally safe -- ie, if it
- raises an exception, internal state may be inconsistent. How
- should we address this?
- @param installables The package names to remove
- """
- remove_file_list = []
- for pkgname in installables:
- for url in self._installed[pkgname].urls():
- remove_file_list.extend(
- self._installed[pkgname].files_in(url))
- self._installed[pkgname].remove(url)
- if not self._dryrun:
- self._installed_changed = True
- if not self._dryrun:
- self._installed.pop(pkgname)
- remove_dir_set = set()
- for filename in remove_file_list:
- print "rm",filename
- if not self._dryrun:
- if os.path.exists(filename):
- remove_dir_set.add(os.path.dirname(filename))
- try:
- os.remove(filename)
- except OSError:
- # This is just for cleanup, so we don't care
- # about normal failures.
- pass
- for dirname in remove_dir_set:
- try:
- os.removedirs(dirname)
- except OSError:
- # This is just for cleanup, so we don't care about
- # normal failures.
- pass
-
- def uninstall(self, installables, install_dir):
- """@brief Remove the packages specified.
- @param installables The package names to remove
- @param install_dir The directory to work from
- """
- print "uninstall",installables,"from",install_dir
- cwd = os.getcwdu()
- os.chdir(install_dir)
- try:
- self._uninstall(installables)
- finally:
- os.chdir(cwd)
-
- def _build_ifiles(self, platform, cache_dir):
- """@brief determine what files to install
- @param platform The target platform. Eg, windows or linux/i686/gcc/3.3
- @param cache_dir The directory to cache downloads.
- @return Returns the ifiles to install
- """
- ifiles = []
- for bin in self._installables:
- ifiles.extend(self._installables[bin].ifiles(bin,
- platform,
- cache_dir))
- to_install = []
- #print "self._installed",self._installed
- for ifile in ifiles:
- if ifile.pkgname not in self._installed:
- to_install.append(ifile)
- elif ifile.url not in self._installed[ifile.pkgname].urls():
- to_install.append(ifile)
- elif ifile.md5sum != \
- self._installed[ifile.pkgname].get_md5sum(ifile.url):
- # *TODO: We may want to uninstall the old version too
- # when we detect it is installed, but the md5 sum is
- # different.
- to_install.append(ifile)
- else:
- #print "Installation up to date:",
- # ifile.pkgname,ifile.platform_path
- pass
- #print "to_install",to_install
- return to_install
-
- def _install(self, to_install, install_dir):
- for ifile in to_install:
- tar = tarfile.open(ifile.filename, 'r')
- print "Extracting",ifile.filename,"to",install_dir
- if not self._dryrun:
- # *NOTE: try to call extractall, which first appears
- # in python 2.5. Phoenix 2008-01-28
- try:
- tar.extractall(path=install_dir)
- except AttributeError:
- _extractall(tar, path=install_dir)
- if ifile.pkgname in self._installed:
- self._installed[ifile.pkgname].add_files(
- ifile.url,
- tar.getnames())
- self._installed[ifile.pkgname].set_md5sum(
- ifile.url,
- ifile.md5sum)
- else:
- # *HACK: this understands the installed package syntax.
- definition = { ifile.url :
- {'files': tar.getnames(),
- 'md5sum' : ifile.md5sum } }
- self._installed[ifile.pkgname] = InstalledPackage(definition)
- self._installed_changed = True
-
- def install(self, installables, platform, install_dir, cache_dir):
- """@brief Do the installation for for the platform.
- @param installables The requested installables to install.
- @param platform The target platform. Eg, windows or linux/i686/gcc/3.3
- @param install_dir The root directory to install into. Created
- if missing.
- @param cache_dir The directory to cache downloads. Created if
- missing.
- """
- # The ordering of steps in the method is to help reduce the
- # likelihood that we break something.
- install_dir = os.path.realpath(install_dir)
- cache_dir = os.path.realpath(cache_dir)
- _mkdir(install_dir)
- _mkdir(cache_dir)
- to_install = self._build_ifiles(platform, cache_dir)
-
- # Filter for files which we actually requested to install.
- to_install = [ifl for ifl in to_install if ifl.pkgname in installables]
- for ifile in to_install:
- ifile.fetch_local()
- self._install(to_install, install_dir)
-
- def do_install(self, installables, platform, install_dir, cache_dir=None,
- check_license=True, scp=None):
- """Determine what installables should be installed. If they were
- passed in on the command line, use them, otherwise install
- all known installables.
- """
- if not cache_dir:
- cache_dir = _default_installable_cache()
- all_installables = self.list_installables()
- if not len(installables):
- install_installables = all_installables
- else:
- # passed in on the command line. We'll need to verify we
- # know about them here.
- install_installables = installables
- for installable in install_installables:
- if installable not in all_installables:
- raise RuntimeError('Unknown installable: %s' %
- (installable,))
- if check_license:
- # *TODO: check against a list of 'known good' licenses.
- # *TODO: check for urls which conflict -- will lead to
- # problems.
- for installable in install_installables:
- if not self.is_valid_license(installable):
- return 1
-
- # Set up the 'scp' handler
- opener = urllib2.build_opener()
- scp_or_http = SCPOrHTTPHandler(scp)
- opener.add_handler(scp_or_http)
- urllib2.install_opener(opener)
-
- # Do the work of installing the requested installables.
- self.install(
- install_installables,
- platform,
- install_dir,
- cache_dir)
- scp_or_http.cleanup()
-
- def do_uninstall(self, installables, install_dir):
- # Do not bother to check license if we're uninstalling.
- all_installed = self.list_installed()
- if not len(installables):
- uninstall_installables = all_installed
- else:
- # passed in on the command line. We'll need to verify we
- # know about them here.
- uninstall_installables = installables
- for installable in uninstall_installables:
- if installable not in all_installed:
- raise RuntimeError('Installable not installed: %s' %
- (installable,))
- self.uninstall(uninstall_installables, install_dir)
-
-class SCPOrHTTPHandler(urllib2.BaseHandler):
- """Evil hack to allow both the build system and developers consume
- proprietary binaries.
- To use http, export the environment variable:
- INSTALL_USE_HTTP_FOR_SCP=true
- """
- def __init__(self, scp_binary):
- self._scp = scp_binary
- self._dir = None
-
- def scp_open(self, request):
- #scp:codex.lindenlab.com:/local/share/install_pkgs/package.tar.bz2
- remote = request.get_full_url()[4:]
- if os.getenv('INSTALL_USE_HTTP_FOR_SCP', None) == 'true':
- return self.do_http(remote)
- try:
- return self.do_scp(remote)
- except:
- self.cleanup()
- raise
-
- def do_http(self, remote):
- url = remote.split(':',1)
- if not url[1].startswith('/'):
- # in case it's in a homedir or something
- url.insert(1, '/')
- url.insert(0, "http://")
- url = ''.join(url)
- print "Using HTTP:",url
- return urllib2.urlopen(url)
-
- def do_scp(self, remote):
- if not self._dir:
- self._dir = tempfile.mkdtemp()
- local = os.path.join(self._dir, remote.split('/')[-1:][0])
- command = []
- for part in (self._scp, remote, local):
- if ' ' in part:
- # I hate shell escaping.
- part.replace('\\', '\\\\')
- part.replace('"', '\\"')
- command.append('"%s"' % part)
- else:
- command.append(part)
- #print "forking:", command
- rv = os.system(' '.join(command))
- if rv != 0:
- raise RuntimeError("Cannot fetch: %s" % remote)
- return file(local, 'rb')
-
- def cleanup(self):
- if self._dir:
- shutil.rmtree(self._dir)
-
-
-#
-# *NOTE: PULLED FROM PYTHON 2.5 tarfile.py Phoenix 2008-01-28
-#
-def _extractall(tar, path=".", members=None):
- """Extract all members from the archive to the current working
- directory and set owner, modification time and permissions on
- directories afterwards. `path' specifies a different directory
- to extract to. `members' is optional and must be a subset of the
- list returned by getmembers().
- """
- directories = []
-
- if members is None:
- members = tar
-
- for tarinfo in members:
- if tarinfo.isdir():
- # Extract directory with a safe mode, so that
- # all files below can be extracted as well.
- try:
- os.makedirs(os.path.join(path, tarinfo.name), 0777)
- except EnvironmentError:
- pass
- directories.append(tarinfo)
- else:
- tar.extract(tarinfo, path)
-
- # Reverse sort directories.
- directories.sort(lambda a, b: cmp(a.name, b.name))
- directories.reverse()
-
- # Set correct owner, mtime and filemode on directories.
- for tarinfo in directories:
- path = os.path.join(path, tarinfo.name)
- try:
- tar.chown(tarinfo, path)
- tar.utime(tarinfo, path)
- tar.chmod(tarinfo, path)
- except tarfile.ExtractError, e:
- if tar.errorlevel > 1:
- raise
- else:
- tar._dbg(1, "tarfile: %s" % e)
-
-
-def _mkdir(directory):
- "Safe, repeatable way to make a directory."
- if not os.path.exists(directory):
- os.makedirs(directory)
-
-def _get_platform():
- "Return appropriate platform packages for the environment."
- platform_map = {
- 'darwin': 'darwin',
- 'linux2': 'linux',
- 'win32' : 'windows',
- 'cygwin' : 'windows',
- 'solaris' : 'solaris'
- }
- this_platform = platform_map[sys.platform]
- if this_platform == 'linux':
- if platform.architecture()[0] == '64bit':
- # TODO -- someday when install.py accepts a platform of the form
- # os/arch/compiler/compiler_version then we can replace the
- # 'linux64' platform with 'linux/x86_64/gcc/4.1'
- this_platform = 'linux'
- return this_platform
-
-def _getuser():
- "Get the user"
- try:
- # Unix-only.
- import getpass
- return getpass.getuser()
- except ImportError:
- import ctypes
- MAX_PATH = 260 # according to a recent WinDef.h
- name = ctypes.create_unicode_buffer(MAX_PATH)
- namelen = ctypes.c_int(len(name)) # len in chars, NOT bytes
- if not ctypes.windll.advapi32.GetUserNameW(name, ctypes.byref(namelen)):
- raise ctypes.WinError()
- return name.value
-
-def _default_installable_cache():
- """In general, the installable files do not change much, so find a
- host/user specific location to cache files."""
- user = _getuser()
- cache_dir = "/var/tmp/%s/install.cache" % user
- if _get_platform() == 'windows':
- cache_dir = os.path.join(tempfile.gettempdir(), \
- 'install.cache.%s' % user)
- return cache_dir
-
-def parse_args():
- parser = optparse.OptionParser(
- usage="usage: %prog [options] [installable1 [installable2...]]",
- formatter = helpformatter.Formatter(),
- description="""This script fetches and installs installable packages.
-It also handles uninstalling those packages and manages the mapping between
-packages and their license.
-
-The process is to open and read an install manifest file which specifies
-what files should be installed. For each installable to be installed.
- * make sure it has a license
- * check the installed version
- ** if not installed and needs to be, download and install
- ** if installed version differs, download & install
-
-If no installables are specified on the command line, then the defaut
-behavior is to install all known installables appropriate for the platform
-specified or uninstall all installables if --uninstall is set. You can specify
-more than one installable on the command line.
-
-When specifying a platform, you can specify 'all' to install all
-packages, or any platform of the form:
-
-OS[/arch[/compiler[/compiler_version]]]
-
-Where the supported values for each are:
-OS: darwin, linux, windows, solaris
-arch: i686, x86_64, ppc, universal
-compiler: vs, gcc
-compiler_version: 2003, 2005, 2008, 3.3, 3.4, 4.0, etc.
-
-No checks are made to ensure a valid combination of platform
-parts. Some exmples of valid platforms:
-
-windows
-windows/i686/vs/2005
-linux/x86_64/gcc/3.3
-linux/x86_64/gcc/4.0
-darwin/universal/gcc/4.0
-""")
- parser.add_option(
- '--dry-run',
- action='store_true',
- default=False,
- dest='dryrun',
- help='Do not actually install files. Downloads will still happen.')
- parser.add_option(
- '--install-manifest',
- type='string',
- default=os.path.join(base_dir, 'install.xml'),
- dest='install_filename',
- help='The file used to describe what should be installed.')
- parser.add_option(
- '--installed-manifest',
- type='string',
- default=os.path.join(base_dir, 'installed.xml'),
- dest='installed_filename',
- help='The file used to record what is installed.')
- parser.add_option(
- '--export-manifest',
- action='store_true',
- default=False,
- dest='export_manifest',
- help="Print the install manifest to stdout and exit.")
- parser.add_option(
- '-p', '--platform',
- type='string',
- default=_get_platform(),
- dest='platform',
- help="""Override the automatically determined platform. \
-You can specify 'all' to do a installation of installables for all platforms.""")
- parser.add_option(
- '--cache-dir',
- type='string',
- default=_default_installable_cache(),
- dest='cache_dir',
- help='Where to download files. Default: %s'% \
- (_default_installable_cache()))
- parser.add_option(
- '--install-dir',
- type='string',
- default=base_dir,
- dest='install_dir',
- help='Where to unpack the installed files.')
- parser.add_option(
- '--list-installed',
- action='store_true',
- default=False,
- dest='list_installed',
- help="List the installed package names and exit.")
- parser.add_option(
- '--skip-license-check',
- action='store_false',
- default=True,
- dest='check_license',
- help="Do not perform the license check.")
- parser.add_option(
- '--list-licenses',
- action='store_true',
- default=False,
- dest='list_licenses',
- help="List known licenses and exit.")
- parser.add_option(
- '--detail-license',
- type='string',
- default=None,
- dest='detail_license',
- help="Get detailed information on specified license and exit.")
- parser.add_option(
- '--add-license',
- type='string',
- default=None,
- dest='new_license',
- help="""Add a license to the install file. Argument is the name of \
-license. Specify --license-url if the license is remote or specify \
---license-text, otherwse the license text will be read from standard \
-input.""")
- parser.add_option(
- '--license-url',
- type='string',
- default=None,
- dest='license_url',
- help="""Put the specified url into an added license. \
-Ignored if --add-license is not specified.""")
- parser.add_option(
- '--license-text',
- type='string',
- default=None,
- dest='license_text',
- help="""Put the text into an added license. \
-Ignored if --add-license is not specified.""")
- parser.add_option(
- '--remove-license',
- type='string',
- default=None,
- dest='remove_license',
- help="Remove a named license.")
- parser.add_option(
- '--remove-installable',
- type='string',
- default=None,
- dest='remove_installable',
- help="Remove a installable from the install file.")
- parser.add_option(
- '--add-installable',
- type='string',
- default=None,
- dest='add_installable',
- help="""Add a installable into the install file. Argument is \
-the name of the installable to add.""")
- parser.add_option(
- '--add-installable-metadata',
- type='string',
- default=None,
- dest='add_installable_metadata',
- help="""Add package for library into the install file. Argument is \
-the name of the library to add.""")
- parser.add_option(
- '--installable-copyright',
- type='string',
- default=None,
- dest='installable_copyright',
- help="""Copyright for specified new package. Ignored if \
---add-installable is not specified.""")
- parser.add_option(
- '--installable-license',
- type='string',
- default=None,
- dest='installable_license',
- help="""Name of license for specified new package. Ignored if \
---add-installable is not specified.""")
- parser.add_option(
- '--installable-description',
- type='string',
- default=None,
- dest='installable_description',
- help="""Description for specified new package. Ignored if \
---add-installable is not specified.""")
- parser.add_option(
- '--add-installable-package',
- type='string',
- default=None,
- dest='add_installable_package',
- help="""Add package for library into the install file. Argument is \
-the name of the library to add.""")
- parser.add_option(
- '--package-platform',
- type='string',
- default=None,
- dest='package_platform',
- help="""Platform for specified new package. \
-Ignored if --add-installable or --add-installable-package is not specified.""")
- parser.add_option(
- '--package-url',
- type='string',
- default=None,
- dest='package_url',
- help="""URL for specified package. \
-Ignored if --add-installable or --add-installable-package is not specified.""")
- parser.add_option(
- '--package-md5',
- type='string',
- default=None,
- dest='package_md5',
- help="""md5sum for new package. \
-Ignored if --add-installable or --add-installable-package is not specified.""")
- parser.add_option(
- '--list',
- action='store_true',
- default=False,
- dest='list_installables',
- help="List the installables in the install manifest and exit.")
- parser.add_option(
- '--detail',
- type='string',
- default=None,
- dest='detail_installable',
- help="Get detailed information on specified installable and exit.")
- parser.add_option(
- '--detail-installed',
- type='string',
- default=None,
- dest='detail_installed',
- help="Get list of files for specified installed installable and exit.")
- parser.add_option(
- '--uninstall',
- action='store_true',
- default=False,
- dest='uninstall',
- help="""Remove the installables specified in the arguments. Just like \
-during installation, if no installables are listed then all installed \
-installables are removed.""")
- parser.add_option(
- '--scp',
- type='string',
- default='scp',
- dest='scp',
- help="Specify the path to your scp program.")
-
- return parser.parse_args()
-
-def main():
- options, args = parse_args()
- installer = Installer(
- options.install_filename,
- options.installed_filename,
- options.dryrun)
-
- #
- # Handle the queries for information
- #
- if options.list_installed:
- print "installed list:", installer.list_installed()
- return 0
- if options.list_installables:
- print "installable list:", installer.list_installables()
- return 0
- if options.detail_installable:
- try:
- detail = installer.detail_installable(options.detail_installable)
- print "Detail on installable",options.detail_installable+":"
- pprint.pprint(detail)
- except KeyError:
- print "Installable '"+options.detail_installable+"' not found in",
- print "install file."
- return 0
- if options.detail_installed:
- try:
- detail = installer.detail_installed(options.detail_installed)
- #print "Detail on installed",options.detail_installed+":"
- for line in detail:
- print line
- except:
- raise
- print "Installable '"+options.detail_installed+"' not found in ",
- print "install file."
- return 0
- if options.list_licenses:
- print "license list:", installer.list_licenses()
- return 0
- if options.detail_license:
- try:
- detail = installer.detail_license(options.detail_license)
- print "Detail on license",options.detail_license+":"
- pprint.pprint(detail)
- except KeyError:
- print "License '"+options.detail_license+"' not defined in",
- print "install file."
- return 0
- if options.export_manifest:
- # *HACK: just re-parse the install manifest and pretty print
- # it. easier than looking at the datastructure designed for
- # actually determining what to install
- install = llsd.parse(file(options.install_filename, 'rb').read())
- pprint.pprint(install)
- return 0
-
- #
- # Handle updates -- can only do one of these
- # *TODO: should this change the command line syntax?
- #
- if options.new_license:
- if not installer.add_license(
- options.new_license,
- text=options.license_text,
- url=options.license_url):
- return 1
- elif options.remove_license:
- installer.remove_license(options.remove_license)
- elif options.remove_installable:
- installer.remove_installable(options.remove_installable)
- elif options.add_installable:
- if not installer.add_installable(
- options.add_installable,
- copyright=options.installable_copyright,
- license=options.installable_license,
- description=options.installable_description,
- platform=options.package_platform,
- url=options.package_url,
- md5sum=options.package_md5):
- return 1
- elif options.add_installable_metadata:
- if not installer.add_installable_metadata(
- options.add_installable_metadata,
- copyright=options.installable_copyright,
- license=options.installable_license,
- description=options.installable_description):
- return 1
- elif options.add_installable_package:
- if not installer.add_installable_package(
- options.add_installable_package,
- platform=options.package_platform,
- url=options.package_url,
- md5sum=options.package_md5):
- return 1
- elif options.uninstall:
- installer.do_uninstall(args, options.install_dir)
- else:
- installer.do_install(args, options.platform, options.install_dir,
- options.cache_dir, options.check_license,
- options.scp)
-
- # save out any changes
- installer.save()
- return 0
-
-if __name__ == '__main__':
- #print sys.argv
- sys.exit(main())
diff --git a/scripts/md5check.py b/scripts/md5check.py
new file mode 100755
index 0000000000..1a54a2844c
--- /dev/null
+++ b/scripts/md5check.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+"""\
+@file md5check.py
+@brief Replacement for message template compatibility verifier.
+
+$LicenseInfo:firstyear=2010&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2010-2011, Linden Research, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation;
+version 2.1 of the License only.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+$/LicenseInfo$
+"""
+
+import sys
+import hashlib
+
+if len(sys.argv) != 3:
+ print """Usage: %s --create|<hash-digest> <file>
+
+Creates an md5sum hash digest of the specified file content
+and compares it with the given hash digest.
+
+If --create is used instead of a hash digest, it will simply
+print out the hash digest of specified file content.
+""" % sys.argv[0]
+ sys.exit(1)
+
+if sys.argv[2] == '-':
+ fh = sys.stdin
+ filename = "<stdin>"
+else:
+ filename = sys.argv[2]
+ fh = open(filename)
+
+hexdigest = hashlib.md5(fh.read()).hexdigest()
+if sys.argv[1] == '--create':
+ print hexdigest
+elif hexdigest == sys.argv[1]:
+ print "md5sum check passed:", filename
+else:
+ print "md5sum check FAILED:", filename
+ sys.exit(1)
diff --git a/scripts/messages/message_template.msg b/scripts/messages/message_template.msg
index d4f791c202..3cec4ada1c 100644..100755
--- a/scripts/messages/message_template.msg
+++ b/scripts/messages/message_template.msg
@@ -2061,6 +2061,15 @@ version 2.0
{ IsPhantom BOOL }
{ CastsShadows BOOL }
}
+ {
+ ExtraPhysics Variable
+ { PhysicsShapeType U8 }
+ { Density F32 }
+ { Friction F32 }
+ { Restitution F32 }
+ { GravityMultiplier F32 }
+
+ }
}
@@ -2930,6 +2939,10 @@ version 2.0
PidStat Single
{ PID S32 }
}
+ {
+ RegionInfo Variable
+ { RegionFlagsExtended U64 }
+ }
}
// viewer -> sim
@@ -2966,7 +2979,7 @@ version 2.0
{ BillableFactor F32 }
{ ObjectBonusFactor F32 }
{ WaterHeight F32 }
- { TerrainRaiseLimit F32 }
+ { TerrainRaiseLimit F32 }
{ TerrainLowerLimit F32 }
{ PricePerMeter S32 }
{ RedirectGridX S32 }
@@ -2982,6 +2995,10 @@ version 2.0
{ HardMaxAgents U32 }
{ HardMaxObjects U32 }
}
+ {
+ RegionInfo3 Variable
+ { RegionFlagsExtended U64 }
+ }
}
// GodUpdateRegionInfo
@@ -3007,6 +3024,10 @@ version 2.0
{ RedirectGridX S32 }
{ RedirectGridY S32 }
}
+ {
+ RegionInfo2 Variable
+ { RegionFlagsExtended U64 }
+ }
}
//NearestLandingRegionRequest
@@ -3107,6 +3128,11 @@ version 2.0
{ ProductSKU Variable 1 } // string
{ ProductName Variable 1 } // string
}
+ {
+ RegionInfo4 Variable
+ { RegionFlagsExtended U64 }
+ { RegionProtocols U64 }
+ }
}
// RegionHandshakeReply
@@ -3562,6 +3588,16 @@ version 2.0
VisualParam Variable
{ ParamValue U8 }
}
+ {
+ AppearanceData Variable
+ { AppearanceVersion U8 }
+ { CofVersion S32 }
+ { Flags U32 }
+ }
+ {
+ AppearanceHover Variable
+ { HoverHeight LLVector3 }
+ }
}
// AvatarSitResponse - response to a request to sit on an object
@@ -4242,6 +4278,10 @@ version 2.0
Buttons Variable
{ ButtonLabel Variable 1 }
}
+ {
+ OwnerData Variable
+ { OwnerID LLUUID }
+ }
}
@@ -6762,6 +6802,8 @@ version 2.0
}
// And, the money transfer
+// *NOTE: Unused as of 2010-04-06, because all back-end money transactions
+// are done with web services via L$ API. JC
{
MoneyTransferBackend Low 312 Trusted Zerocoded
{
@@ -6812,6 +6854,19 @@ version 2.0
{ SquareMetersCommitted S32 }
{ Description Variable 1 } // string
}
+ // For replies that are part of a transaction (buying something) provide
+ // metadata for localization. If TransactionType is 0, the message is
+ // purely a balance update. Added for server 1.40 and viewer 2.1. JC
+ {
+ TransactionInfo Single
+ { TransactionType S32 } // lltransactiontype.h
+ { SourceID LLUUID }
+ { IsSourceGroup BOOL }
+ { DestID LLUUID }
+ { IsDestGroup BOOL }
+ { Amount S32 }
+ { ItemDescription Variable 1 } // string
+ }
}
@@ -6838,6 +6893,17 @@ version 2.0
{ SquareMetersCommitted S32 }
{ Description Variable 1 } // string
}
+ // See MoneyBalanceReply above.
+ {
+ TransactionInfo Single
+ { TransactionType S32 } // lltransactiontype.h
+ { SourceID LLUUID }
+ { IsSourceGroup BOOL }
+ { DestID LLUUID }
+ { IsDestGroup BOOL }
+ { Amount S32 }
+ { ItemDescription Variable 1 } // string
+ }
}
@@ -8972,5 +9038,7 @@ version 2.0
{ InvType S8 }
{ Name Variable 1 }
{ Description Variable 1 }
+
}
}
+
diff --git a/scripts/messages/message_template.msg.sha1 b/scripts/messages/message_template.msg.sha1
new file mode 100755
index 0000000000..e699efb03c
--- /dev/null
+++ b/scripts/messages/message_template.msg.sha1
@@ -0,0 +1 @@
+2286adc795b1b06eb86fdda431a71a6f0874b4f1 \ No newline at end of file
diff --git a/scripts/packages-formatter.py b/scripts/packages-formatter.py
new file mode 100755
index 0000000000..4e66cf9ed4
--- /dev/null
+++ b/scripts/packages-formatter.py
@@ -0,0 +1,93 @@
+#!/usr/bin/env python
+"""\
+This module formats the package version and copyright information for the
+viewer and its dependent packages.
+
+$LicenseInfo:firstyear=2014&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2014, Linden Research, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation;
+version 2.1 of the License only.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+$/LicenseInfo$
+"""
+import os
+import sys
+import errno
+import re
+import subprocess
+
+_autobuild=os.getenv('AUTOBUILD', 'autobuild')
+
+pkg_line=re.compile('^([\w-]+):\s+(.*)$')
+
+def autobuild(*args):
+ """
+ Launch autobuild with specified command-line arguments.
+ Return its stdout pipe from which the caller can read.
+ """
+ # subprocess wants a list, not a tuple
+ command = [_autobuild] + list(args)
+ try:
+ child = subprocess.Popen(command,
+ stdin=None, stdout=subprocess.PIPE,
+ universal_newlines=True)
+ except OSError as err:
+ if err.errno != errno.ENOENT:
+ # Don't attempt to interpret anything but ENOENT
+ raise
+ # Here it's ENOENT: subprocess can't find the autobuild executable.
+ print >>sys.stderr, "packages-formatter on %s: can't run autobuild:\n%s\n%s" % \
+ (sys.platform, ' '.join(command), err)
+ sys.exit(1)
+
+ # no exceptions yet, let caller read stdout
+ return child.stdout
+
+version={}
+versions=autobuild('install', '--versions')
+for line in versions:
+ pkg_info = pkg_line.match(line)
+ if pkg_info:
+ pkg = pkg_info.group(1)
+ if pkg not in version:
+ version[pkg] = pkg_info.group(2).strip()
+ else:
+ sys.exit("Duplicate version for %s" % pkg)
+ else:
+ sys.exit("Unrecognized --versions output: %s" % line)
+
+copyright={}
+copyrights=autobuild('install', '--copyrights')
+viewer_copyright = copyrights.readline() # first line is the copyright for the viewer itself
+for line in copyrights:
+ pkg_info = pkg_line.match(line)
+ if pkg_info:
+ pkg = pkg_info.group(1)
+ if pkg not in copyright:
+ copyright[pkg] = pkg_info.group(2).strip()
+ else:
+ sys.exit("Duplicate copyright for %s" % pkg)
+ else:
+ sys.exit("Unrecognized --copyrights output: %s" % line)
+
+print viewer_copyright
+for pkg in sorted(version):
+ print ': '.join([pkg, version[pkg]])
+ if pkg in copyright:
+ print copyright[pkg]
+ else:
+ sys.exit("No copyright for %s" % pkg)
diff --git a/scripts/setup-path.py b/scripts/setup-path.py
index 157bda0027..ce83d815bf 100755
--- a/scripts/setup-path.py
+++ b/scripts/setup-path.py
@@ -1,34 +1,28 @@
-#!/usr/bin/python
+#!/usr/bin/env python
"""\
@file setup-path.py
@brief Get the python library directory in the path, so we don't have
to screw with PYTHONPATH or symbolic links.
-$LicenseInfo:firstyear=2007&license=viewergpl$
+$LicenseInfo:firstyear=2007&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2010, Linden Research, Inc.
-Copyright (c) 2007-2009, Linden Research, Inc.
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation;
+version 2.1 of the License only.
-Second Life Viewer Source Code
-The source code in this file ("Source Code") is provided by Linden Lab
-to you under the terms of the GNU General Public License, version 2.0
-("GPL"), unless you have obtained a separate licensing agreement
-("Other License"), formally executed by you and Linden Lab. Terms of
-the GPL can be found in doc/GPL-license.txt in this distribution, or
-online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
-
-There are special exceptions to the terms and conditions of the GPL as
-it is applied to this Source Code. View the full text of the exception
-in the file doc/FLOSS-exception.txt in this software distribution, or
-online at
-http://secondlifegrid.net/programs/open_source/licensing/flossexception
-
-By copying, modifying or distributing this software, you acknowledge
-that you have read and understood your obligations described above,
-and agree to abide by those obligations.
-
-ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
-WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
-COMPLETENESS OR PERFORMANCE.
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
$/LicenseInfo$
"""
diff --git a/scripts/template_verifier.py b/scripts/template_verifier.py
index adcfcbcae6..b44410cdd8 100755
--- a/scripts/template_verifier.py
+++ b/scripts/template_verifier.py
@@ -1,33 +1,27 @@
-#!/usr/bin/python
+#!/usr/bin/env python
"""\
@file template_verifier.py
@brief Message template compatibility verifier.
-$LicenseInfo:firstyear=2007&license=viewergpl$
+$LicenseInfo:firstyear=2007&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2010, Linden Research, Inc.
-Copyright (c) 2007-2009, Linden Research, Inc.
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation;
+version 2.1 of the License only.
-Second Life Viewer Source Code
-The source code in this file ("Source Code") is provided by Linden Lab
-to you under the terms of the GNU General Public License, version 2.0
-("GPL"), unless you have obtained a separate licensing agreement
-("Other License"), formally executed by you and Linden Lab. Terms of
-the GPL can be found in doc/GPL-license.txt in this distribution, or
-online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
-
-There are special exceptions to the terms and conditions of the GPL as
-it is applied to this Source Code. View the full text of the exception
-in the file doc/FLOSS-exception.txt in this software distribution, or
-online at
-http://secondlifegrid.net/programs/open_source/licensing/flossexception
-
-By copying, modifying or distributing this software, you acknowledge
-that you have read and understood your obligations described above,
-and agree to abide by those obligations.
-
-ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
-WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
-COMPLETENESS OR PERFORMANCE.
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
$/LicenseInfo$
"""
@@ -72,6 +66,7 @@ add_indra_lib_path()
import optparse
import os
import urllib
+import hashlib
from indra.ipc import compatibility
from indra.ipc import tokenstream
@@ -234,11 +229,14 @@ http://wiki.secondlife.com/wiki/Template_verifier.py
""")
parser.add_option(
'-u', '--master_url', type='string', dest='master_url',
- default='http://secondlife.com/app/message_template/master_message_template.msg',
+ default='http://bitbucket.org/lindenlab/master-message-template/raw/tip/message_template.msg',
help="""The url of the master message template.""")
parser.add_option(
'-c', '--cache_master', action='store_true', dest='cache_master',
default=False, help="""Set to true to attempt use local cached copy of the master template.""")
+ parser.add_option(
+ '-f', '--force', action='store_true', dest='force_verification',
+ default=False, help="""Set to true to skip the sha_1 check and force template verification.""")
options, args = parser.parse_args(sysargs)
@@ -275,8 +273,18 @@ http://wiki.secondlife.com/wiki/Template_verifier.py
print "current:", current_filename
current_url = 'file://%s' % current_filename
- # retrieve the contents of the local template and check for syntax
+ # retrieve the contents of the local template
current = fetch(current_url)
+ hexdigest = hashlib.sha1(current).hexdigest()
+ if not options.force_verification:
+ # Early exist if the template hasn't changed.
+ sha_url = "%s.sha1" % current_url
+ current_sha = fetch(sha_url)
+ if hexdigest == current_sha:
+ print "Message template SHA_1 has not changed."
+ sys.exit(0)
+
+ # and check for syntax
current_parsed = llmessage.parseTemplateString(current)
if options.cache_master:
@@ -307,6 +315,12 @@ http://wiki.secondlife.com/wiki/Template_verifier.py
if acceptable:
explain("--- PASS ---", compat)
+ if options.force_verification == False:
+ print "Updating sha1 to %s" % hexdigest
+ sha_filename = "%s.sha1" % current_filename
+ sha_file = open(sha_filename, 'w')
+ sha_file.write(hexdigest)
+ sha_file.close()
else:
explain("*** FAIL ***", compat)
return 1
diff --git a/scripts/templates/template-cpp.cpp b/scripts/templates/template-cpp.cpp
new file mode 100755
index 0000000000..35d8441c87
--- /dev/null
+++ b/scripts/templates/template-cpp.cpp
@@ -0,0 +1,30 @@
+/**
+* @file #filename#.cpp
+* @brief Implementation of #filename#
+* @author #getpass.getuser()#@lindenlab.com
+*
+* $LicenseInfo:firstyear=#datetime.datetime.now().year#&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) #datetime.datetime.now().year#, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+
+#'' if ( skip_h ) else '%cinclude "%s.h"' % (35,filename)#
+
diff --git a/scripts/templates/template-h.h b/scripts/templates/template-h.h
new file mode 100755
index 0000000000..ce7b4ddc87
--- /dev/null
+++ b/scripts/templates/template-h.h
@@ -0,0 +1,31 @@
+/**
+* @file #filename#.h
+* @brief Header file for #filename#
+* @author #getpass.getuser()#@lindenlab.com
+*
+* $LicenseInfo:firstyear=#datetime.datetime.now().year#&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) #datetime.datetime.now().year#, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+#'%c'%35#ifndef LL_#filename.upper().replace('-','_')#_H
+#'%c'%35#define LL_#filename.upper().replace('-','_')#_H
+
+
+#'%c'%35#endif // LL_#filename.upper().replace('-','_')#_H
diff --git a/scripts/update_version_files.py b/scripts/update_version_files.py
deleted file mode 100755
index da60fd105a..0000000000
--- a/scripts/update_version_files.py
+++ /dev/null
@@ -1,331 +0,0 @@
-#!/usr/bin/python
-#
-# Update all of the various files in the repository to a new version number,
-# instead of having to figure it out by hand
-#
-
-import sys
-import os.path
-
-# Look for indra/lib/python in all possible parent directories ...
-# This is an improvement over the setup-path.py method used previously:
-# * the script may blocated anywhere inside the source tree
-# * it doesn't depend on the current directory
-# * it doesn't depend on another file being present.
-
-def add_indra_lib_path():
- root = os.path.realpath(__file__)
- # always insert the directory of the script in the search path
- dir = os.path.dirname(root)
- if dir not in sys.path:
- sys.path.insert(0, dir)
-
- # Now go look for indra/lib/python in the parent dies
- while root != os.path.sep:
- root = os.path.dirname(root)
- dir = os.path.join(root, 'indra', 'lib', 'python')
- if os.path.isdir(dir):
- if dir not in sys.path:
- sys.path.insert(0, dir)
- break
- else:
- print >>sys.stderr, "This script is not inside a valid installation."
- sys.exit(1)
-
-add_indra_lib_path()
-
-import getopt, os, re, commands
-from indra.util import llversion
-
-svn = os.path.expandvars("${SVN}")
-if not svn or svn == "${SVN}": svn = "svn"
-
-def usage():
- print "Usage:"
- print sys.argv[0] + """ [options]
-
-Options:
- --version
- Specify the version string to replace current version.
- --revision
- Specify the revision to replace the last digit of the version.
- By default, revision is computed from the version control system.
- --skip-on-branch
- Specify a regular expression against which the current branch
- is matched. If it matches, then leave version strings alone.
- Use this to avoid changing version strings on release candidate
- builds.
- --server
- Update llversionserver.h only with new version
- --viewer
- Update llversionviewer.h only with new version
- --channel
- Specify the viewer channel string to replace current channel.
- --server_channel
- Specify the server channel string to replace current channel.
- --verbose
- --help
- Print this message and exit.
-
-Common Uses:
- # Update server and viewer build numbers to the current SVN revision:
- update_version_files.py
-
- # Update build numbers unless we are on a release branch:
- update_version_files.py --skip-on-branch='^Branch_'
-
- # Update server and viewer version numbers explicitly:
- update_version_files.py --version=1.18.1.6
-
- # Update just the viewer version number explicitly:
- update_version_files.py --viewer --version=1.18.1.6
-
- # Update just the server build number to the current SVN revision:
- update_version_files.py --server
-
- # Update the viewer channel
- update_version_files.py --channel="First Look Puppeteering"
-
- # Update the server channel
- update_version_files.py --server_channel="Het Grid"
-
-"""
-def _getstatusoutput(cmd):
- """Return Win32 (status, output) of executing cmd
-in a shell."""
- if os.path.sep != "/":
- # stupid #%#$$ windows
- cmd = 'cmd.exe /c "'+cmd+'"'
- pipe = os.popen(cmd, 'r')
- text = pipe.read()
- sts = pipe.close()
- if sts is None: sts = 0
- if text[-1:] == '\n': text = text[:-1]
- return sts, text
-
-re_map = {}
-
-#re_map['filename'] = (('pattern', 'replacement'),
-# ('pattern', 'replacement')
-re_map['indra/llcommon/llversionviewer.h'] = \
- (('const S32 LL_VERSION_MAJOR = (\d+);',
- 'const S32 LL_VERSION_MAJOR = %(VER_MAJOR)s;'),
- ('const S32 LL_VERSION_MINOR = (\d+);',
- 'const S32 LL_VERSION_MINOR = %(VER_MINOR)s;'),
- ('const S32 LL_VERSION_PATCH = (\d+);',
- 'const S32 LL_VERSION_PATCH = %(VER_PATCH)s;'),
- ('const S32 LL_VERSION_BUILD = (\d+);',
- 'const S32 LL_VERSION_BUILD = %(VER_BUILD)s;'),
- ('const char \* const LL_CHANNEL = "(.+)";',
- 'const char * const LL_CHANNEL = "%(VIEWER_CHANNEL)s";'))
-re_map['indra/llcommon/llversionserver.h'] = \
- (('const S32 LL_VERSION_MAJOR = (\d+);',
- 'const S32 LL_VERSION_MAJOR = %(SERVER_VER_MAJOR)s;'),
- ('const S32 LL_VERSION_MINOR = (\d+);',
- 'const S32 LL_VERSION_MINOR = %(SERVER_VER_MINOR)s;'),
- ('const S32 LL_VERSION_PATCH = (\d+);',
- 'const S32 LL_VERSION_PATCH = %(SERVER_VER_PATCH)s;'),
- ('const S32 LL_VERSION_BUILD = (\d+);',
- 'const S32 LL_VERSION_BUILD = %(SERVER_VER_BUILD)s;'),
- ('const char \* const LL_CHANNEL = "(.+)";',
- 'const char * const LL_CHANNEL = "%(SERVER_CHANNEL)s";'))
-re_map['indra/newview/res/viewerRes.rc'] = \
- (('FILEVERSION [0-9,]+',
- 'FILEVERSION %(VER_MAJOR)s,%(VER_MINOR)s,%(VER_PATCH)s,%(VER_BUILD)s'),
- ('PRODUCTVERSION [0-9,]+',
- 'PRODUCTVERSION %(VER_MAJOR)s,%(VER_MINOR)s,%(VER_PATCH)s,%(VER_BUILD)s'),
- ('VALUE "FileVersion", "[0-9.]+"',
- 'VALUE "FileVersion", "%(VER_MAJOR)s.%(VER_MINOR)s.%(VER_PATCH)s.%(VER_BUILD)s"'),
- ('VALUE "ProductVersion", "[0-9.]+"',
- 'VALUE "ProductVersion", "%(VER_MAJOR)s.%(VER_MINOR)s.%(VER_PATCH)s.%(VER_BUILD)s"'))
-
-# Trailing ',' in top level tuple is special form to avoid parsing issues with one element tuple
-re_map['indra/newview/Info-SecondLife.plist'] = \
- (('<key>CFBundleVersion</key>\n\t<string>[0-9.]+</string>',
- '<key>CFBundleVersion</key>\n\t<string>%(VER_MAJOR)s.%(VER_MINOR)s.%(VER_PATCH)s.%(VER_BUILD)s</string>'),)
-
-# This will probably only work as long as InfoPlist.strings is NOT UTF16, which is should be...
-re_map['indra/newview/English.lproj/InfoPlist.strings'] = \
- (('CFBundleShortVersionString = "Second Life version [0-9.]+";',
- 'CFBundleShortVersionString = "Second Life version %(VER_MAJOR)s.%(VER_MINOR)s.%(VER_PATCH)s.%(VER_BUILD)s";'),
- ('CFBundleGetInfoString = "Second Life version [0-9.]+',
- 'CFBundleGetInfoString = "Second Life version %(VER_MAJOR)s.%(VER_MINOR)s.%(VER_PATCH)s.%(VER_BUILD)s'))
-
-
-version_re = re.compile('(\d+).(\d+).(\d+).(\d+)')
-svn_branch_re = re.compile('^URL:\s+\S+/([^/\s]+)$', re.MULTILINE)
-svn_revision_re = re.compile('^Last Changed Rev: (\d+)$', re.MULTILINE)
-
-def main():
- script_path = os.path.dirname(__file__)
- src_root = script_path + "/../"
- verbose = False
-
- opts, args = getopt.getopt(sys.argv[1:],
- "",
- ['version=',
- 'revision=',
- 'channel=',
- 'server_channel=',
- 'skip-on-branch=',
- 'verbose',
- 'server',
- 'viewer',
- 'help'])
- update_server = False
- update_viewer = False
- new_version = None
- new_revision = None
- new_viewer_channel = None
- new_server_channel = None
- skip_on_branch_re = None
- for o,a in opts:
- if o in ('--version'):
- new_version = a
- if o in ('--revision'):
- new_revision = a
- if o in ('--skip-on-branch'):
- skip_on_branch_re = re.compile(a)
- if o in ('--channel'):
- new_viewer_channel = a
- if o in ('--server_channel'):
- new_server_channel = a
- if o in ('--verbose'):
- verbose = True
- if o in ('--server'):
- update_server = True
- if o in ('--viewer'):
- update_viewer = True
- if o in ('--help'):
- usage()
- return 0
-
- if not(update_server or update_viewer):
- update_server = True
- update_viewer = True
-
- # Get current channel/version from llversion*.h
- try:
- viewer_channel = llversion.get_viewer_channel()
- viewer_version = llversion.get_viewer_version()
- except IOError:
- print "Viewer version file not present, skipping..."
- viewer_channel = None
- viewer_version = None
- update_viewer = False
-
- try:
- server_channel = llversion.get_server_channel()
- server_version = llversion.get_server_version()
- except IOError:
- print "Server version file not present, skipping..."
- server_channel = None
- server_version = None
- update_server = False
-
- if verbose:
- print "Source Path:", src_root
- if viewer_channel != None:
- print "Current viewer channel/version: '%(viewer_channel)s' / '%(viewer_version)s'" % locals()
- if server_channel != None:
- print "Current server channel/version: '%(server_channel)s' / '%(server_version)s'" % locals()
- print
-
- # Determine new channel(s)
- if new_viewer_channel != None and len(new_viewer_channel) > 0:
- viewer_channel = new_viewer_channel
- if new_server_channel != None and len(new_server_channel) > 0:
- server_channel = new_server_channel
-
- # Determine new version(s)
- if new_version:
- m = version_re.match(new_version)
- if not m:
- print "Invalid version string specified!"
- return -1
- if update_viewer:
- viewer_version = new_version
- if update_server:
- server_version = new_version
- else:
-
- if llversion.using_svn():
- if new_revision:
- revision = new_revision
- else:
- revision = llversion.get_svn_revision()
- branch = llversion.get_svn_branch()
- elif llversion.using_hg():
- if new_revision:
- revision = new_revision
- else:
- revision = llversion.get_hg_changeset()
- branch = llversion.get_hg_repo()
- elif new_revision:
- revision = new_revision
- branch = "unknown"
- else:
- print >>sys.stderr, "ERROR: could not determine revision and branch"
- return -1
-
- if skip_on_branch_re and skip_on_branch_re.match(branch):
- print "Release Candidate Build, leaving version files untouched."
- return 0
- if update_viewer:
- m = version_re.match(viewer_version)
- viewer_version = m.group(1)+"."+m.group(2)+"."+m.group(3)+"."+revision
- if update_server:
- m = version_re.match(server_version)
- server_version = m.group(1)+"."+m.group(2)+"."+m.group(3)+"."+revision
-
- if verbose:
- if update_viewer:
- print "Setting viewer channel/version: '%(viewer_channel)s' / '%(viewer_version)s'" % locals()
- if update_server:
- print "Setting server channel/version: '%(server_channel)s' / '%(server_version)s'" % locals()
- print
-
- # split out version parts
- if viewer_version != None:
- m = version_re.match(viewer_version)
- VER_MAJOR = m.group(1)
- VER_MINOR = m.group(2)
- VER_PATCH = m.group(3)
- VER_BUILD = m.group(4)
-
- if server_version != None:
- m = version_re.match(server_version)
- SERVER_VER_MAJOR = m.group(1)
- SERVER_VER_MINOR = m.group(2)
- SERVER_VER_PATCH = m.group(3)
- SERVER_VER_BUILD = m.group(4)
-
- # For readability and symmetry with version strings:
- VIEWER_CHANNEL = viewer_channel
- SERVER_CHANNEL = server_channel
-
- # Iterate through all of the files in the map, and apply the
- # substitution filters
- for filename in re_map.keys():
- try:
- # Read the entire file into a string
- full_fn = src_root + '/' + filename
- file = open(full_fn,"r")
- file_str = file.read()
- file.close()
-
- if verbose:
- print "Processing file:",filename
- for rule in re_map[filename]:
- repl = rule[1] % locals()
- file_str = re.sub(rule[0], repl, file_str)
-
- file = open(full_fn,"w")
- file.write(file_str)
- file.close()
- except IOError:
- print "File %(filename)s not present, skipping..." % locals()
- return 0
-
-main()
-