Tools: [Win] Extend auto-version.pl to support 5-tuple versions
authorbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 21 Jul 2014 23:10:44 +0000 (23:10 +0000)
committerbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 21 Jul 2014 23:10:44 +0000 (23:10 +0000)
https://bugs.webkit.org/show_bug.cgi?id=135124
<rdar://problem/17750334>

Reviewed by David Kilzer.

Add test cases for auto-version.pl.

* Scripts/webkitperl/auto-version_unittest: Added.
* Scripts/webkitperl/auto-version_unittest/autoVersionTests.pl: Added.

WebKitLibraries: [Win] Extend auto-version.pl to handle 5-tuple versions
https://bugs.webkit.org/show_bug.cgi?id=135124
<rdar://problem/17750334>

Reviewed by David Kilzer.

Extend tuple parsing to handle up to five tuples, and as
few as a single tuple. On Windows, the two additional
tuples are unused.

Also corrected regular expression capture logic to use local
blocks, preventing later capture expressions from reusing
previous capture results when the current expression failed
to find a match (GRRR, Perl!).

Clean up code by putting logic into a couple of subroutines.

* win/tools/scripts/auto-version.pl:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@171319 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Tools/ChangeLog
Tools/Scripts/webkitperl/auto-version_unittest/autoVersionTests.pl [new file with mode: 0644]
WebKitLibraries/ChangeLog
WebKitLibraries/win/tools/scripts/auto-version.pl

index f6e07ff..4109d3a 100644 (file)
@@ -1,3 +1,16 @@
+2014-07-21  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Extend auto-version.pl to support 5-tuple versions
+        https://bugs.webkit.org/show_bug.cgi?id=135124
+        <rdar://problem/17750334>
+
+        Reviewed by David Kilzer.
+
+        Add test cases for auto-version.pl.
+
+        * Scripts/webkitperl/auto-version_unittest: Added.
+        * Scripts/webkitperl/auto-version_unittest/autoVersionTests.pl: Added.
+
 2014-07-21  Dean Jackson  <dino@apple.com>
 
         Allow MiniBrowser WK1 to do element fullscreen
