def __preprocess(self, match):

		raw_incl = match if isinstance(match, str) else match.group(1)
		incl = raw_incl.strip().lower()
		if incl in self.__processed_includes:
			return ''

		self.__processed_includes.append(incl)
		text = utils.read_all_text_from_file(Path(utils.entry_script_dir(), '..', 'include', 'toml++', incl).resolve(), logger=True).strip() + '\n'
		text = text.replace('\r\n', '\n') # convert windows newlines
		text = self.__re_strip_blocks.sub('', text, 0) # strip {{ }} blocks
		self.__current_level += 1
		text = self.__re_includes.sub(lambda m : self.__preprocess(m), text, 0)
		self.__current_level -= 1

		if (self.__current_level == 1):
			header_text = '↓ ' + raw_incl
			lpad = 20 + ((25 * (self.__header_indent % 4)) - int((len(header_text) + 4) / 2))
			self.__header_indent += 1
			text = '#if 1  {}\n{}\n\n#endif {}\n'.format(
				utils.make_divider(header_text, lpad, line_length=113),
				text,
				utils.make_divider('↑ ' + raw_incl, lpad, line_length=113)
			)

		return '\n\n' + text + '\n\n' # will get merged later
def main():
	extern_root = Path(utils.entry_script_dir(), '..', 'external').resolve()
	utils.assert_existing_directory(extern_root)
	assert extern_root.exists()
	all_tests = { 'valid': dict(), 'invalid': dict() }
	load_valid_inputs(all_tests, extern_root)
	load_invalid_inputs(all_tests, extern_root)
	for validity, sources in all_tests.items():
		for source, tests in sources.items():
			write_test_file('{}/{}'.format(source, validity), tests )
def main():
    extern_root = Path(utils.entry_script_dir(), '..', 'external').resolve()
    utils.assert_existing_directory(extern_root)
    assert extern_root.exists()
    tests = {'valid': dict(), 'invalid': dict()}
    load_valid_inputs(tests, extern_root)
    load_invalid_inputs(tests, extern_root)
    for test_type, test_groups in tests.items():
        for test_group, test_cases in test_groups.items():
            write_test_file('{}/{}'.format(test_group, test_type), test_cases)
Beispiel #4
0
def main():
    hpp_path = Path(utils.entry_script_dir(), '..', 'toml.hpp').resolve()
    hash1 = utils.sha1(utils.read_all_text_from_file(hpp_path, logger=True))
    print(rf'Hash 1: {hash1}')
    utils.run_python_script(r'generate_single_header.py')
    hash2 = utils.sha1(utils.read_all_text_from_file(hpp_path, logger=True))
    print(rf'Hash 2: {hash2}')
    if (hash1 != hash2):
        print(
            "toml.hpp wasn't up-to-date!\nRun generate_single_header.py before your commit to prevent this error.",
            file=sys.stderr)
        return 1
    print("toml.hpp was up-to-date")
    return 0
