diff --git a/gobject/glib-mkenums.in b/gobject/glib-mkenums.in index de05232ce..985edd2f7 100755 --- a/gobject/glib-mkenums.in +++ b/gobject/glib-mkenums.in @@ -303,15 +303,15 @@ parser = argparse.ArgumentParser(epilog=help_epilog, parser.add_argument('--identifier-prefix', default='', dest='idprefix', help='Identifier prefix') parser.add_argument('--symbol-prefix', default='', dest='symprefix', - help='symbol-prefix') + help='Symbol prefix') parser.add_argument('--fhead', default=[], dest='fhead', action='append', help='Output file header') parser.add_argument('--ftail', default=[], dest='ftail', action='append', - help='Per input file production') + help='Output file footer') parser.add_argument('--fprod', default=[], dest='fprod', action='append', - help='Put out TEXT everytime a new input file is being processed.') + help='Put out TEXT every time a new input file is being processed.') parser.add_argument('--eprod', default=[], dest='eprod', action='append', - help='Per enum text (produced prior to value iterations)') + help='Per enum text, produced prior to value iterations') parser.add_argument('--vhead', default=[], dest='vhead', action='append', help='Value header, produced before iterating over enum values') parser.add_argument('--vprod', default=[], dest='vprod', action='append', @@ -324,8 +324,9 @@ parser.add_argument('--template', default='', dest='template', help='Template file') parser.add_argument('--output', default=None, dest='output') parser.add_argument('--version', '-v', default=False, action='store_true', dest='version', - help='Print version informations') -parser.add_argument('args', nargs='*') + help='Print version information') +parser.add_argument('args', nargs='*', + help='Input files') options = parser.parse_args() @@ -415,12 +416,17 @@ def replace_specials(prod): prod = prod.rstrip() return prod + +def warn_if_filename_basename_used(section, prod): + for substitution in ('\u0040filename\u0040', + '\u0040basename\u0040'): + if substitution in prod: + print_warning('{} used in {} section.'.format(substitution, + section)) + if len(fhead) > 0: prod = fhead - base = os.path.basename(options.args[0]) - - prod = prod.replace('\u0040filename\u0040', options.args[0]) - prod = prod.replace('\u0040basename\u0040', base) + warn_if_filename_basename_used('file-header', prod) prod = replace_specials(prod) write_output(prod) @@ -712,10 +718,7 @@ for fname in sorted(options.args): if len(ftail) > 0: prod = ftail - base = os.path.basename(options.args[-1]) # FIXME, wrong - - prod = prod.replace('\u0040filename\u0040', 'ARGV') # wrong too - prod = prod.replace('\u0040basename\u0040', base) + warn_if_filename_basename_used('file-tail', prod) prod = replace_specials(prod) write_output(prod) diff --git a/gobject/tests/mkenums.py b/gobject/tests/mkenums.py index 431453d01..bb5443394 100644 --- a/gobject/tests/mkenums.py +++ b/gobject/tests/mkenums.py @@ -20,14 +20,19 @@ """Integration tests for glib-mkenums utility.""" +import collections import os import subprocess import tempfile +import textwrap import unittest import taptestrunner +Result = collections.namedtuple('Result', ('info', 'out', 'err', 'subs')) + + class TestMkenums(unittest.TestCase): """Integration test for running glib-mkenums. @@ -70,15 +75,40 @@ class TestMkenums(unittest.TestCase): stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) - print('Output:', info.stdout.decode('utf-8')) - return info + info.check_returncode() + out = info.stdout.decode('utf-8').strip() + err = info.stderr.decode('utf-8').strip() - def runMkenumsWithHeader(self, h_contents, encoding='utf-8', *args): + # Known substitutions for standard boilerplate + subs = { + 'standard_top_comment': + 'This file is generated by glib-mkenums, do not modify ' + 'it. This code is licensed under the same license as the ' + 'containing project. Note that it links to GLib, so must ' + 'comply with the LGPL linking clauses.', + 'standard_bottom_comment': 'Generated data ends here' + } + + result = Result(info, out, err, subs) + + print('Output:', result.out) + return result + + def runMkenumsWithTemplate(self, template_contents, *args): + with tempfile.NamedTemporaryFile(dir=self.tmpdir.name, + suffix='.template') as template_file: + # Write out the template. + template_file.write(template_contents.encode('utf-8')) + print(template_file.name + ':', template_contents) + template_file.flush() + + return self.runMkenums('--template', template_file.name, *args) + + def runMkenumsWithAllSubstitutions(self, *args): + '''Run glib-mkenums with a template which outputs all substitutions.''' template_contents = ''' /*** BEGIN file-header ***/ file-header -filename: @filename@ -basename: @basename@ /*** END file-header ***/ /*** BEGIN file-production ***/ @@ -140,48 +170,30 @@ comment: @comment@ /*** BEGIN file-tail ***/ file-tail -filename: @filename@ -basename: @basename@ /*** END file-tail ***/ ''' + return self.runMkenumsWithTemplate(template_contents, *args) + def runMkenumsWithHeader(self, h_contents, encoding='utf-8'): with tempfile.NamedTemporaryFile(dir=self.tmpdir.name, - suffix='.template') as template_file, \ - tempfile.NamedTemporaryFile(dir=self.tmpdir.name, suffix='.h') as h_file: - # Write out the template. - template_file.write(template_contents.encode('utf-8')) - print(template_file.name + ':', template_contents) - # Write out the header to be scanned. h_file.write(h_contents.encode(encoding)) print(h_file.name + ':', h_contents) - - template_file.flush() h_file.flush() # Run glib-mkenums with a template which outputs all substitutions. - info = self.runMkenums('--template', template_file.name, - h_file.name) - info.check_returncode() - out = info.stdout.decode('utf-8').strip() - err = info.stderr.decode('utf-8').strip() + result = self.runMkenumsWithAllSubstitutions(h_file.name) # Known substitutions for generated filenames. - subs = { + result.subs.update({ 'filename': h_file.name, 'basename': os.path.basename(h_file.name), - 'standard_top_comment': - 'This file is generated by glib-mkenums, do not modify ' - 'it. This code is licensed under the same license as the ' - 'containing project. Note that it links to GLib, so must ' - 'comply with the LGPL linking clauses.', - 'standard_bottom_comment': 'Generated data ends here' - } + }) - return (info, out, err, subs) + return result - def assertSingleEnum(self, out, subs, enum_name_camel, enum_name_lower, + def assertSingleEnum(self, result, enum_name_camel, enum_name_lower, enum_name_upper, enum_name_short, enum_prefix, type_lower, type_camel, type_upper, value_name, value_nick, value_num): @@ -199,7 +211,7 @@ basename: @basename@ 'value_name': value_name, 'value_nick': value_nick, 'value_num': value_num, - }, **subs) + }, **result.subs) self.assertEqual(''' comment @@ -207,8 +219,6 @@ comment: {standard_top_comment} file-header -filename: {filename} -basename: {basename} file-production filename: {filename} basename: {basename} @@ -247,40 +257,67 @@ type: {type_lower} Type: {type_camel} TYPE: {type_upper} file-tail -filename: ARGV -basename: {basename} comment comment: {standard_bottom_comment} -'''.format(**subs).strip(), out) +'''.format(**subs).strip(), result.out) def test_help(self): """Test the --help argument.""" - info = self.runMkenums('--help') - info.check_returncode() + result = self.runMkenums('--help') + self.assertIn('usage: glib-mkenums', result.out) - out = info.stdout.decode('utf-8').strip() - self.assertIn('usage: glib-mkenums', out) + def test_no_args(self): + """Test running with no arguments at all.""" + result = self.runMkenums() + self.assertEqual('', result.err) + self.assertEquals('''/* {standard_top_comment} */ + + +/* {standard_bottom_comment} */'''.format(**result.subs), + result.out.strip()) + + def test_empty_template(self): + """Test running with an empty template and no header files.""" + result = self.runMkenumsWithTemplate('') + self.assertEqual('', result.err) + self.assertEquals('''/* {standard_top_comment} */ + + +/* {standard_bottom_comment} */'''.format(**result.subs), + result.out.strip()) + + def test_no_headers(self): + """Test running with a complete template, but no header files.""" + result = self.runMkenumsWithAllSubstitutions() + self.assertEqual('', result.err) + self.assertEquals(''' +comment +comment: {standard_top_comment} + + +file-header +file-tail + +comment +comment: {standard_bottom_comment} +'''.format(**result.subs).strip(), result.out) def test_empty_header(self): """Test an empty header.""" - (info, out, err, subs) = self.runMkenumsWithHeader('') - self.assertEqual('', err) + result = self.runMkenumsWithHeader('') + self.assertEqual('', result.err) self.assertEqual(''' comment comment: {standard_top_comment} file-header -filename: {filename} -basename: {basename} file-tail -filename: ARGV -basename: {basename} comment comment: {standard_bottom_comment} -'''.format(**subs).strip(), out) +'''.format(**result.subs).strip(), result.out) def test_enum_name(self): """Test typedefs with an enum and a typedef name. Bug #794506.""" @@ -289,9 +326,9 @@ comment: {standard_bottom_comment} ENUM_VALUE } SomeEnumIdentifier; ''' - (info, out, err, subs) = self.runMkenumsWithHeader(h_contents) - self.assertEqual('', err) - self.assertSingleEnum(out, subs, 'SomeEnumIdentifier', + result = self.runMkenumsWithHeader(h_contents) + self.assertEqual('', result.err) + self.assertSingleEnum(result, 'SomeEnumIdentifier', 'some_enum_identifier', 'SOME_ENUM_IDENTIFIER', 'ENUM_IDENTIFIER', 'SOME', 'enum', 'Enum', 'ENUM', 'ENUM_VALUE', 'value', '0') @@ -304,10 +341,9 @@ comment: {standard_bottom_comment} ENUM_VALUE } SomeEnumIdentifier; ''' - (info, out, err, subs) = \ - self.runMkenumsWithHeader(h_contents, encoding='iso-8859-1') - self.assertIn('WARNING: UnicodeWarning: ', err) - self.assertSingleEnum(out, subs, 'SomeEnumIdentifier', + result = self.runMkenumsWithHeader(h_contents, encoding='iso-8859-1') + self.assertIn('WARNING: UnicodeWarning: ', result.err) + self.assertSingleEnum(result, 'SomeEnumIdentifier', 'some_enum_identifier', 'SOME_ENUM_IDENTIFIER', 'ENUM_IDENTIFIER', 'SOME', 'enum', 'Enum', 'ENUM', 'ENUM_VALUE', 'value', '0') @@ -315,6 +351,8 @@ comment: {standard_bottom_comment} def test_reproducible(self): """Test builds are reproducible regardless of file ordering. Bug #691436.""" + template_contents = 'template' + h_contents1 = ''' typedef enum { FIRST, @@ -328,36 +366,28 @@ comment: {standard_bottom_comment} ''' with tempfile.NamedTemporaryFile(dir=self.tmpdir.name, - suffix='.template') as template_file, \ - tempfile.NamedTemporaryFile(dir=self.tmpdir.name, suffix='1.h') as h_file1, \ - tempfile.NamedTemporaryFile(dir=self.tmpdir.name, - suffix='2.h') as h_file2: - # Write out the template and headers. - template_file.write('template'.encode('utf-8')) + tempfile.NamedTemporaryFile(dir=self.tmpdir.name, + suffix='2.h') as h_file2: + # Write out the headers. h_file1.write(h_contents1.encode('utf-8')) h_file2.write(h_contents2.encode('utf-8')) - template_file.flush() h_file1.flush() h_file2.flush() # Run glib-mkenums with the headers in one order, and then again # in another order. - info1 = self.runMkenums('--template', template_file.name, - h_file1.name, h_file2.name) - info1.check_returncode() - out1 = info1.stdout.decode('utf-8').strip() - self.assertEqual('', info1.stderr.decode('utf-8').strip()) + result1 = self.runMkenumsWithTemplate(template_contents, + h_file1.name, h_file2.name) + self.assertEqual('', result1.err) - info2 = self.runMkenums('--template', template_file.name, - h_file2.name, h_file1.name) - info2.check_returncode() - out2 = info2.stdout.decode('utf-8').strip() - self.assertEqual('', info2.stderr.decode('utf-8').strip()) + result2 = self.runMkenumsWithTemplate(template_contents, + h_file2.name, h_file1.name) + self.assertEqual('', result2.err) # The output should be the same. - self.assertEqual(out1, out2) + self.assertEqual(result1.out, result2.out) def test_no_nick(self): """Test trigraphs with a desc but no nick. Issue #1360.""" @@ -366,13 +396,57 @@ comment: {standard_bottom_comment} GEGL_SAMPLER_NEAREST = 0, /*< desc="nearest" >*/ } GeglSamplerType; ''' - (info, out, err, subs) = self.runMkenumsWithHeader(h_contents) - self.assertEqual('', err) - self.assertSingleEnum(out, subs, 'GeglSamplerType', + result = self.runMkenumsWithHeader(h_contents) + self.assertEqual('', result.err) + self.assertSingleEnum(result, 'GeglSamplerType', 'gegl_sampler_type', 'GEGL_SAMPLER_TYPE', 'SAMPLER_TYPE', 'GEGL', 'enum', 'Enum', 'ENUM', 'GEGL_SAMPLER_NEAREST', 'nearest', '0') + def test_filename_basename_in_fhead_ftail(self): + template_contents = ''' +/*** BEGIN file-header ***/ +file-header +filename: @filename@ +basename: @basename@ +/*** END file-header ***/ + +/*** BEGIN comment ***/ +comment +comment: @comment@ +/*** END comment ***/ + +/*** BEGIN file-tail ***/ +file-tail +filename: @filename@ +basename: @basename@ +/*** END file-tail ***/''' + result = self.runMkenumsWithTemplate(template_contents) + self.assertEqual( + textwrap.dedent( + ''' + WARNING: @filename@ used in file-header section. + WARNING: @basename@ used in file-header section. + WARNING: @filename@ used in file-tail section. + WARNING: @basename@ used in file-tail section. + ''').strip(), + result.err) + self.assertEqual(''' +comment +comment: {standard_top_comment} + + +file-header +filename: @filename@ +basename: @basename@ +file-tail +filename: @filename@ +basename: @basename@ + +comment +comment: {standard_bottom_comment} +'''.format(**result.subs).strip(), result.out) + if __name__ == '__main__': unittest.main(testRunner=taptestrunner.TAPTestRunner())