diff --git a/Tools/Scripts/webkitperl/auto-version_unittest/autoVersionTests.pl b/Tools/Scripts/webkitperl/auto-version_unittest/autoVersionTests.pl
new file mode 100644 (file)
index 0000000..0fd09e4
--- /dev/null
@@ -0,0 +1,404 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2014 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+use strict;
+use warnings;
+
+use File::Spec;
+use File::Temp qw/ tempdir /;
+
+use Test::More;
+
+my @testCases = 
+(
+    {
+        'RC_ProjectSourceVersion' => '5300.4.3.2.1',
+        expectedResults => {
+            '__VERSION_TEXT__' => '300.4.3',
+            '__BUILD_NUMBER__' => '300.4.3',
+            '__BUILD_NUMBER_SHORT__' => '300.4.3',
+            '__VERSION_MAJOR__' => '3',
+            '__VERSION_MINOR__' => '00',
+            '__VERSION_TINY__' => '4',
+            '__VERSION_BUILD__' => '3',
+            '__BUILD_NUMBER_MAJOR__' => '300',
+            '__BUILD_NUMBER_MINOR__' => '4',
+            '__BUILD_NUMBER_VARIANT__' => '3',
+        },
+    },
+
+    {
+        'RC_ProjectSourceVersion' => '530.4.3.2.1',
+        expectedResults => {
+            '__VERSION_TEXT__' => '530.4.3',
+            '__BUILD_NUMBER__' => '530.4.3',
+            '__BUILD_NUMBER_SHORT__' => '530.4.3',
+            '__VERSION_MAJOR__' => '5',
+            '__VERSION_MINOR__' => '30',
+            '__VERSION_TINY__' => '4',
+            '__VERSION_BUILD__' => '3',
+            '__BUILD_NUMBER_MAJOR__' => '530',
+            '__BUILD_NUMBER_MINOR__' => '4',
+            '__BUILD_NUMBER_VARIANT__' => '3',
+        },
+    },
+
+    {
+        'RC_ProjectSourceVersion' => '53.4.3.2.1',
+        expectedResults => {
+            '__VERSION_TEXT__' => '53.4.3',
+            '__BUILD_NUMBER__' => '53.4.3',
+            '__BUILD_NUMBER_SHORT__' => '53.4.3',
+            '__VERSION_MAJOR__' => '5',
+            '__VERSION_MINOR__' => '3',
+            '__VERSION_TINY__' => '4',
+            '__VERSION_BUILD__' => '3',
+            '__BUILD_NUMBER_MAJOR__' => '53',
+            '__BUILD_NUMBER_MINOR__' => '4',
+            '__BUILD_NUMBER_VARIANT__' => '3',
+        },
+    },
+
+    {
+        'RC_ProjectSourceVersion' => '5.4.3.2.1',
+        expectedResults => {
+            '__VERSION_TEXT__' => '5.4.3',
+            '__BUILD_NUMBER__' => '5.4.3',
+            '__BUILD_NUMBER_SHORT__' => '5.4.3',
+            '__VERSION_MAJOR__' => '5',
+            '__VERSION_MINOR__' => '',
+            '__VERSION_TINY__' => '4',
+            '__VERSION_BUILD__' => '3',
+            '__BUILD_NUMBER_MAJOR__' => '5',
+            '__BUILD_NUMBER_MINOR__' => '4',
+            '__BUILD_NUMBER_VARIANT__' => '3',
+        },
+    },
+
+    {
+        'RC_ProjectSourceVersion' => '5300.4.3.2',
+        expectedResults => {
+            '__VERSION_TEXT__' => '300.4.3',
+            '__BUILD_NUMBER__' => '300.4.3',
+            '__BUILD_NUMBER_SHORT__' => '300.4.3',
+            '__VERSION_MAJOR__' => '3',
+            '__VERSION_MINOR__' => '00',
+            '__VERSION_TINY__' => '4',
+            '__VERSION_BUILD__' => '3',
+            '__BUILD_NUMBER_MAJOR__' => '300',
+            '__BUILD_NUMBER_MINOR__' => '4',
+            '__BUILD_NUMBER_VARIANT__' => '3',
+        },
+    },
+
+    {
+        'RC_ProjectSourceVersion' => '530.4.3.2',
+        expectedResults => {
+            '__VERSION_TEXT__' => '530.4.3',
+            '__BUILD_NUMBER__' => '530.4.3',
+            '__BUILD_NUMBER_SHORT__' => '530.4.3',
+            '__VERSION_MAJOR__' => '5',
+            '__VERSION_MINOR__' => '30',
+            '__VERSION_TINY__' => '4',
+            '__VERSION_BUILD__' => '3',
+            '__BUILD_NUMBER_MAJOR__' => '530',
+            '__BUILD_NUMBER_MINOR__' => '4',
+            '__BUILD_NUMBER_VARIANT__' => '3',
+        },
+    },
+
+    {
+        'RC_ProjectSourceVersion' => '53.4.3.2',
+        expectedResults => {
+            '__VERSION_TEXT__' => '53.4.3',
+            '__BUILD_NUMBER__' => '53.4.3',
+            '__BUILD_NUMBER_SHORT__' => '53.4.3',
+            '__VERSION_MAJOR__' => '5',
+            '__VERSION_MINOR__' => '3',
+            '__VERSION_TINY__' => '4',
+            '__VERSION_BUILD__' => '3',
+            '__BUILD_NUMBER_MAJOR__' => '53',
+            '__BUILD_NUMBER_MINOR__' => '4',
+            '__BUILD_NUMBER_VARIANT__' => '3',
+        },
+    },
+
+    {
+        'RC_ProjectSourceVersion' => '5.4.3.2',
+        expectedResults => {
+            '__VERSION_TEXT__' => '5.4.3',
+            '__BUILD_NUMBER__' => '5.4.3',
+            '__BUILD_NUMBER_SHORT__' => '5.4.3',
+            '__VERSION_MAJOR__' => '5',
+            '__VERSION_MINOR__' => '',
+            '__VERSION_TINY__' => '4',
+            '__VERSION_BUILD__' => '3',
+            '__BUILD_NUMBER_MAJOR__' => '5',
+            '__BUILD_NUMBER_MINOR__' => '4',
+            '__BUILD_NUMBER_VARIANT__' => '3',
+        },
+    },
+
+    {
+        'RC_ProjectSourceVersion' => '5300.4.3',
+        expectedResults => {
+            '__VERSION_TEXT__' => '300.4.3',
+            '__BUILD_NUMBER__' => '300.4.3',
+            '__BUILD_NUMBER_SHORT__' => '300.4.3',
+            '__VERSION_MAJOR__' => '3',
+            '__VERSION_MINOR__' => '00',
+            '__VERSION_TINY__' => '4',
+            '__VERSION_BUILD__' => '3',
+            '__BUILD_NUMBER_MAJOR__' => '300',
+            '__BUILD_NUMBER_MINOR__' => '4',
+            '__BUILD_NUMBER_VARIANT__' => '3',
+        },
+    },
+
+    {
+        'RC_ProjectSourceVersion' => '530.4.3',
+        expectedResults => {
+            '__VERSION_TEXT__' => '530.4.3',
+            '__BUILD_NUMBER__' => '530.4.3',
+            '__BUILD_NUMBER_SHORT__' => '530.4.3',
+            '__VERSION_MAJOR__' => '5',
+            '__VERSION_MINOR__' => '30',
+            '__VERSION_TINY__' => '4',
+            '__VERSION_BUILD__' => '3',
+            '__BUILD_NUMBER_MAJOR__' => '530',
+            '__BUILD_NUMBER_MINOR__' => '4',
+            '__BUILD_NUMBER_VARIANT__' => '3',
+        },
+    },
+
+    {
+        'RC_ProjectSourceVersion' => '53.4.3',
+        expectedResults => {
+            '__VERSION_TEXT__' => '53.4.3',
+            '__BUILD_NUMBER__' => '53.4.3',
+            '__BUILD_NUMBER_SHORT__' => '53.4.3',
+            '__VERSION_MAJOR__' => '5',
+            '__VERSION_MINOR__' => '3',
+            '__VERSION_TINY__' => '4',
+            '__VERSION_BUILD__' => '3',
+            '__BUILD_NUMBER_MAJOR__' => '53',
+            '__BUILD_NUMBER_MINOR__' => '4',
+            '__BUILD_NUMBER_VARIANT__' => '3',
+        },
+    },
+
+    {
+        'RC_ProjectSourceVersion' => '5.4.3',
+        expectedResults => {
+            '__VERSION_TEXT__' => '5.4.3',
+            '__BUILD_NUMBER__' => '5.4.3',
+            '__BUILD_NUMBER_SHORT__' => '5.4.3',
+            '__VERSION_MAJOR__' => '5',
+            '__VERSION_MINOR__' => '',
+            '__VERSION_TINY__' => '4',
+            '__VERSION_BUILD__' => '3',
+            '__BUILD_NUMBER_MAJOR__' => '5',
+            '__BUILD_NUMBER_MINOR__' => '4',
+            '__BUILD_NUMBER_VARIANT__' => '3',
+        },
+    },
+
+    {
+        'RC_ProjectSourceVersion' => '5300.4',
+        expectedResults => {
+            '__VERSION_TEXT__' => '300.4.0',
+            '__BUILD_NUMBER__' => '300.4.0',
+            '__BUILD_NUMBER_SHORT__' => '300.4.0',
+            '__VERSION_MAJOR__' => '3',
+            '__VERSION_MINOR__' => '00',
+            '__VERSION_TINY__' => '4',
+            '__VERSION_BUILD__' => '0',
+            '__BUILD_NUMBER_MAJOR__' => '300',
+            '__BUILD_NUMBER_MINOR__' => '4',
+            '__BUILD_NUMBER_VARIANT__' => '0',
+        },
+    },
+
+    {
+        'RC_ProjectSourceVersion' => '530.4',
+        expectedResults => {
+            '__VERSION_TEXT__' => '530.4.0',
+            '__BUILD_NUMBER__' => '530.4.0',
+            '__BUILD_NUMBER_SHORT__' => '530.4.0',
+            '__VERSION_MAJOR__' => '5',
+            '__VERSION_MINOR__' => '30',
+            '__VERSION_TINY__' => '4',
+            '__VERSION_BUILD__' => '0',
+            '__BUILD_NUMBER_MAJOR__' => '530',
+            '__BUILD_NUMBER_MINOR__' => '4',
+            '__BUILD_NUMBER_VARIANT__' => '0',
+        },
+    },
+
+    {
+        'RC_ProjectSourceVersion' => '53.4',
+        expectedResults => {
+            '__VERSION_TEXT__' => '53.4.0',
+            '__BUILD_NUMBER__' => '53.4.0',
+            '__BUILD_NUMBER_SHORT__' => '53.4.0',
+            '__VERSION_MAJOR__' => '5',
+            '__VERSION_MINOR__' => '3',
+            '__VERSION_TINY__' => '4',
+            '__VERSION_BUILD__' => '0',
+            '__BUILD_NUMBER_MAJOR__' => '53',
+            '__BUILD_NUMBER_MINOR__' => '4',
+            '__BUILD_NUMBER_VARIANT__' => '0',
+        },
+    },
+
+    {
+        'RC_ProjectSourceVersion' => '5.4',
+        expectedResults => {
+            '__VERSION_TEXT__' => '5.4.0',
+            '__BUILD_NUMBER__' => '5.4.0',
+            '__BUILD_NUMBER_SHORT__' => '5.4.0',
+            '__VERSION_MAJOR__' => '5',
+            '__VERSION_MINOR__' => '',
+            '__VERSION_TINY__' => '4',
+            '__VERSION_BUILD__' => '0',
+            '__BUILD_NUMBER_MAJOR__' => '5',
+            '__BUILD_NUMBER_MINOR__' => '4',
+            '__BUILD_NUMBER_VARIANT__' => '0',
+        },
+    },
+
+    {
+        'RC_ProjectSourceVersion' => '5300',
+        expectedResults => {
+            '__VERSION_TEXT__' => '300.0.0',
+            '__BUILD_NUMBER__' => '300.0.0',
+            '__BUILD_NUMBER_SHORT__' => '300.0.0',
+            '__VERSION_MAJOR__' => '3',
+            '__VERSION_MINOR__' => '00',
+            '__VERSION_TINY__' => '0',
+            '__VERSION_BUILD__' => '0',
+            '__BUILD_NUMBER_MAJOR__' => '300',
+            '__BUILD_NUMBER_MINOR__' => '0',
+            '__BUILD_NUMBER_VARIANT__' => '0',
+        },
+    },
+
+    {
+        'RC_ProjectSourceVersion' => '530',
+        expectedResults => {
+            '__VERSION_TEXT__' => '530.0.0',
+            '__BUILD_NUMBER__' => '530.0.0',
+            '__BUILD_NUMBER_SHORT__' => '530.0.0',
+            '__VERSION_MAJOR__' => '5',
+            '__VERSION_MINOR__' => '30',
+            '__VERSION_TINY__' => '0',
+            '__VERSION_BUILD__' => '0',
+            '__BUILD_NUMBER_MAJOR__' => '530',
+            '__BUILD_NUMBER_MINOR__' => '0',
+            '__BUILD_NUMBER_VARIANT__' => '0',
+        },
+    },
+
+    # Smallest "Valid" case
+    {
+        'RC_ProjectSourceVersion' => '53',
+        expectedResults => {
+            '__VERSION_TEXT__' => '53.0.0',
+            '__BUILD_NUMBER__' => '53.0.0',
+            '__BUILD_NUMBER_SHORT__' => '53.0.0',
+            '__VERSION_MAJOR__' => '5',
+            '__VERSION_MINOR__' => '3',
+            '__VERSION_TINY__' => '0',
+            '__VERSION_BUILD__' => '0',
+            '__BUILD_NUMBER_MAJOR__' => '53',
+            '__BUILD_NUMBER_MINOR__' => '0',
+            '__BUILD_NUMBER_VARIANT__' => '0',
+        },
+    },
+
+    # We don't support 1-digit versions, but we should run without crashing
+    {
+        'RC_ProjectSourceVersion' => '5',
+        expectedResults => {
+            '__VERSION_TEXT__' => '5.0.0',
+            '__BUILD_NUMBER__' => '5.0.0',
+            '__BUILD_NUMBER_SHORT__' => '5.0.0',
+            '__VERSION_MAJOR__' => '5',
+            '__VERSION_MINOR__' => '',
+            '__VERSION_TINY__' => '0',
+            '__VERSION_BUILD__' => '0',
+            '__BUILD_NUMBER_MAJOR__' => '5',
+            '__BUILD_NUMBER_MINOR__' => '0',
+            '__BUILD_NUMBER_VARIANT__' => '0',
+        },
+    },
+
+    # Largest specified version test
+    {
+        'RC_ProjectSourceVersion' => '214747.99.99.99.99',
+        expectedResults => {
+            '__VERSION_TEXT__' => '747.99.99',
+            '__BUILD_NUMBER__' => '747.99.99',
+            '__BUILD_NUMBER_SHORT__' => '747.99.99',
+            '__VERSION_MAJOR__' => '7',
+            '__VERSION_MINOR__' => '47',
+            '__VERSION_TINY__' => '99',
+            '__VERSION_BUILD__' => '99',
+            '__BUILD_NUMBER_MAJOR__' => '747',
+            '__BUILD_NUMBER_MINOR__' => '99',
+            '__BUILD_NUMBER_VARIANT__' => '99',
+        },
+    },
+);
+
+my $testCasesCount = scalar(@testCases) * 10; # 10 expected results
+plan(tests => $testCasesCount);
+
+foreach my $testCase (@testCases) {
+    my $toolsPath = $ENV{'WEBKIT_LIBRARIES'};
+    my $autoVersionScript = File::Spec->catfile($toolsPath, 'tools', 'scripts', 'auto-version.pl');
+    my $testOutputDir = tempdir(CLEANUP => 1);
+    `RC_ProjectSourceVersion=$testCase->{'RC_ProjectSourceVersion'} perl $autoVersionScript $testOutputDir`;
+
+    my $expectedResults = $testCase->{expectedResults};
+
+    my $outputFile = File::Spec->catfile($testOutputDir, 'include', 'autoversion.h');
+    open(TEST_OUTPUT, '<', $outputFile) or die "Unable to open $outputFile";
+
+    while (my $line = <TEST_OUTPUT>) {
+        foreach my $expectedResultKey (keys $expectedResults) {
+            if ($line !~ m/$expectedResultKey/) {
+                next;
+            }
+
+            $line =~ s/#define $expectedResultKey//;
+            $line =~ s/^\s*(.*)\s*$/$1/;
+            $line =~ s/^"(.*)"$/$1/;
+            chomp($line);
+
+            my $expectedResultValue = $expectedResults->{$expectedResultKey};
+            is($line, $expectedResultValue, "$testCase->{'RC_ProjectSourceVersion'}: $expectedResultKey");
+        }
+    }
+}
index 9fbd2bb..1dce3b7 100644 (file)
@@ -1,5 +1,26 @@
 2014-07-21  Brent Fulgham  <bfulgham@apple.com>
 