Beispiel #5
0
def main():

	# establish local directories
	root_dir = utils.entry_script_dir().parent
	include_dir = Path(root_dir, 'include', 'toml++')

	# preprocess header(s)
	toml_h = str(Preprocessor(Path(include_dir, 'toml.h')))

	# strip various things:
	if 1:
		for i in range(3):
			# trailing whitespace
			toml_h = re.sub('([^ \t])[ \t]+\n', r'\1\n', toml_h)
			# explicit 'strip this' blocks
			toml_h = re.sub(r'(?:\n[ \t]*)?//[#!][ \t]*[{][{].*?//[#!][ \t]*[}][}].*?\n', '\n', toml_h, flags=re.S)
			# spdx license identifiers
			toml_h = re.sub(r'^\s*//\s*SPDX-License-Identifier:.+?$', '', toml_h, 0, re.I | re.M)
			# double blank lines
			toml_h = re.sub('\n(?:[ \t]*\n[ \t]*)+\n', '\n\n', toml_h)
			# magic comments
			blank_line = r'(?:[ \t]*\n)'
			comment_line = r'(?:[ \t]*//(?:[/#!<]| ?(?:---|===|\^\^\^|vvv))[^\n]*\n)'
			toml_h = re.sub(rf'\n{comment_line}{blank_line}+{comment_line}', '\n', toml_h)
			toml_h = re.sub(rf'([{{,])\s*\n(?:{comment_line}|{blank_line})+', r'\1\n', toml_h)
			toml_h = re.sub(rf'{comment_line}+', '\n', toml_h)
			# weird spacing edge case between } and pp directives
			toml_h = re.sub('\n[}]\n#', r'\n}\n\n#', toml_h, re.S)
			# enable warnings -> disable warnings
			toml_h = re.sub('(TOML_ENABLE_WARNINGS;)\n[ \t\n]*\n(TOML_DISABLE_WARNINGS;)', r'', toml_h)
			# blank lines between consecutive TOML_XXXXX_WARNINGS statements
			toml_h = re.sub('(TOML_[A-Z_]+?_WARNINGS;)\n[ \t\n]*\n(TOML_[A-Z_]+?_WARNINGS;)', r'\1\n\2', toml_h)
			# blank lines between consecutive #includes
			toml_h = re.sub('[#]\s*include\s*<(.+?)>\n[ \t\n]*\n[#]\s*include\s*<(.+?)>', r'#include <\1>\n#include <\2>', toml_h)
			# blank lines following opening brackets or a comma
			toml_h = re.sub(r'([^@][({,])\n\n', r'\1\n', toml_h)
			# blank lines preceeding closing brackets
			toml_h = re.sub(r'\n\n([ \t]*[})])', r'\n\1', toml_h)
		# ensure only one trailing newline
		toml_h = toml_h.strip() + '\n'

	# change TOML_LIB_SINGLE_HEADER to 1
	toml_h = re.sub(
		'#\s*define\s+TOML_LIB_SINGLE_HEADER\s+[0-9]+',
		'#define	TOML_LIB_SINGLE_HEADER 1',
		toml_h, 0, re.I
	)

	# read version number
	version_h = utils.read_all_text_from_file(Path(include_dir, 'impl/version.h'), logger=True)
	match = re.search(
			r'#\s*define\s+TOML_LIB_MAJOR\s+([0-9]+)[^0-9].*'
			+ r'#\s*define\s+TOML_LIB_MINOR\s+([0-9]+)[^0-9].*'
			+ r'#\s*define\s+TOML_LIB_PATCH\s+([0-9]+)[^0-9]',
			version_h, re.I | re.S)
	if match is None:
		raise Exception("could not find TOML_LIB_MAJOR, TOML_LIB_MINOR or TOML_LIB_PATCH impl/version.h")
	version = rf'{int(match[1])}.{int(match[2])}.{int(match[3])}'
	print(rf'Library version: {version}')

	# build the preamble (license etc)
	preamble = []
	preamble.append(rf'''
// toml++ v{version}
// https://github.com/marzer/tomlplusplus
// SPDX-License-Identifier: MIT''')
	preamble.append(r'''
// -         THIS FILE WAS ASSEMBLED FROM MULTIPLE HEADER FILES BY A SCRIPT - PLEASE DON'T EDIT IT DIRECTLY            -
//
// If you wish to submit a contribution to toml++, hooray and thanks! Before you crack on, please be aware that this
// file was assembled from a number of smaller files by a python script, and code contributions should not be made
// against it directly. You should instead make your changes in the relevant source file(s). The file names of the files
// that contributed to this header can be found at the beginnings and ends of the corresponding sections of this file.''')
	preamble.append(r'''
// TOML Language Specifications:
// latest:      https://github.com/toml-lang/toml/blob/master/README.md
// v1.0.0:      https://toml.io/en/v1.0.0
// v0.5.0:      https://toml.io/en/v0.5.0
// changelog:   https://github.com/toml-lang/toml/blob/master/CHANGELOG.md''')
	preamble.append(utils.read_all_text_from_file(Path(utils.entry_script_dir(), '..', 'LICENSE').resolve(), logger=True))

	# write the output
	with StringIO(newline='\n') as output:

		# build in a string buffer
		write = lambda txt, end='\n': print(txt, file=output, end=end)
		if (len(preamble) > 0):
			write(utils.make_divider())
		for pre in preamble:
			write('//')
			for line in pre.strip().splitlines():
				if len(line) == 0:
					write('//')
					continue
				if not line.startswith('//'):
					write('// ', end = '')
				write(line)
			write('//')
			write(utils.make_divider())
		write(toml_h)
		write('')

		output_str = output.getvalue().strip()

		# analyze the output to find any potentially missing #undefs
		if 1:
			re_define = re.compile(r'^\s*#\s*define\s+([a-zA-Z0-9_]+)(?:$|\s|\()')
			re_undef = re.compile(r'^\s*#\s*undef\s+([a-zA-Z0-9_]+)(?:$|\s|//)')
			defines = dict()
			for output_line in output_str.splitlines():
				defined = True
				m = re_define.match(output_line)
				if not m:
					defined = False
					m = re_undef.match(output_line)
				if m:
					defines[m.group(1)] = defined
			ignore_list = ( # macros that are meant to stay public (user configs etc)
				r'INCLUDE_TOMLPLUSPLUS_H',
				r'POXY_IMPLEMENTATION_DETAIL',
				r'TOML_ALL_INLINE',
				r'TOML_API',
				r'TOML_CONCAT',
				r'TOML_CONCAT_1',
				r'TOML_CONFIG_HEADER',
				r'TOML_ENABLE_FORMATTERS',
				r'TOML_ENABLE_PARSER',
				r'TOML_ENABLE_SIMD',
				r'TOML_ENABLE_UNRELEASED_FEATURES',
				r'TOML_ENABLE_WINDOWS_COMPAT',
				r'TOML_EXCEPTIONS',
				r'TOML_EXTERN_TEMPLATES',
				r'TOML_HEADER_ONLY',
				r'TOML_LANG_MAJOR',
				r'TOML_LANG_MINOR',
				r'TOML_LANG_PATCH',
				r'TOML_LIB_MAJOR',
				r'TOML_LIB_MINOR',
				r'TOML_LIB_PATCH',
				r'TOML_LIB_SINGLE_HEADER',
				r'TOML_MAX_NESTED_VALUES',
				r'TOML_NAMESPACE_END',
				r'TOML_NAMESPACE_START',
				r'TOML_OPTIONAL_TYPE',
				r'TOML_SMALL_FLOAT_TYPE',
				r'TOML_SMALL_INT_TYPE',
				r'TOML_UNDEF_MACROS',
				r'TOMLPLUSPLUS_H',
			)
			set_defines = []
			for define, currently_set in defines.items():
				if currently_set and define not in ignore_list:
					set_defines.append(define)
			if len(set_defines) > 0:
				set_defines.sort()
				print(f"Potentially missing #undefs:")
				for define in set_defines:
					print(f"\t#undef {define}")

		# write the output file
		output_file_path = Path(utils.entry_script_dir(), '..', 'toml.hpp').resolve()
		print("Writing to {}".format(output_file_path))
		with open(output_file_path,'w', encoding='utf-8', newline='\n') as output_file:
			print(output_str, file=output_file)
