diff --git a/scripts/generateSingleHeader.py b/scripts/generateSingleHeader.py
index 18a2612a..d5d51a7a 100755
--- a/scripts/generateSingleHeader.py
+++ b/scripts/generateSingleHeader.py
@@ -9,97 +9,100 @@ import datetime
import string
from scriptCommon import catchPath
-from releaseCommon import Version
-includesParser = re.compile( r'\s*#\s*include\s*"(.*)"' )
-guardParser = re.compile( r'\s*#.*TWOBLUECUBES_CATCH_.*_INCLUDED')
-defineParser = re.compile( r'\s*#define')
-ifParser = re.compile( r'\s*#ifndef TWOBLUECUBES_CATCH_.*_INCLUDED')
-endIfParser = re.compile( r'\s*#endif // TWOBLUECUBES_CATCH_.*_INCLUDED')
-ifImplParser = re.compile( r'\s*#ifdef CATCH_CONFIG_RUNNER' )
-commentParser1 = re.compile( r'^\s*/\*')
-commentParser2 = re.compile( r'^ \*')
-blankParser = re.compile( r'^\s*$')
-seenHeaders = set([])
-rootPath = os.path.join( catchPath, 'include/' )
-outputPath = os.path.join( catchPath, 'single_include/catch.hpp' )
+def generate(v):
+ includesParser = re.compile( r'\s*#\s*include\s*"(.*)"' )
+ guardParser = re.compile( r'\s*#.*TWOBLUECUBES_CATCH_.*_INCLUDED')
+ defineParser = re.compile( r'\s*#define')
+ ifParser = re.compile( r'\s*#ifndef TWOBLUECUBES_CATCH_.*_INCLUDED')
+ endIfParser = re.compile( r'\s*#endif // TWOBLUECUBES_CATCH_.*_INCLUDED')
+ ifImplParser = re.compile( r'\s*#ifdef CATCH_CONFIG_RUNNER' )
+ commentParser1 = re.compile( r'^\s*/\*')
+ commentParser2 = re.compile( r'^ \*')
+ blankParser = re.compile( r'^\s*$')
+ seenHeaders = set([])
+ rootPath = os.path.join( catchPath, 'include/' )
+ outputPath = os.path.join( catchPath, 'single_include/catch.hpp' )
-includeImpl = True
-for arg in sys.argv[1:]:
- arg = string.lower(arg)
- if arg == "noimpl":
- includeImpl = False
- print( "Not including impl code" )
- else:
- print( "\n** Unrecognised argument: " + arg + " **\n" )
- exit(1)
+ globals = {
+ 'ifdefs' : 0,
+ 'implIfDefs' : -1,
+ 'includeImpl': True
+ }
-out = open( outputPath, 'w' )
-ifdefs = 0
-implIfDefs = -1
-
-def write( line ):
- if includeImpl or implIfDefs == -1:
- out.write( line )
-
-def parseFile( path, filename ):
- global ifdefs
- global implIfDefs
-
- f = open( path + filename, 'r' )
- blanks = 0
- for line in f:
- if ifParser.match( line ):
- ifdefs = ifdefs + 1
- elif endIfParser.match( line ):
- ifdefs = ifdefs - 1
- if ifdefs == implIfDefs:
- implIfDefs = -1
- m = includesParser.match( line )
- if m:
- header = m.group(1)
- headerPath, sep, headerFile = header.rpartition( "/" )
- if not headerFile in seenHeaders:
- if headerFile != "tbc_text_format.h" and headerFile != "clara.h":
- seenHeaders.add( headerFile )
- write( "// #included from: {0}\n".format( header ) )
- if headerPath == "internal" and path.endswith("internal/"):
- headerPath = ""
- sep = ""
- if os.path.exists( path + headerPath + sep + headerFile ):
- parseFile( path + headerPath + sep, headerFile )
- else:
- parseFile( rootPath + headerPath + sep, headerFile )
+ for arg in sys.argv[1:]:
+ arg = string.lower(arg)
+ if arg == "noimpl":
+ globals['includeImpl'] = False
+ print( "Not including impl code" )
else:
- if ifImplParser.match(line):
- implIfDefs = ifdefs
- if (not guardParser.match( line ) or defineParser.match( line ) ) and not commentParser1.match( line )and not commentParser2.match( line ):
- if blankParser.match( line ):
- blanks = blanks + 1
- else:
- blanks = 0
- if blanks < 2:
- write( line.rstrip() + "\n" )
+ print( "\n** Unrecognised argument: " + arg + " **\n" )
+ exit(1)
+
+ out = open( outputPath, 'w' )
+
+ def write( line ):
+ if globals['includeImpl'] or globals['implIfDefs'] == -1:
+ out.write( line )
+
+ def parseFile( path, filename ):
+ f = open( path + filename, 'r' )
+ blanks = 0
+ for line in f:
+ if ifParser.match( line ):
+ globals['ifdefs'] += 1
+ elif endIfParser.match( line ):
+ globals['ifdefs'] -= 1
+ if globals['ifdefs'] == globals['implIfDefs']:
+ globals['implIfDefs'] = -1
+ m = includesParser.match( line )
+ if m:
+ header = m.group(1)
+ headerPath, sep, headerFile = header.rpartition( "/" )
+ if not headerFile in seenHeaders:
+ if headerFile != "tbc_text_format.h" and headerFile != "clara.h":
+ seenHeaders.add( headerFile )
+ write( "// #included from: {0}\n".format( header ) )
+ if headerPath == "internal" and path.endswith("internal/"):
+ headerPath = ""
+ sep = ""
+ if os.path.exists( path + headerPath + sep + headerFile ):
+ parseFile( path + headerPath + sep, headerFile )
+ else:
+ parseFile( rootPath + headerPath + sep, headerFile )
+ else:
+ if ifImplParser.match(line):
+ globals['implIfDefs'] = globals['ifdefs']
+ if (not guardParser.match( line ) or defineParser.match( line ) ) and not commentParser1.match( line )and not commentParser2.match( line ):
+ if blankParser.match( line ):
+ blanks = blanks + 1
+ else:
+ blanks = 0
+ if blanks < 2:
+ write( line.rstrip() + "\n" )
-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" )
+ 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" )
-parseFile( rootPath, 'catch.hpp' )
+ parseFile( rootPath, 'catch.hpp' )
-out.write( "#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n\n" )
+ out.write( "#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n\n" )
+ out.close()
+ print ("Generated single include for Catch v{0}\n".format( v.getVersionString() ) )
-print ("Generated single include for Catch v{0}\n".format( v.getVersionString() ) )
+if __name__ == '__main__':
+ from releaseCommon import Version
+ generate(Version())
diff --git a/scripts/majorRelease.py b/scripts/majorRelease.py
index e8116d3b..8da34066 100755
--- a/scripts/majorRelease.py
+++ b/scripts/majorRelease.py
@@ -1,13 +1,10 @@
#!/usr/bin/env python
from __future__ import print_function
-from releaseCommon import Version
+import releaseCommon
-v = Version()
+v = releaseCommon.Version()
v.incrementMajorVersion()
-v.updateVersionFile()
-v.updateReadmeFile()
-v.updateConanFile()
-v.updateConanTestFile()
+releaseCommon.performUpdates(v)
print( "Updated Version.hpp, README and Conan to v{0}".format( v.getVersionString() ) )
diff --git a/scripts/minorRelease.py b/scripts/minorRelease.py
index dff2d8c8..6e71cd80 100755
--- a/scripts/minorRelease.py
+++ b/scripts/minorRelease.py
@@ -1,13 +1,10 @@
#!/usr/bin/env python
from __future__ import print_function
-from releaseCommon import Version
+import releaseCommon
-v = Version()
+v = releaseCommon.Version()
v.incrementMinorVersion()
-v.updateVersionFile()
-v.updateReadmeFile()
-v.updateConanFile()
-v.updateConanTestFile()
+releaseCommon.performUpdates(v)
print( "Updated Version.hpp, README and Conan to v{0}".format( v.getVersionString() ) )
diff --git a/scripts/patchRelease.py b/scripts/patchRelease.py
index e33e4064..14176420 100755
--- a/scripts/patchRelease.py
+++ b/scripts/patchRelease.py
@@ -1,13 +1,10 @@
#!/usr/bin/env python
from __future__ import print_function
-from releaseCommon import Version
+import releaseCommon
-v = Version()
+v = releaseCommon.Version()
v.incrementPatchNumber()
-v.updateVersionFile()
-v.updateReadmeFile()
-v.updateConanFile()
-v.updateConanTestFile()
+releaseCommon.performUpdates(v)
print( "Updated Version.hpp, README and Conan to v{0}".format( v.getVersionString() ) )
diff --git a/scripts/releaseCommon.py b/scripts/releaseCommon.py
index 9a62690d..a5fdd7d0 100644
--- a/scripts/releaseCommon.py
+++ b/scripts/releaseCommon.py
@@ -6,6 +6,8 @@ import re
import string
from scriptCommon import catchPath
+import generateSingleHeader
+import updateWandbox
versionParser = re.compile( r'(\s*static\sVersion\sversion)\s*\(\s*(.*)\s*,\s*(.*)\s*,\s*(.*)\s*,\s*\"(.*)\"\s*,\s*(.*)\s*\).*' )
rootPath = os.path.join( catchPath, 'include/' )
@@ -76,44 +78,61 @@ class Version:
for line in lines:
f.write( line + "\n" )
- def updateReadmeFile(self):
- downloadParser = re.compile( r'' )
- f = open( readmePath, 'r' )
- lines = []
- for line in f:
+def updateReadmeFile(version):
+ downloadParser = re.compile( r'' )
+ success, wandboxLink = updateWandbox.uploadFiles()
+ if not success:
+ print('Error when uploading to wandbox: {}'.format(wandboxLink))
+ exit(1)
+ f = open( readmePath, 'r' )
+ lines = []
+ for line in f:
+ lines.append( line.rstrip() )
+ f.close()
+ f = open( readmePath, 'w' )
+ for line in lines:
+ line = downloadParser.sub( r''.format(version.getVersionString()) , line)
+ if '[![Try online](https://img.shields.io/badge/try-online-blue.svg)]' in line:
+ line = '[![Try online](https://img.shields.io/badge/try-online-blue.svg)]({0})'.format(wandboxLink)
+ f.write( line + "\n" )
+
+def updateConanFile(version):
+ conanParser = re.compile( r' version = "\d+\.\d+\.\d+.*"')
+ f = open( conanPath, 'r' )
+ lines = []
+ for line in f:
+ m = conanParser.match( line )
+ if m:
+ lines.append( ' version = "{0}"'.format(format(version.getVersionString())) )
+ else:
lines.append( line.rstrip() )
- f.close()
- f = open( readmePath, 'w' )
- for line in lines:
- line = downloadParser.sub( r''.format(self.getVersionString()) , line)
- f.write( line + "\n" )
+ f.close()
+ f = open( conanPath, 'w' )
+ for line in lines:
+ f.write( line + "\n" )
- def updateConanFile(self):
- conanParser = re.compile( r' version = "\d+\.\d+\.\d+.*"')
- f = open( conanPath, 'r' )
- lines = []
- for line in f:
- m = conanParser.match( line )
- if m:
- lines.append( ' version = "{0}"'.format(format(self.getVersionString())) )
- else:
- lines.append( line.rstrip() )
- f.close()
- f = open( conanPath, 'w' )
- for line in lines:
- f.write( line + "\n" )
+def updateConanTestFile(version):
+ conanParser = re.compile( r' requires = \"Catch\/\d+\.\d+\.\d+.*@%s\/%s\" % \(username, channel\)')
+ f = open( conanTestPath, 'r' )
+ lines = []
+ for line in f:
+ m = conanParser.match( line )
+ if m:
+ lines.append( ' requires = "Catch/{0}@%s/%s" % (username, channel)'.format(format(version.getVersionString())) )
+ else:
+ lines.append( line.rstrip() )
+ f.close()
+ f = open( conanTestPath, 'w' )
+ for line in lines:
+ f.write( line + "\n" )
- def updateConanTestFile(self):
- conanParser = re.compile( r' requires = \"Catch\/\d+\.\d+\.\d+.*@%s\/%s\" % \(username, channel\)')
- f = open( conanTestPath, 'r' )
- lines = []
- for line in f:
- m = conanParser.match( line )
- if m:
- lines.append( ' requires = "Catch/{0}@%s/%s" % (username, channel)'.format(format(self.getVersionString())) )
- else:
- lines.append( line.rstrip() )
- f.close()
- f = open( conanTestPath, 'w' )
- for line in lines:
- f.write( line + "\n" )
+def performUpdates(version):
+ # First update version file, so we can regenerate single header and
+ # have it ready for upload to wandbox, when updating readme
+ version.updateVersionFile()
+ # ToDo: Regenerate single header
+ generateSingleHeader.generate(version)
+ updateReadmeFile(version)
+
+ updateConanFile(version)
+ updateConanTestFile(version)
diff --git a/scripts/updateWandbox.py b/scripts/updateWandbox.py
new file mode 100644
index 00000000..25a74631
--- /dev/null
+++ b/scripts/updateWandbox.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+
+import json
+import os
+import urllib2
+
+from scriptCommon import catchPath
+
+def upload(options):
+ request = urllib2.Request('http://melpon.org/wandbox/api/compile.json')
+ request.add_header('Content-Type', 'application/json')
+ response = urllib2.urlopen(request, json.dumps(options))
+ return json.loads(response.read())
+
+main_file = '''
+#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
+#include "catch.hpp"
+
+unsigned int Factorial( unsigned int number ) {
+ return number <= 1 ? number : Factorial(number-1)*number;
+}
+
+TEST_CASE( "Factorials are computed", "[factorial]" ) {
+ REQUIRE( Factorial(1) == 1 );
+ REQUIRE( Factorial(2) == 2 );
+ REQUIRE( Factorial(3) == 6 );
+ REQUIRE( Factorial(10) == 3628800 );
+}
+'''
+
+def uploadFiles():
+ response = upload({
+ 'compiler': 'gcc-head',
+ 'code': main_file,
+ 'codes': [{
+ 'file': 'catch.hpp',
+ 'code': open(os.path.join(catchPath, 'single_include', 'catch.hpp')).read()
+ }],
+ 'options': 'c++11,cpp-no-pedantic,boost-nothing',
+ 'compiler-option-raw': '-DCATCH_CONFIG_FAST_COMPILE',
+ 'save': True
+ })
+
+ if 'status' in response and not 'compiler_error' in response:
+ return True, response['url']
+ else:
+ return False, response