Committed to semantic versioning

as prompted by #365, #430, #447 and a thread on the google group.
- split version bumping out of generateSingleHeader script
- separate scripts for bumping each version component
- "build" number only incremented for "develop" builds
diff --git a/README.md b/README.md
index 6cbcb90..98c7116 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 ![catch logo](catch-logo-small.png)
 
-*v1.1 build 3 (master branch)*
+*v1.2.0*
 
 Build status (on Travis CI) [![Build Status](https://travis-ci.org/philsquared/Catch.png)](https://travis-ci.org/philsquared/Catch)
 
diff --git a/docs/contributing.md b/docs/contributing.md
index 5e22836..49a663c 100644
--- a/docs/contributing.md
+++ b/docs/contributing.md
@@ -6,7 +6,7 @@
 
 ## Branches
 
-Ongoing development is on the "develop" branch, or on feature branches that are branched off of develop. Please target any pull requests at develop, or, for larger chunks of work, a branch off of develop.
+Ongoing development is on the "develop" branch (if there is one, currently), or on feature branches that are branched off of develop. Please target any pull requests at develop, or, for larger chunks of work, a branch off of develop.
 
 ## Directory structure
 
diff --git a/include/catch_runner.hpp b/include/catch_runner.hpp
index bf03ccd..8023d97 100644
--- a/include/catch_runner.hpp
+++ b/include/catch_runner.hpp
@@ -126,12 +126,7 @@
         }
 
         void showHelp( std::string const& processName ) {
-            Catch::cout() << "\nCatch v"    << libraryVersion.majorVersion << "."
-                                        << libraryVersion.minorVersion << " build "
-                                        << libraryVersion.buildNumber;
-            if( libraryVersion.branchName != std::string( "master" ) )
-                Catch::cout() << " (" << libraryVersion.branchName << " branch)";
-            Catch::cout() << "\n";
+            Catch::cout() << "\nCatch v" << libraryVersion << "\n";
 
             m_cli.usage( Catch::cout(), processName );
             Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
@@ -148,9 +143,10 @@
             catch( std::exception& ex ) {
                 {
                     Colour colourGuard( Colour::Red );
-                    Catch::cerr()   << "\nError(s) in input:\n"
-                                << Text( ex.what(), TextAttributes().setIndent(2) )
-                                << "\n\n";
+                    Catch::cerr()
+                        << "\nError(s) in input:\n"
+                        << Text( ex.what(), TextAttributes().setIndent(2) )
+                        << "\n\n";
                 }
                 m_cli.usage( Catch::cout(), m_configData.processName );
                 return (std::numeric_limits<int>::max)();
diff --git a/include/internal/catch_version.h b/include/internal/catch_version.h
index ca2feef..b6a9707 100644
--- a/include/internal/catch_version.h
+++ b/include/internal/catch_version.h
@@ -14,19 +14,20 @@
     struct Version {
         Version(    unsigned int _majorVersion,
                     unsigned int _minorVersion,
-                    unsigned int _buildNumber,
-                    char const* const _branchName )
-        :   majorVersion( _majorVersion ),
-            minorVersion( _minorVersion ),
-            buildNumber( _buildNumber ),
-            branchName( _branchName )
-        {}
+                    unsigned int _patchNumber,
+                    std::string const& _branchName,
+                    unsigned int _buildNumber );
 
         unsigned int const majorVersion;
         unsigned int const minorVersion;
-        unsigned int const buildNumber;
-        char const* const branchName;
+        unsigned int const patchNumber;
 
+        // buildNumber is only used if branchName is not null
+        std::string const branchName;
+        unsigned int const buildNumber;
+
+        friend std::ostream& operator << ( std::ostream& os, Version const& version );
+        
     private:
         void operator=( Version const& );
     };
diff --git a/include/internal/catch_version.hpp b/include/internal/catch_version.hpp
index 4a83053..90f4a15 100644
--- a/include/internal/catch_version.hpp
+++ b/include/internal/catch_version.hpp
@@ -12,8 +12,33 @@
 
 namespace Catch {
 
-    // These numbers are maintained by a script
-    Version libraryVersion( 1, 1, 3, "master" );
+    Version::Version
+        (   unsigned int _majorVersion,
+            unsigned int _minorVersion,
+            unsigned int _patchNumber,
+            std::string const& _branchName,
+            unsigned int _buildNumber )
+    :   majorVersion( _majorVersion ),
+        minorVersion( _minorVersion ),
+        patchNumber( _patchNumber ),
+        branchName( _branchName ),
+        buildNumber( _buildNumber )
+    {}
+
+    std::ostream& operator << ( std::ostream& os, Version const& version ) {
+        os  << version.majorVersion << "."
+            << version.minorVersion << "."
+            << version.patchNumber;
+
+        if( !version.branchName.empty() ) {
+            os  << "-" << version.branchName
+                << "." << version.buildNumber;
+        }
+        return os;
+    }
+
+    Version libraryVersion( 1, 2, 0, "", 0 );
+
 }
 
 #endif // TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED
diff --git a/include/reporters/catch_reporter_console.hpp b/include/reporters/catch_reporter_console.hpp
index 16896f4..150cf52 100644
--- a/include/reporters/catch_reporter_console.hpp
+++ b/include/reporters/catch_reporter_console.hpp
@@ -261,12 +261,7 @@
             stream  << "\n" << getLineOfChars<'~'>() << "\n";
             Colour colour( Colour::SecondaryText );
             stream  << currentTestRunInfo->name
-                    << " is a Catch v"  << libraryVersion.majorVersion << "."
-                    << libraryVersion.minorVersion << " b"
-                    << libraryVersion.buildNumber;
-            if( libraryVersion.branchName != std::string( "master" ) )
-                stream << " (" << libraryVersion.branchName << ")";
-            stream  << " host application.\n"
+                    << " is a Catch v"  << libraryVersion << " host application.\n"
                     << "Run with -? for options\n\n";
 
             if( m_config->rngSeed() != 0 )
diff --git a/scripts/developBuild.py b/scripts/developBuild.py
new file mode 100644
index 0000000..c244871
--- /dev/null
+++ b/scripts/developBuild.py
@@ -0,0 +1,9 @@
+from  __future__ import  print_function
+from releaseCommon import Version
+
+v = Version()
+v.incrementBuildNumber()
+v.updateVersionFile()
+v.updateReadmeFile()
+
+print( "Updated Version.hpp and README to v{0}".format( v.getVersionString() ) )
\ No newline at end of file
diff --git a/scripts/generateSingleHeader.py b/scripts/generateSingleHeader.py
index cd97010..419633f 100644
--- a/scripts/generateSingleHeader.py
+++ b/scripts/generateSingleHeader.py
@@ -7,8 +7,9 @@
 import string
 
 from scriptCommon import catchPath
+from releaseCommon import Version
 
-versionParser = re.compile( r'(\s*Version\slibraryVersion)\s*\(\s*(.*)\s*,\s*(.*)\s*,\s*(.*)\s*,\s*\"(.*)\"\s*\).*' )
+
 includesParser = re.compile( r'\s*#include\s*"(.*)"' )
 guardParser = re.compile( r'\s*#.*TWOBLUECUBES_CATCH_.*_INCLUDED')
 defineParser = re.compile( r'\s*#define')
@@ -20,22 +21,15 @@
 blankParser = re.compile( r'^\s*$')
 seenHeaders = set([])
 rootPath = os.path.join( catchPath, 'include/' )
-versionPath = os.path.join( rootPath, "internal/catch_version.hpp" )
-readmePath = os.path.join( catchPath, "README.md" )
 outputPath = os.path.join( catchPath, 'single_include/catch.hpp' )
 
-bumpVersion = True
 includeImpl = True
 
 for arg in sys.argv[1:]:
     arg = string.lower(arg)
-    if arg == "nobump":
-        bumpVersion = False
-        print( "Not bumping version number" )
-    elif arg == "noimpl":
+    if arg == "noimpl":
         includeImpl = False
-        bumpVersion = False
-        print( "Not including impl code (and not bumping version)" )
+        print( "Not including impl code" )
     else:
         print( "\n** Unrecognised argument: " + arg + " **\n" )
         exit(1)
@@ -87,70 +81,23 @@
                 if blanks < 2:
                     write( line.rstrip() + "\n" )
 
-class Version:
-    def __init__(self):
-        f = open( versionPath, 'r' )
-        for line in f:
-            m = versionParser.match( line )
-            if m:
-                self.variableDecl = m.group(1)
-                self.majorVersion = int(m.group(2))
-                self.minorVersion = int(m.group(3))
-                self.buildNumber = int(m.group(4))
-                self.branchName = m.group(5)
-        f.close()
 
-    def incrementBuildNumber(self):
-        self.buildNumber = self.buildNumber+1
+v = Version()
+out.write( "/*\n" )
+out.write( " *  Catch v{0}\n".format( v.getVersionString() ) )
+out.write( " *  Generated: {0}\n".format( datetime.datetime.now() ) )
+out.write( " *  ----------------------------------------------------------\n" )
+out.write( " *  This file has been merged from multiple headers. Please don't edit it directly\n" )
+out.write( " *  Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.\n" )
+out.write( " *\n" )
+out.write( " *  Distributed under the Boost Software License, Version 1.0. (See accompanying\n" )
+out.write( " *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n" )
+out.write( " */\n" )
+out.write( "#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n" )
+out.write( "#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n" )
 
-    def updateVersionFile(self):
-        f = open( versionPath, 'r' )
-        lines = []
-        for line in f:
-            m = versionParser.match( line )
-            if m:
-                lines.append( '{0}( {1}, {2}, {3}, "{4}" );'.format( self.variableDecl, self.majorVersion, self.minorVersion, self.buildNumber, self.branchName ) )
-            else:
-                lines.append( line.rstrip() )
-        f.close()
-        f = open( versionPath, 'w' )
-        for line in lines:
-            f.write( line + "\n" )
+parseFile( rootPath, 'catch.hpp' )
 
-    def updateReadmeFile(self):
-        f = open( readmePath, 'r' )
-        lines = []
-        for line in f:
-            lines.append( line.rstrip() )
-        f.close()
-        f = open( readmePath, 'w' )
-        for line in lines:
-            if line.startswith( "*v" ):
-                f.write( '*v{0}.{1} build {2} ({3} branch)*\n'.format( self.majorVersion, self.minorVersion, self.buildNumber, self.branchName ) )
-            else:
-                f.write( line + "\n" )
+out.write( "#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n\n" )
 
-def generateSingleInclude():
-    v = Version()
-    if bumpVersion:
-        v.incrementBuildNumber()
-        v.updateVersionFile()
-        v.updateReadmeFile()
-    out.write( "/*\n" )
-    out.write( " *  CATCH v{0}.{1} build {2} ({3} branch)\n".format( v.majorVersion, v.minorVersion, v.buildNumber, v.branchName ) )
-    out.write( " *  Generated: {0}\n".format( datetime.datetime.now() ) )
-    out.write( " *  ----------------------------------------------------------\n" )
-    out.write( " *  This file has been merged from multiple headers. Please don't edit it directly\n" )
-    out.write( " *  Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.\n" )
-    out.write( " *\n" )
-    out.write( " *  Distributed under the Boost Software License, Version 1.0. (See accompanying\n" )
-    out.write( " *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n" )
-    out.write( " */\n" )
-    out.write( "#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n" )
-    out.write( "#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n" )
-
-    parseFile( rootPath, 'catch.hpp' )
-
-    out.write( "#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n\n" )
-
-generateSingleInclude()
+print ("Generated single include for Catch v{0}\n".format( v.getVersionString() ) )
diff --git a/scripts/majorRelease.py b/scripts/majorRelease.py
new file mode 100644
index 0000000..03b7e78
--- /dev/null
+++ b/scripts/majorRelease.py
@@ -0,0 +1,9 @@
+from  __future__ import  print_function
+from releaseCommon import Version
+
+v = Version()
+v.incrementMajorVersion()
+v.updateVersionFile()
+v.updateReadmeFile()
+
+print( "Updated Version.hpp and README to v{0}".format( v.getVersionString() ) )
\ No newline at end of file
diff --git a/scripts/minorRelease.py b/scripts/minorRelease.py
new file mode 100644
index 0000000..bbd97ed
--- /dev/null
+++ b/scripts/minorRelease.py
@@ -0,0 +1,9 @@
+from  __future__ import  print_function
+from releaseCommon import Version
+
+v = Version()
+v.incrementMinorVersion()
+v.updateVersionFile()
+v.updateReadmeFile()
+
+print( "Updated Version.hpp and README to v{0}".format( v.getVersionString() ) )
\ No newline at end of file
diff --git a/scripts/patchRelease.py b/scripts/patchRelease.py
new file mode 100644
index 0000000..6abf87a
--- /dev/null
+++ b/scripts/patchRelease.py
@@ -0,0 +1,9 @@
+from  __future__ import  print_function
+from releaseCommon import Version
+
+v = Version()
+v.incrementPatchNumber()
+v.updateVersionFile()
+v.updateReadmeFile()
+
+print( "Updated Version.hpp and README to v{0}".format( v.getVersionString() ) )
\ No newline at end of file
diff --git a/scripts/releaseCommon.py b/scripts/releaseCommon.py
new file mode 100644
index 0000000..14eb235
--- /dev/null
+++ b/scripts/releaseCommon.py
@@ -0,0 +1,89 @@
+from  __future__ import  print_function
+
+import os
+import sys
+import re
+import string
+
+from scriptCommon import catchPath
+
+versionParser = re.compile( r'(\s*Version\slibraryVersion)\s*\(\s*(.*)\s*,\s*(.*)\s*,\s*(.*)\s*,\s*\"(.*)\"\s*,\s*(.*)\s*\).*' )
+rootPath = os.path.join( catchPath, 'include/' )
+versionPath = os.path.join( rootPath, "internal/catch_version.hpp" )
+readmePath = os.path.join( catchPath, "README.md" )
+
+class Version:
+    def __init__(self):
+        f = open( versionPath, 'r' )
+        for line in f:
+            m = versionParser.match( line )
+            if m:
+                self.variableDecl = m.group(1)
+                self.majorVersion = int(m.group(2))
+                self.minorVersion = int(m.group(3))
+                self.patchNumber = int(m.group(4))
+                self.branchName = m.group(5)
+                self.buildNumber = int(m.group(6))
+        f.close()
+
+    def nonDevelopRelease(self):
+        if self.branchName != "":
+            self.branchName = ""
+            self.buildNumber = 0
+    def developBuild(self):
+        if self.branchName == "":
+            self.branchName = "develop"
+            self.buildNumber = 0
+
+    def incrementBuildNumber(self):
+        self.developBuild()
+        self.buildNumber = self.buildNumber+1
+
+    def incrementPatchNumber(self):
+        self.nonDevelopRelease()
+        self.patchNumber = self.patchNumber+1
+
+    def incrementMinorVersion(self):
+        self.nonDevelopRelease()
+        self.patchNumber = 0
+        self.minorVersion = self.minorVersion+1
+
+    def incrementMajorVersion(self):
+        self.nonDevelopRelease()
+        self.patchNumber = 0
+        self.minorVersion = 0
+        self.majorVersion = self.majorVersion+1
+
+    def getVersionString(self):
+        versionString = '{0}.{1}.{2}'.format( self.majorVersion, self.minorVersion, self.patchNumber )
+        if self.branchName != "":
+            versionString = versionString + '-{0}.{1}'.format( self.branchName, self.buildNumber )
+        return versionString
+
+    def updateVersionFile(self):
+        f = open( versionPath, 'r' )
+        lines = []
+        for line in f:
+            m = versionParser.match( line )
+            if m:
+                lines.append( '{0}( {1}, {2}, {3}, "{4}", {5} );'.format( self.variableDecl, self.majorVersion, self.minorVersion, self.patchNumber, self.branchName, self.buildNumber ) )
+            else:
+                lines.append( line.rstrip() )
+        f.close()
+        f = open( versionPath, 'w' )
+        for line in lines:
+            f.write( line + "\n" )
+
+    def updateReadmeFile(self):
+        f = open( readmePath, 'r' )
+        lines = []
+        for line in f:
+            lines.append( line.rstrip() )
+        f.close()
+        f = open( readmePath, 'w' )
+        for line in lines:
+            if line.startswith( "*v" ):
+                f.write( '*v{0}*\n'.format( self.getVersionString() ) )
+            else:
+                f.write( line + "\n" )
+
diff --git a/single_include/catch.hpp b/single_include/catch.hpp
index 391c7ab..24d677f 100644
--- a/single_include/catch.hpp
+++ b/single_include/catch.hpp
@@ -1,6 +1,6 @@
 /*
- *  CATCH v1.1 build 3 (master branch)
- *  Generated: 2015-05-21 06:16:00.388118
+ *  Catch v1.2.0
+ *  Generated: 2015-06-29 08:12:52.943445
  *  ----------------------------------------------------------
  *  This file has been merged from multiple headers. Please don't edit it directly
  *  Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
@@ -798,8 +798,8 @@
                         ResultDisposition::Flags resultDisposition );
 
         template<typename T>
-        ExpressionLhs<T const&> operator->* ( T const& operand );
-        ExpressionLhs<bool> operator->* ( bool value );
+        ExpressionLhs<T const&> operator <= ( T const& operand );
+        ExpressionLhs<bool> operator <= ( bool value );
 
         template<typename T>
         ResultBuilder& operator << ( T const& value ) {
@@ -1461,11 +1461,11 @@
 namespace Catch {
 
     template<typename T>
-    inline ExpressionLhs<T const&> ResultBuilder::operator->* ( T const& operand ) {
+    inline ExpressionLhs<T const&> ResultBuilder::operator <= ( T const& operand ) {
         return ExpressionLhs<T const&>( *this, operand );
     }
 
-    inline ExpressionLhs<bool> ResultBuilder::operator->* ( bool value ) {
+    inline ExpressionLhs<bool> ResultBuilder::operator <= ( bool value ) {
         return ExpressionLhs<bool>( *this, value );
     }
 
@@ -1637,7 +1637,7 @@
     do { \
         Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \
         try { \
-            ( __catchResult->*expr ).endExpression(); \
+            ( __catchResult <= expr ).endExpression(); \
         } \
         catch( ... ) { \
             __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \
@@ -5539,18 +5539,19 @@
     struct Version {
         Version(    unsigned int _majorVersion,
                     unsigned int _minorVersion,
-                    unsigned int _buildNumber,
-                    char const* const _branchName )
-        :   majorVersion( _majorVersion ),
-            minorVersion( _minorVersion ),
-            buildNumber( _buildNumber ),
-            branchName( _branchName )
-        {}
+                    unsigned int _patchNumber,
+                    std::string const& _branchName,
+                    unsigned int _buildNumber );
 
         unsigned int const majorVersion;
         unsigned int const minorVersion;
+        unsigned int const patchNumber;
+
+        // buildNumber is only used if branchName is not null
+        std::string const branchName;
         unsigned int const buildNumber;
-        char const* const branchName;
+
+        friend std::ostream& operator << ( std::ostream& os, Version const& version );
 
     private:
         void operator=( Version const& );
@@ -5670,12 +5671,7 @@
         }
 
         void showHelp( std::string const& processName ) {
-            Catch::cout() << "\nCatch v"    << libraryVersion.majorVersion << "."
-                                        << libraryVersion.minorVersion << " build "
-                                        << libraryVersion.buildNumber;
-            if( libraryVersion.branchName != std::string( "master" ) )
-                Catch::cout() << " (" << libraryVersion.branchName << " branch)";
-            Catch::cout() << "\n";
+            Catch::cout() << "\nCatch v" << libraryVersion << "\n";
 
             m_cli.usage( Catch::cout(), processName );
             Catch::cout() << "For more detail usage please see the project docs\n" << std::endl;
@@ -5692,9 +5688,10 @@
             catch( std::exception& ex ) {
                 {
                     Colour colourGuard( Colour::Red );
-                    Catch::cerr()   << "\nError(s) in input:\n"
-                                << Text( ex.what(), TextAttributes().setIndent(2) )
-                                << "\n\n";
+                    Catch::cerr()
+                        << "\nError(s) in input:\n"
+                        << Text( ex.what(), TextAttributes().setIndent(2) )
+                        << "\n\n";
                 }
                 m_cli.usage( Catch::cout(), m_configData.processName );
                 return (std::numeric_limits<int>::max)();
@@ -6806,8 +6803,33 @@
 
 namespace Catch {
 
-    // These numbers are maintained by a script
-    Version libraryVersion( 1, 1, 3, "master" );
+    Version::Version
+        (   unsigned int _majorVersion,
+            unsigned int _minorVersion,
+            unsigned int _patchNumber,
+            std::string const& _branchName,
+            unsigned int _buildNumber )
+    :   majorVersion( _majorVersion ),
+        minorVersion( _minorVersion ),
+        patchNumber( _patchNumber ),
+        branchName( _branchName ),
+        buildNumber( _buildNumber )
+    {}
+
+    std::ostream& operator << ( std::ostream& os, Version const& version ) {
+        os  << version.majorVersion << "."
+            << version.minorVersion << "."
+            << version.patchNumber;
+
+        if( !version.branchName.empty() ) {
+            os  << "-" << version.branchName
+                << "." << version.buildNumber;
+        }
+        return os;
+    }
+
+    Version libraryVersion( 1, 2, 0, "", 0 );
+
 }
 
 // #included from: catch_message.hpp
@@ -8733,12 +8755,7 @@
             stream  << "\n" << getLineOfChars<'~'>() << "\n";
             Colour colour( Colour::SecondaryText );
             stream  << currentTestRunInfo->name
-                    << " is a Catch v"  << libraryVersion.majorVersion << "."
-                    << libraryVersion.minorVersion << " b"
-                    << libraryVersion.buildNumber;
-            if( libraryVersion.branchName != std::string( "master" ) )
-                stream << " (" << libraryVersion.branchName << ")";
-            stream  << " host application.\n"
+                    << " is a Catch v"  << libraryVersion << " host application.\n"
                     << "Run with -? for options\n\n";
 
             if( m_config->rngSeed() != 0 )