def main():

	# preprocess header(s)
	source_text = str(Preprocessor('toml.h'))

	# strip various things:
	# 'pragma once'
	source_text = re.sub(r'^\s*#\s*pragma\s+once\s*$', '', source_text, 0, re.I | re.M)
	# clang-format directives
	source_text = re.sub(r'^\s*//\s*clang-format\s+.+?$', '', source_text, 0, re.I | re.M)
	# spdx license identifiers
	source_text = re.sub(r'^\s*//\s*SPDX-License-Identifier:.+?$', '', source_text, 0, re.I | re.M)
	# 'magic' comment blocks (incl. doxygen)
	source_text = re.sub('(?:(?:\n|^)[ \t]*//[/#!<]+[^\n]*)+\n', '\n', source_text, 0, re.I | re.M)
	# 'magic' comments (incl. doxygen)
	source_text = re.sub('(?://[/#!<].*?)\n', '\n', source_text, 0, re.I | re.M)
	# remove trailing whitespace
	source_text = re.sub('([^ \t])[ \t]+\n', '\\1\n', source_text, 0, re.I | re.M)
	# bookended namespace blocks
	source_text = re.sub('}\n+TOML_NAMESPACE_END\n+TOML_NAMESPACE_START\n+{\n+', '\n', source_text, 0, re.I | re.M)
	source_text = re.sub('}\n+TOML_IMPL_NAMESPACE_END\n+TOML_IMPL_NAMESPACE_START\n+{\n+', '\n', source_text, 0, re.I | re.M)
	# blank lines before some preprocessor directives
	#source_text = re.sub('\n+\n(\s*)#\s*(elif|else|endif)(.*?)\n', '\n\\1#\\2\\3\n', source_text, 0, re.I | re.M)
	# blank lines after some preprocessor directives
	#source_text = re.sub('#\s*(if|ifn?def|elif|else)(.*?)\n\n+', '#\\1\\2\n', source_text, 0, re.I | re.M)
	# blank lines after opening braces
	source_text = re.sub('[{]\s*\n\s*\n+', '{\n', source_text, 0, re.I | re.M)
	# double newlines
	source_text = re.sub('\n(?:[ \t]*\n[ \t]*)+\n', '\n\n', source_text, 0, re.I | re.M)

	# source_text = re.sub(  # blank lines between various preprocessor directives
	# 	'[#](endif(?:\s*//[^\n]*)?)\n{2,}[#](ifn?(?:def)?|define)',
	# 	'#\\1\n#\\2',
	# 	source_text, 0, re.I | re.M
	# )
	return_type_pattern														\
		= r'(?:'															\
		+ r'(?:\[\[nodiscard\]\]\s*)?'										\
		+ r'(?:(?:friend|explicit|virtual|inline|const|operator)\s+)*'		\
		+ r'(?:'															\
			+ r'bool|int64_t|(?:const_)?iterator|double|void'				\
			+ r'|node(?:_(?:view|of)<.+?>|)?|table|array|value(?:<.+?>)?'	\
			+ r'|T|U|parse_(?:error|result)'								\
		+ r')'																\
		+ r'(?:\s*[&*]+)?'													\
		+ r'(?:\s*[(]\s*[)])?'												\
		+ r'\s+'															\
		+ r')'
	blank_lines_between_returns_pattern = '({}[^\n]+)\n\n([ \t]*{})'.format(return_type_pattern, return_type_pattern)
	for i in range(0, 5): # remove blank lines between simple one-liner definitions
		source_text = re.sub('(using .+?;)\n\n([ \t]*using)', '\\1\n\\2', source_text, 0, re.I | re.M)
		source_text = re.sub(
				'([a-zA-Z_][a-zA-Z0-9_]*[ \t]+[a-zA-Z_][a-zA-Z0-9_]*[ \t]*;)'	\
				+ '\n\n([ \t]*[a-zA-Z_][a-zA-Z0-9_]*[ \t]+[a-zA-Z_][a-zA-Z0-9_]*[ \t]*;)', '\\1\n\\2',
				source_text, 0, re.I | re.M)
		source_text = re.sub(blank_lines_between_returns_pattern, '\\1\n\\2', source_text, 0, re.I | re.M)
	source_text = source_text.strip() + '\n'

	# change TOML_LIB_SINGLE_HEADER to 1
	source_text = re.sub(
		'#\s*define\s+TOML_LIB_SINGLE_HEADER\s+[0-9]+',
		'#define	TOML_LIB_SINGLE_HEADER 1',
		source_text, 0, re.I
	)

	# extract library version
	library_version = {
		'major': 0,
		'minor': 0,
		'patch': 0
	}
	match = re.search(r'^\s*#\s*define\s+TOML_LIB_MAJOR\s+([0-9]+)\s*$', source_text, re.I | re.M)
	if match is not None:
		library_version['major'] = match.group(1)
	match = re.search(r'^\s*#\s*define\s+TOML_LIB_MINOR\s+([0-9]+)\s*$', source_text, re.I | re.M)
	if match is not None:
		library_version['minor'] = match.group(1)
	match = re.search(r'^\s*#\s*define\s+TOML_LIB_(?:REVISION|PATCH)\s+([0-9]+)\s*$', source_text, re.I | re.M)
	if match is not None:
		library_version['patch'] = match.group(1)

	# build the preamble (license etc)
	preamble = []
	preamble.append('''
// toml++ v{major}.{minor}.{patch}
// https://github.com/marzer/tomlplusplus
// SPDX-License-Identifier: MIT'''.format(**library_version))
	preamble.append('''
// -         THIS FILE WAS ASSEMBLED FROM MULTIPLE HEADER FILES BY A SCRIPT - PLEASE DON'T EDIT IT DIRECTLY            -
//
// If you wish to submit a contribution to toml++, hooray and thanks! Before you crack on, please be aware that this
// file was assembled from a number of smaller files by a python script, and code contributions should not be made
// against it directly. You should instead make your changes in the relevant source file(s). The file names of the files
// that contributed to this header can be found at the beginnings and ends of the corresponding sections of this file.''')
	preamble.append('''
// TOML Language Specifications:
// latest:      https://github.com/toml-lang/toml/blob/master/README.md
// v1.0.0:      https://toml.io/en/v1.0.0
// v0.5.0:      https://toml.io/en/v0.5.0
// changelog:   https://github.com/toml-lang/toml/blob/master/CHANGELOG.md''')
	preamble.append(utils.read_all_text_from_file(Path(utils.entry_script_dir(), '..', 'LICENSE').resolve(), logger=True))

	# write the output
	with StringIO(newline='\n') as output:

		# build in a string buffer
		write = lambda txt, end='\n': print(txt, file=output, end=end)
		if (len(preamble) > 0):
			write(utils.make_divider())
		for pre in preamble:
			write('//')
			for line in pre.strip().splitlines():
				if len(line) == 0:
					write('//')
					continue
				if not line.startswith('//'):
					write('// ', end = '')
				write(line)
			write('//')
			write(utils.make_divider())
		write(source_text)
		write('')

		output_str = output.getvalue().strip()

		# analyze the output to find any potentially missing #undefs
		re_define = re.compile(r'^\s*#\s*define\s+([a-zA-Z0-9_]+)(?:$|\s|\()')
		re_undef = re.compile(r'^\s*#\s*undef\s+([a-zA-Z0-9_]+)(?:$|\s|//)')
		defines = dict()
		for output_line in output_str.splitlines():
			defined = True
			m = re_define.match(output_line)
			if not m:
				defined = False
				m = re_undef.match(output_line)
			if m:
				defines[m.group(1)] = defined
		ignore_list = ( # macros that are meant to stay public (user configs etc)
			'INCLUDE_TOMLPLUSPLUS_H',
			'TOML_API',
			'TOML_UNRELEASED_FEATURES',
			'TOML_LARGE_FILES',
			'TOML_PARSER',
			'TOML_WINDOWS_COMPAT',
			'TOML_EXCEPTIONS',
			'TOML_LIB_SINGLE_HEADER',
			'TOML_LIB_MAJOR',
			'TOML_LIB_MINOR',
			'TOML_LIB_PATCH',
			'TOML_LANG_MAJOR',
			'TOML_LANG_MINOR',
			'TOML_LANG_PATCH',
			'TOML_UNDEF_MACROS',
			'TOML_HEADER_ONLY',
			'TOML_ALL_INLINE'
		)
		set_defines = []
		for define, currently_set in defines.items():
			if currently_set and define not in ignore_list:
				set_defines.append(define)
		if len(set_defines) > 0:
			set_defines.sort()
			print(f"Potentially missing #undefs:")
			for define in set_defines:
				print(f"\t#undef {define}")

		# write the output file
		output_file_path = Path(utils.entry_script_dir(), '..', 'toml.hpp').resolve()
		print("Writing to {}".format(output_file_path))
		with open(output_file_path,'w', encoding='utf-8', newline='\n') as output_file:
			print(output_str, file=output_file)