+        [Win] Extend auto-version.pl to handle 5-tuple versions
+        https://bugs.webkit.org/show_bug.cgi?id=135124
+        <rdar://problem/17750334>
+
+        Reviewed by David Kilzer.
+
+        Extend tuple parsing to handle up to five tuples, and as
+        few as a single tuple. On Windows, the two additional
+        tuples are unused.
+
+        Also corrected regular expression capture logic to use local
+        blocks, preventing later capture expressions from reusing
+        previous capture results when the current expression failed
+        to find a match (GRRR, Perl!).
+
+        Clean up code by putting logic into a couple of subroutines.
+
+        * win/tools/scripts/auto-version.pl:
+
+2014-07-21  Brent Fulgham  <bfulgham@apple.com>
+
         [Win] Correct auto-version.pl script for two-digit version numbers
         https://bugs.webkit.org/show_bug.cgi?id=135119
         <rdar://problem/17743959>
index f5e7876..800cb04 100755 (executable)
@@ -28,6 +28,9 @@ use Win32;
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 
+sub splitVersion($);
+sub splitBuildMajorVersion($);
+
 die "You must supply an output path as the argument.\n" if ($#ARGV < 0);
 
 my $WEBKIT_LIBRARIES = $ENV{'WEBKIT_LIBRARIES'};
@@ -68,47 +71,13 @@ if (!defined $ENVIRONMENT_VERSION) {
 my $PROPOSED_VERSION = (defined $ENVIRONMENT_VERSION) ? $ENVIRONMENT_VERSION : $FALLBACK_VERSION;
 chomp($PROPOSED_VERSION);
 
-# Split out the three components of the dotted version number.  We pad
-# the input with trailing dots to handle the case where the input version
-# has fewer components than we expect.
-$PROPOSED_VERSION =~ m/^(?:(\d+)\.)?(?:(\d+)\.)?(\*|\d+)$/ or die "Couldn't parse $PROPOSED_VERSION";
-my $BUILD_MAJOR_VERSION = $1;
-my $BUILD_MINOR_VERSION = $2;
-my $BUILD_TINY_VERSION = $3;
-
-# The default version (with no decimals) will be matched by the regexp
-# to $BUILD_TINY_VERSION. If that happens, we need to move it to
-# $BUILD_MAJOR_VERSION.
-if (!defined $BUILD_MAJOR_VERSION && !defined $BUILD_MINOR_VERSION) {
-    $BUILD_MAJOR_VERSION = $BUILD_TINY_VERSION;
-    $BUILD_TINY_VERSION = 0;
-}
-
-# Cut the major component down to three characters by dropping any
-# extra leading digits, then adjust the major version portion of the
-# version string to match.
-$BUILD_MAJOR_VERSION =~ s/^.*(\d\d\d)$/$1/;
-
-# Have the minor and tiny components default to zero if not present.
-if (!defined $BUILD_MINOR_VERSION) {
-    $BUILD_MINOR_VERSION = 0;
-}
-if (!defined $BUILD_TINY_VERSION) {
-    $BUILD_TINY_VERSION = 0;
-}
+my ($BUILD_MAJOR_VERSION, $BUILD_MINOR_VERSION, $BUILD_TINY_VERSION) = splitVersion($PROPOSED_VERSION);
 
 $PROPOSED_VERSION = "$BUILD_MAJOR_VERSION.$BUILD_MINOR_VERSION.$BUILD_TINY_VERSION";
 
-# Split the first component further by using the first digit for the
-# major version and the remaining two characters as the minor version.
-# The minor version is shifted down to the tiny version, with the tiny
-# version becoming the variant version.
-$BUILD_MAJOR_VERSION =~ m/^[^\d]*(\d)(\d{1,})/;
-my $MAJOR_VERSION = $1;
-my $MINOR_VERSION = $2;
+my ($MAJOR_VERSION, $MINOR_VERSION) = splitBuildMajorVersion($BUILD_MAJOR_VERSION);
 my $TINY_VERSION = $BUILD_MINOR_VERSION;
 my $VARIANT_VERSION = $BUILD_TINY_VERSION;
-
 my $VERSION_TEXT = $PROPOSED_VERSION;
 my $VERSION_TEXT_SHORT = $VERSION_TEXT;
 
@@ -149,3 +118,54 @@ if (defined $COPYRIGHT_END_YEAR) {
     print OUTPUT_FILE "#define __COPYRIGHT_YEAR_END_TEXT__ \"$COPYRIGHT_END_YEAR\"\n";
 }
 close(OUTPUT_FILE);
+
+
+sub splitVersion($)
+{
+    my $PROPOSED_VERSION = shift;
+
+    # Split out the three components of the dotted version number.  We pad
+    # the input with trailing dots to handle the case where the input version
+    # has fewer components than we expect.
+    my @components = split(/\./, $PROPOSED_VERSION) or die "Couldn't parse $PROPOSED_VERSION";
+    my $componentCount = scalar(@components);
+
+    my $BUILD_MAJOR_VERSION = $components[0];
+
+    # Have the minor and tiny components default to zero if not present.
+    my $BUILD_MINOR_VERSION = 0;
+    my $BUILD_TINY_VERSION = 0;
+    if ($componentCount > 1) {
+        $BUILD_MINOR_VERSION = $components[1];
+        if ($componentCount > 2) {
+            $BUILD_TINY_VERSION = $components[2];
+        }
+    }
+
+    # Cut the major component down to three characters by dropping any
+    # extra leading digits, then adjust the major version portion of the
+    # version string to match.
+    $BUILD_MAJOR_VERSION =~ s/^.*(\d\d\d)$/$1/;
+
+    return ($BUILD_MAJOR_VERSION, $BUILD_MINOR_VERSION, $BUILD_TINY_VERSION);
+}
+
+sub splitBuildMajorVersion($)
+{
+    # Split the first component further by using the first digit for the
+    # major version and the remaining two characters as the minor version.
+    # The minor version is shifted down to the tiny version, with the tiny
+    # version becoming the variant version.
+    my ($MAJOR_VERSION, $MINOR_VERSION);
+    {
+        if ($BUILD_MAJOR_VERSION =~ m/^[^\d]*(\d)(\d{1,})/) {
+            $MAJOR_VERSION = $1;
+            $MINOR_VERSION = $2;
+        } else {
+            $MAJOR_VERSION = $BUILD_MAJOR_VERSION;
+            $MINOR_VERSION = '';
+        }
+    }
+
+    return ($MAJOR_VERSION, $MINOR_VERSION);
+}