def write_test_file(name, all_tests):

	for test in all_tests:
		unicode = requires_unicode(str(test))
		if not unicode and not isinstance(test.expected(), bool):
			unicode = requires_unicode(test.expected().render())
		if unicode:
			test.add_condition(r'UNICODE_LITERALS_OK')

	tests_by_group = {}
	for test in all_tests:
		if test.group() not in tests_by_group:
			tests_by_group[test.group()] = {}
		cond = test.condition()
		if cond not in tests_by_group[test.group()]:
			tests_by_group[test.group()][cond] = []
		tests_by_group[test.group()][cond].append(test)
	all_tests = tests_by_group

	test_file_path = Path(utils.entry_script_dir(), '..', 'tests', rf'conformance_{sanitize(name.strip())}.cpp').resolve()
	print(rf'Writing to {test_file_path}')
	with open(test_file_path, 'w', encoding='utf-8', newline='\n') as test_file:
		write = lambda txt,end='\n': print(txt, file=test_file, end=end)

		# preamble
		write('// This file is a part of toml++ and is subject to the the terms of the MIT license.')
		write('// Copyright (c) Mark Gillard <*****@*****.**>')
		write('// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.')
		write('// SPDX-License-Identifier: MIT')
		write('//-----')
		write('// this file was generated by generate_conformance_tests.py - do not modify it directly')
		write('')
		write('#include "tests.h"')
		write('using namespace toml::impl;')
		write('')

		# test data
		write('TOML_DISABLE_WARNINGS; // unused variable spam')
		write('')
		write('namespace')
		write('{', end='')
		for group, conditions in all_tests.items():
			for condition, tests in conditions.items():
				write('')
				if condition != '':
					write(f'#if {condition}');
					write('')
				for test in tests:
					write(f'\t{test}')
				if condition != '':
					write('')
					write(f'#endif // {condition}');
		write('}')
		write('')
		write('TOML_ENABLE_WARNINGS;')
		write('')

		# tests
		write(f'TEST_CASE("conformance - {name}")')
		write('{', end='')
		for group, conditions in all_tests.items():
			for condition, tests in conditions.items():
				if condition != '':
					write('')
					write(f'#if {condition}');
				for test in tests:
					write('')
					expected = test.expected()
					if isinstance(expected, bool):
						if expected:
							write(f'\tparsing_should_succeed(FILE_LINE_ARGS, {test.identifier()}); // {test.name()}')
						else:
							write(f'\tparsing_should_fail(FILE_LINE_ARGS, {test.identifier()}); // {test.name()}')
					else:
						s = expected.render('\t\t')
						write(f'\tparsing_should_succeed(FILE_LINE_ARGS, {test.identifier()}, [](toml::table&& tbl) // {test.name()}')
						write('\t{')
						write(f'\t\tconst auto expected = {s};')
						write('\t\tREQUIRE(tbl == expected);')
						write('\t});')
				if condition != '':
					write('')
					write(f'#endif // {condition}');
		write('}')
		write('')
def main():

    mode_keys = ['!!debug', '!x86', 'cpplatest', 'unrel', 'noexcept']
    modes = [[]]
    for n in range(1, len(mode_keys)):
        for combo in itertools.combinations(mode_keys, n):
            modes.append([i for i in combo])
    modes.append(mode_keys)
    for mode in modes:
        if '!x86' not in mode:
            mode.insert(0, '!x64')
        if '!!debug' not in mode:
            mode.insert(0, '!!release')
        mode.sort()
        for i in range(0, len(mode)):
            while mode[i].startswith('!'):
                mode[i] = mode[i][1:]
    modes.sort()

    test_root = Path(utils.entry_script_dir(), '..', 'tests', 'vs').resolve()
    uuid_namespace = UUID('{51C7001B-048C-4AF0-B598-D75E78FF31F0}')
    configuration_name = lambda x: 'Debug' if x.lower(
    ) == 'debug' else 'Release'
    platform_name = lambda x: 'Win32' if x == 'x86' else x
    for mode in modes:
        file_path = Path(test_root, 'test_{}.vcxproj'.format('_'.join(mode)))
        print(f"Writing to {file_path}")
        with open(file_path, 'w', encoding='utf-8-sig',
                  newline='\r\n') as file:
            write = lambda txt: print(txt, file=file)
            write(r'''
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
	<ItemGroup Label="ProjectConfigurations">
		<ProjectConfiguration Include="{configuration}|{platform}">
			<Configuration>{configuration}</Configuration>
			<Platform>{platform}</Platform>
		</ProjectConfiguration>
	</ItemGroup>
	<PropertyGroup Label="Globals">
		<VCProjectVersion>16.0</VCProjectVersion>
		<ProjectGuid>{{{uuid}}}</ProjectGuid>
		<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
	</PropertyGroup>
	<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
	<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|{platform}'" Label="Configuration">
		<ConfigurationType>Application</ConfigurationType>
		<UseDebugLibraries>true</UseDebugLibraries>
		<PlatformToolset>v142</PlatformToolset>
		<CharacterSet>MultiByte</CharacterSet>
	</PropertyGroup>
	<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|{platform}'" Label="Configuration">
		<ConfigurationType>Application</ConfigurationType>
		<UseDebugLibraries>false</UseDebugLibraries>
		<PlatformToolset>v142</PlatformToolset>
		<WholeProgramOptimization>true</WholeProgramOptimization>
		<CharacterSet>MultiByte</CharacterSet>
	</PropertyGroup>
	<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
	<ImportGroup Label="PropertySheets">
		<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
			Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
	</ImportGroup>
	<Import Project="../../toml++.props" />
	<ItemDefinitionGroup>
		<ClCompile>
			<AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
			<ExceptionHandling>{exceptions}</ExceptionHandling>
			<PrecompiledHeader>Use</PrecompiledHeader>
			<PrecompiledHeaderFile>tests.h</PrecompiledHeaderFile>
			<PreprocessorDefinitions>TOML_UNRELEASED_FEATURES={unreleased_features};%(PreprocessorDefinitions)</PreprocessorDefinitions>
			<PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
			<PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
			<PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
			<PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
			<LanguageStandard>std{standard}</LanguageStandard>
			<MultiProcessorCompilation>true</MultiProcessorCompilation>
		</ClCompile>
	</ItemDefinitionGroup>
	<PropertyGroup>
		<LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
	</PropertyGroup>
	<ItemGroup>
		<ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
		<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
		<ClCompile Include="..\conformance_iarna_invalid.cpp" />
		<ClCompile Include="..\conformance_iarna_valid.cpp" />
		<ClCompile Include="..\impl_catch2.cpp">
			<PrecompiledHeader>NotUsing</PrecompiledHeader>
		</ClCompile>
		<ClCompile Include="..\impl_toml.cpp">
			<PrecompiledHeader>NotUsing</PrecompiledHeader>
		</ClCompile>
		<ClCompile Include="..\manipulating_arrays.cpp" />
		<ClCompile Include="..\manipulating_tables.cpp" />
		<ClCompile Include="..\manipulating_parse_result.cpp" />
		<ClCompile Include="..\manipulating_values.cpp" />
		<ClCompile Include="..\parsing_arrays.cpp" />
		<ClCompile Include="..\parsing_booleans.cpp" />
		<ClCompile Include="..\parsing_comments.cpp" />
		<ClCompile Include="..\parsing_dates_and_times.cpp" />
		<ClCompile Include="..\parsing_floats.cpp" />
		<ClCompile Include="..\parsing_integers.cpp" />
		<ClCompile Include="..\parsing_key_value_pairs.cpp" />
		<ClCompile Include="..\parsing_spec_example.cpp" />
		<ClCompile Include="..\parsing_strings.cpp" />
		<ClCompile Include="..\parsing_tables.cpp" />
		<ClCompile Include="..\tests.cpp">
			<PrecompiledHeader>Create</PrecompiledHeader>
		</ClCompile>
		<ClCompile Include="..\unicode.cpp" />
		<ClCompile Include="..\user_feedback.cpp" />
		<ClCompile Include="..\using_iterators.cpp" />
		<ClCompile Include="..\windows_compat.cpp" />
	</ItemGroup>
	<ItemGroup>
		<Natvis Include="..\..\toml++.natvis" />
	</ItemGroup>
	<ItemGroup>
		<ClInclude Include="..\catch2.h" />
		<ClInclude Include="..\leakproof.h" />
		<ClInclude Include="..\settings.h" />
		<ClInclude Include="..\tests.h" />
		<ClInclude Include="..\tloptional.h" />
	</ItemGroup>
	<ItemGroup>
		<None Include="..\cpp.hint" />
		<None Include="..\meson.build" />
	</ItemGroup>
	<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
			'''.strip().format(
                configuration=next(
                    configuration_name(x) for x in mode
                    if x in ('debug', 'release')),
                platform=next(
                    platform_name(x) for x in mode if x in ('x64', 'x86')),
                uuid=str(uuid5(uuid_namespace, '_'.join(mode))).upper(),
                exceptions='false' if 'noexcept' in mode else 'Sync',
                unreleased_features=1 if 'unrel' in mode else 0,
                standard='cpplatest' if 'cpplatest' in mode else 'cpp17'))
Beispiel #9
0
def main():

	mode_keys = [ '!!debug', '!x86', 'cpplatest', 'unrel', 'noexcept' ]
	modes = [ [] ]
	for n in range(1, len(mode_keys)):
		for combo in itertools.combinations(mode_keys, n):
			modes.append([i for i in combo])
	modes.append(mode_keys)
	for mode in modes:
		if '!x86' not in mode:
			mode.insert(0, '!x64')
		if '!!debug' not in mode:
			mode.insert(0, '!!release')
		mode.sort()
		for i in range(0, len(mode)):
			while mode[i].startswith('!'):
				mode[i] = mode[i][1:]
	modes.sort()

	test_root = Path(utils.entry_script_dir(), '..', 'tests', 'vs').resolve()
	uuid_namespace = UUID('{51C7001B-048C-4AF0-B598-D75E78FF31F0}')
	configuration_name = lambda x: 'Debug' if x.lower() == 'debug' else 'Release'
	platform_name = lambda x: 'Win32' if x == 'x86' else x
	for mode in modes:
		file_path = Path(test_root, 'test_{}.vcxproj'.format('_'.join(mode)))
		print(f"Writing to {file_path}")
		with open(file_path, 'w', encoding='utf-8-sig', newline='\r\n') as file:
			write = lambda txt: print(txt, file=file)
			write(r'''
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
	<ItemGroup Label="ProjectConfigurations">
		<ProjectConfiguration Include="{configuration}|{platform}">
			<Configuration>{configuration}</Configuration>
			<Platform>{platform}</Platform>
		</ProjectConfiguration>
	</ItemGroup>
	<PropertyGroup Label="Globals">
		<VCProjectVersion>16.0</VCProjectVersion>
		<ProjectGuid>{{{uuid}}}</ProjectGuid>
		<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
	</PropertyGroup>
	<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
	<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|{platform}'" Label="Configuration">
		<ConfigurationType>Application</ConfigurationType>
		<UseDebugLibraries>true</UseDebugLibraries>
		<PlatformToolset>v142</PlatformToolset>
		<CharacterSet>MultiByte</CharacterSet>
	</PropertyGroup>
	<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|{platform}'" Label="Configuration">
		<ConfigurationType>Application</ConfigurationType>
		<UseDebugLibraries>false</UseDebugLibraries>
		<PlatformToolset>v142</PlatformToolset>
		<WholeProgramOptimization>true</WholeProgramOptimization>
		<CharacterSet>MultiByte</CharacterSet>
	</PropertyGroup>
	<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
	<ImportGroup Label="PropertySheets">
		<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"
			Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
	</ImportGroup>
	<Import Project="../../toml++.props" />
	<ItemDefinitionGroup>
		<ClCompile>
			<AdditionalIncludeDirectories>..\tests;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
			<ExceptionHandling>{exceptions}</ExceptionHandling>
			<PrecompiledHeader>Use</PrecompiledHeader>
			<PrecompiledHeaderFile>tests.h</PrecompiledHeaderFile>
			<PreprocessorDefinitions>TOML_UNRELEASED_FEATURES={unreleased_features};%(PreprocessorDefinitions)</PreprocessorDefinitions>
			<PreprocessorDefinitions>LEAK_TESTS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
			<PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
			<PreprocessorDefinitions Condition="'%(ExceptionHandling)'=='false'">SHOULD_HAVE_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
			<PreprocessorDefinitions Condition="'%(ExceptionHandling)'!='false'">SHOULD_HAVE_EXCEPTIONS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
			<LanguageStandard>std{standard}</LanguageStandard>
			<MultiProcessorCompilation>true</MultiProcessorCompilation>
			<WarningLevel>EnableAllWarnings</WarningLevel>
			<DisableSpecificWarnings>%(DisableSpecificWarnings);4127</DisableSpecificWarnings> <!-- conditional expr is constant -->
			<DisableSpecificWarnings>%(DisableSpecificWarnings);4324</DisableSpecificWarnings> <!-- structure was padded due to alignment specifier -->
			<DisableSpecificWarnings>%(DisableSpecificWarnings);4464</DisableSpecificWarnings> <!-- relative include path contains '..' -->
			<DisableSpecificWarnings>%(DisableSpecificWarnings);4505</DisableSpecificWarnings> <!-- unreferenced local function removed -->
			<DisableSpecificWarnings>%(DisableSpecificWarnings);4514</DisableSpecificWarnings> <!-- unreferenced inline function has been removed -->
			<DisableSpecificWarnings>%(DisableSpecificWarnings);4577</DisableSpecificWarnings> <!-- 'noexcept' used with no exception handling mode specified -->
			<DisableSpecificWarnings>%(DisableSpecificWarnings);4582</DisableSpecificWarnings> <!-- constructor is not implicitly called -->
			<DisableSpecificWarnings>%(DisableSpecificWarnings);4623</DisableSpecificWarnings> <!-- default constructor was implicitly defined as deleted -->
			<DisableSpecificWarnings>%(DisableSpecificWarnings);4625</DisableSpecificWarnings> <!-- copy constructor was implicitly defined as deleted -->
			<DisableSpecificWarnings>%(DisableSpecificWarnings);4626</DisableSpecificWarnings> <!-- assignment operator was implicitly defined as deleted -->
			<DisableSpecificWarnings>%(DisableSpecificWarnings);4710</DisableSpecificWarnings> <!-- function not inlined -->
			<DisableSpecificWarnings>%(DisableSpecificWarnings);4711</DisableSpecificWarnings> <!-- function selected for automatic expansion -->
			<DisableSpecificWarnings>%(DisableSpecificWarnings);4738</DisableSpecificWarnings> <!-- storing 32-bit float result in memory -->
			<DisableSpecificWarnings>%(DisableSpecificWarnings);4820</DisableSpecificWarnings> <!-- N bytes padding added -->
			<DisableSpecificWarnings>%(DisableSpecificWarnings);4866</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in operator[] -->
			<DisableSpecificWarnings>%(DisableSpecificWarnings);4868</DisableSpecificWarnings> <!-- compiler may not enforce ltr eval in initializer list -->
			<DisableSpecificWarnings>%(DisableSpecificWarnings);4946</DisableSpecificWarnings> <!-- reinterpret_cast used between related classes -->
			<DisableSpecificWarnings>%(DisableSpecificWarnings);5026</DisableSpecificWarnings> <!-- move constructor was implicitly defined as deleted -->
			<DisableSpecificWarnings>%(DisableSpecificWarnings);5027</DisableSpecificWarnings> <!-- move assignment operator was implicitly defined as deleted -->
			<DisableSpecificWarnings>%(DisableSpecificWarnings);5039</DisableSpecificWarnings> <!-- potentially throwing function passed to 'extern "C"' -->
			<DisableSpecificWarnings>%(DisableSpecificWarnings);5045</DisableSpecificWarnings> <!-- Compiler will insert Spectre mitigation -->
		</ClCompile>
	</ItemDefinitionGroup>
	<PropertyGroup>
		<LocalDebuggerWorkingDirectory>$(ProjectDir)..\</LocalDebuggerWorkingDirectory>
	</PropertyGroup>
	<ItemGroup>
		<ClCompile Include="..\conformance_burntsushi_invalid.cpp" />
		<ClCompile Include="..\conformance_burntsushi_valid.cpp" />
		<ClCompile Include="..\conformance_iarna_invalid.cpp" />
		<ClCompile Include="..\conformance_iarna_valid.cpp" />
		<ClCompile Include="..\impl_catch2.cpp">
			<PrecompiledHeader>NotUsing</PrecompiledHeader>
		</ClCompile>
		<ClCompile Include="..\impl_toml.cpp">
			<PrecompiledHeader>NotUsing</PrecompiledHeader>
		</ClCompile>
		<ClCompile Include="..\manipulating_arrays.cpp" />
		<ClCompile Include="..\manipulating_tables.cpp" />
		<ClCompile Include="..\manipulating_parse_result.cpp" />
		<ClCompile Include="..\manipulating_values.cpp" />
		<ClCompile Include="..\parsing_arrays.cpp" />
		<ClCompile Include="..\parsing_booleans.cpp" />
		<ClCompile Include="..\parsing_comments.cpp" />
		<ClCompile Include="..\parsing_dates_and_times.cpp" />
		<ClCompile Include="..\parsing_floats.cpp" />
		<ClCompile Include="..\parsing_integers.cpp" />
		<ClCompile Include="..\parsing_key_value_pairs.cpp" />
		<ClCompile Include="..\parsing_spec_example.cpp" />
		<ClCompile Include="..\parsing_strings.cpp" />
		<ClCompile Include="..\parsing_tables.cpp" />
		<ClCompile Include="..\tests.cpp">
			<PrecompiledHeader>Create</PrecompiledHeader>
		</ClCompile>
		<ClCompile Include="..\unicode.cpp" />
		<ClCompile Include="..\user_feedback.cpp" />
		<ClCompile Include="..\using_iterators.cpp" />
		<ClCompile Include="..\windows_compat.cpp" />
	</ItemGroup>
	<ItemGroup>
		<Natvis Include="..\..\toml++.natvis" />
	</ItemGroup>
	<ItemGroup>
		<ClInclude Include="..\catch2.h" />
		<ClInclude Include="..\leakproof.h" />
		<ClInclude Include="..\settings.h" />
		<ClInclude Include="..\tests.h" />
		<ClInclude Include="..\tloptional.h" />
	</ItemGroup>
	<ItemGroup>
		<None Include="..\cpp.hint" />
		<None Include="..\meson.build" />
	</ItemGroup>
	<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
			'''.strip().format(
				configuration=next(configuration_name(x) for x in mode if x in ('debug', 'release')),
				platform=next(platform_name(x) for x in mode if x in ('x64', 'x86')),
				uuid=str(uuid5(uuid_namespace, '_'.join(mode))).upper(),
				exceptions='false' if 'noexcept' in mode else 'Sync',
				unreleased_features=1 if 'unrel' in mode else 0,
				standard='cpplatest' if 'cpplatest' in mode else 'cpp17'
			))