codegen: Use - instead of stdout for output to stdout

In command-line tools, ordinary filenames normally do not have
special-cased meanings, so commit 3ef742eb "Don't skip dbus-codegen tests
on Win32" was a command-line API break: in the unlikely event that a
user wanted to write to a file named exactly `stdout`, this would have
been an incompatible change.

There is a conventional pseudo-filename to represent standard output,
which is `-` (for example `cat -` is a no-op filter). Adding support
for this is technically also a command-line API break (in the very
unlikely event that a user wants to write to a file named exactly `-`,
they would now have to write it as `./-`), but filenames starting with
a dash often require special treatment anyway, so this probably will not
come as a surprise to anyone.

When the output filename is `-` we don't want to use `#ifdef _____` as
a header guard, so special-case it as `__STDOUT__` as before.

Signed-off-by: Simon McVittie <smcv@collabora.com>
This commit is contained in:
Simon McVittie 2024-02-06 10:54:51 +00:00
parent 25e68476fa
commit 6a1fdb8145
3 changed files with 38 additions and 55 deletions

View File

@ -57,6 +57,9 @@ def generate_namespace(namespace):
def generate_header_guard(header_name): def generate_header_guard(header_name):
if header_name == "-":
return "STDOUT"
# There might be more characters that are safe to use than these, but lets # There might be more characters that are safe to use than these, but lets
# stay conservative. # stay conservative.
safe_valid_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" safe_valid_chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

View File

@ -66,7 +66,7 @@ def find_prop(iface, prop):
@contextmanager @contextmanager
def file_or_stdout(filename): def file_or_stdout(filename):
if filename is None or filename == "stdout": if filename is None or filename == "-":
yield sys.stdout yield sys.stdout
else: else:
with open(filename, "w") as outfile: with open(filename, "w") as outfile:

View File

@ -353,7 +353,7 @@ class TestCodegen(unittest.TestCase):
def test_empty_interface_header(self): def test_empty_interface_header(self):
"""Test generating a header with an empty interface file.""" """Test generating a header with an empty interface file."""
result = self.runCodegenWithInterface("", "--output", "stdout", "--header") result = self.runCodegenWithInterface("", "--output", "-", "--header")
self.assertEqual("", result.err) self.assertEqual("", result.err)
self.assertEqual( self.assertEqual(
"""{standard_top_comment} """{standard_top_comment}
@ -376,14 +376,14 @@ G_END_DECLS
def test_empty_interface_body(self): def test_empty_interface_body(self):
"""Test generating a body with an empty interface file.""" """Test generating a body with an empty interface file."""
result = self.runCodegenWithInterface("", "--output", "stdout", "--body") result = self.runCodegenWithInterface("", "--output", "-", "--body")
self.assertEqual("", result.err) self.assertEqual("", result.err)
self.assertEqual( self.assertEqual(
"""{standard_top_comment} """{standard_top_comment}
{standard_config_h_include} {standard_config_h_include}
#include "stdout.h" #include "-.h"
{standard_header_includes} {standard_header_includes}
@ -437,7 +437,7 @@ G_END_DECLS
xml_file1.name, xml_file1.name,
xml_file2.name, xml_file2.name,
"--output", "--output",
"stdout", "-",
header_or_body, header_or_body,
) )
self.assertEqual("", result1.err) self.assertEqual("", result1.err)
@ -446,7 +446,7 @@ G_END_DECLS
xml_file2.name, xml_file2.name,
xml_file1.name, xml_file1.name,
"--output", "--output",
"stdout", "-",
header_or_body, header_or_body,
) )
self.assertEqual("", result2.err) self.assertEqual("", result2.err)
@ -652,7 +652,7 @@ G_END_DECLS
self.runCodegenWithInterface( self.runCodegenWithInterface(
"", "",
"--output", "--output",
"stdout", "-",
"--body", "--body",
"--glib-min-required", "--glib-min-required",
"hello mum", "hello mum",
@ -663,7 +663,7 @@ G_END_DECLS
probably a typo).""" probably a typo)."""
with self.assertRaises(subprocess.CalledProcessError): with self.assertRaises(subprocess.CalledProcessError):
self.runCodegenWithInterface( self.runCodegenWithInterface(
"", "--output", "stdout", "--body", "--glib-min-required", "2.6" "", "--output", "-", "--body", "--glib-min-required", "2.6"
) )
def test_glib_min_required_major_only(self): def test_glib_min_required_major_only(self):
@ -671,7 +671,7 @@ G_END_DECLS
result = self.runCodegenWithInterface( result = self.runCodegenWithInterface(
"", "",
"--output", "--output",
"stdout", "-",
"--header", "--header",
"--glib-min-required", "--glib-min-required",
"3", "3",
@ -684,7 +684,7 @@ G_END_DECLS
def test_glib_min_required_with_micro(self): def test_glib_min_required_with_micro(self):
"""Test running with a --glib-min-required which contains a micro version.""" """Test running with a --glib-min-required which contains a micro version."""
result = self.runCodegenWithInterface( result = self.runCodegenWithInterface(
"", "--output", "stdout", "--header", "--glib-min-required", "2.46.2" "", "--output", "-", "--header", "--glib-min-required", "2.46.2"
) )
self.assertEqual("", result.err) self.assertEqual("", result.err)
self.assertNotEqual("", result.out.strip()) self.assertNotEqual("", result.out.strip())
@ -694,13 +694,13 @@ G_END_DECLS
probably a typo).""" probably a typo)."""
with self.assertRaises(subprocess.CalledProcessError): with self.assertRaises(subprocess.CalledProcessError):
self.runCodegenWithInterface( self.runCodegenWithInterface(
"", "--output", "stdout", "--body", "--glib-max-allowed", "2.6" "", "--output", "-", "--body", "--glib-max-allowed", "2.6"
) )
def test_glib_max_allowed_major_only(self): def test_glib_max_allowed_major_only(self):
"""Test running with a --glib-max-allowed which contains only a major version.""" """Test running with a --glib-max-allowed which contains only a major version."""
result = self.runCodegenWithInterface( result = self.runCodegenWithInterface(
"", "--output", "stdout", "--header", "--glib-max-allowed", "3" "", "--output", "-", "--header", "--glib-max-allowed", "3"
) )
self.assertEqual("", result.err) self.assertEqual("", result.err)
self.assertNotEqual("", result.out.strip()) self.assertNotEqual("", result.out.strip())
@ -708,7 +708,7 @@ G_END_DECLS
def test_glib_max_allowed_with_micro(self): def test_glib_max_allowed_with_micro(self):
"""Test running with a --glib-max-allowed which contains a micro version.""" """Test running with a --glib-max-allowed which contains a micro version."""
result = self.runCodegenWithInterface( result = self.runCodegenWithInterface(
"", "--output", "stdout", "--header", "--glib-max-allowed", "2.46.2" "", "--output", "-", "--header", "--glib-max-allowed", "2.46.2"
) )
self.assertEqual("", result.err) self.assertEqual("", result.err)
self.assertNotEqual("", result.out.strip()) self.assertNotEqual("", result.out.strip())
@ -720,7 +720,7 @@ G_END_DECLS
result = self.runCodegenWithInterface( result = self.runCodegenWithInterface(
"", "",
"--output", "--output",
"stdout", "-",
"--header", "--header",
"--glib-max-allowed", "--glib-max-allowed",
"2.63", "2.63",
@ -737,7 +737,7 @@ G_END_DECLS
self.runCodegenWithInterface( self.runCodegenWithInterface(
"", "",
"--output", "--output",
"stdout", "-",
"--body", "--body",
"--glib-max-allowed", "--glib-max-allowed",
"2.62", "2.62",
@ -780,9 +780,7 @@ G_END_DECLS
</interface> </interface>
</node>""" </node>"""
with self.assertRaises(subprocess.CalledProcessError): with self.assertRaises(subprocess.CalledProcessError):
self.runCodegenWithInterface( self.runCodegenWithInterface(interface_xml, "--output", "-", "--body")
interface_xml, "--output", "stdout", "--body"
)
good_types = [ good_types = [
"si{s{b(ybnqiuxtdh)}}{yv}{nv}{dv}", "si{s{b(ybnqiuxtdh)}}{yv}{nv}{dv}",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
@ -798,7 +796,7 @@ G_END_DECLS
</interface> </interface>
</node>""" </node>"""
result = self.runCodegenWithInterface( result = self.runCodegenWithInterface(
interface_xml, "--output", "stdout", "--body" interface_xml, "--output", "-", "--body"
) )
self.assertEqual("", result.err) self.assertEqual("", result.err)
@ -829,7 +827,7 @@ G_END_DECLS
# Try without specifying --glib-min-required. # Try without specifying --glib-min-required.
result = self.runCodegenWithInterface( result = self.runCodegenWithInterface(
interface_xml, "--output", "stdout", "--header" interface_xml, "--output", "-", "--header"
) )
self.assertEqual("", result.err) self.assertEqual("", result.err)
self.assertEqual(result.out.strip().count("GUnixFDList"), 6) self.assertEqual(result.out.strip().count("GUnixFDList"), 6)
@ -838,7 +836,7 @@ G_END_DECLS
result = self.runCodegenWithInterface( result = self.runCodegenWithInterface(
interface_xml, interface_xml,
"--output", "--output",
"stdout", "-",
"--header", "--header",
"--glib-min-required", "--glib-min-required",
"2.32", "2.32",
@ -852,7 +850,7 @@ G_END_DECLS
result = self.runCodegenWithInterface( result = self.runCodegenWithInterface(
interface_xml, interface_xml,
"--output", "--output",
"stdout", "-",
"--header", "--header",
"--glib-min-required", "--glib-min-required",
"2.64", "2.64",
@ -873,7 +871,7 @@ G_END_DECLS
# Try without specifying --glib-min-required. # Try without specifying --glib-min-required.
result = self.runCodegenWithInterface( result = self.runCodegenWithInterface(
interface_xml, "--output", "stdout", "--header" interface_xml, "--output", "-", "--header"
) )
self.assertEqual("", result.err) self.assertEqual("", result.err)
self.assertEqual(result.out.strip().count("GDBusCallFlags call_flags,"), 0) self.assertEqual(result.out.strip().count("GDBusCallFlags call_flags,"), 0)
@ -883,7 +881,7 @@ G_END_DECLS
result = self.runCodegenWithInterface( result = self.runCodegenWithInterface(
interface_xml, interface_xml,
"--output", "--output",
"stdout", "-",
"--header", "--header",
"--glib-min-required", "--glib-min-required",
"2.32", "2.32",
@ -897,7 +895,7 @@ G_END_DECLS
result = self.runCodegenWithInterface( result = self.runCodegenWithInterface(
interface_xml, interface_xml,
"--output", "--output",
"stdout", "-",
"--header", "--header",
"--glib-min-required", "--glib-min-required",
"2.64", "2.64",
@ -918,9 +916,7 @@ G_END_DECLS
</interface> </interface>
</node>""" </node>"""
result = self.runCodegenWithInterface( result = self.runCodegenWithInterface(interface_xml, "--output", "-", "--body")
interface_xml, "--output", "stdout", "--body"
)
stripped_out = result.out.strip() stripped_out = result.out.strip()
self.assertFalse(result.err) self.assertFalse(result.err)
self.assertIs(stripped_out.count("g_signal_emit_by_name ("), 0) self.assertIs(stripped_out.count("g_signal_emit_by_name ("), 0)
@ -956,9 +952,7 @@ G_END_DECLS
</interface> </interface>
</node>""" </node>"""
result = self.runCodegenWithInterface( result = self.runCodegenWithInterface(interface_xml, "--output", "-", "--body")
interface_xml, "--output", "stdout", "--body"
)
stripped_out = result.out.strip() stripped_out = result.out.strip()
self.assertFalse(result.err) self.assertFalse(result.err)
self.assertIs(stripped_out.count("g_signal_emit_by_name ("), 0) self.assertIs(stripped_out.count("g_signal_emit_by_name ("), 0)
@ -993,9 +987,7 @@ G_END_DECLS
</interface> </interface>
</node>""" </node>"""
result = self.runCodegenWithInterface( result = self.runCodegenWithInterface(interface_xml, "--output", "-", "--body")
interface_xml, "--output", "stdout", "--body"
)
stripped_out = result.out.strip() stripped_out = result.out.strip()
self.assertFalse(result.err) self.assertFalse(result.err)
self.assertIs(stripped_out.count("g_signal_emit_by_name ("), 0) self.assertIs(stripped_out.count("g_signal_emit_by_name ("), 0)
@ -1026,9 +1018,7 @@ G_END_DECLS
</interface> </interface>
</node>""" </node>"""
result = self.runCodegenWithInterface( result = self.runCodegenWithInterface(interface_xml, "--output", "-", "--body")
interface_xml, "--output", "stdout", "--body"
)
stripped_out = result.out.strip() stripped_out = result.out.strip()
self.assertFalse(result.err) self.assertFalse(result.err)
self.assertIs(stripped_out.count("g_cclosure_marshal_generic"), 0) self.assertIs(stripped_out.count("g_cclosure_marshal_generic"), 0)
@ -1058,7 +1048,7 @@ G_END_DECLS
</node>""" </node>"""
result = self.runCodegenWithInterface( result = self.runCodegenWithInterface(
interface_xml, "--output", "stdout", "--body" interface_xml, "--output", "-", "--body"
) )
stripped_out = result.out.strip() stripped_out = result.out.strip()
self.assertFalse(result.err) self.assertFalse(result.err)
@ -1106,9 +1096,7 @@ G_END_DECLS
</interface> </interface>
</node>""" </node>"""
result = self.runCodegenWithInterface( result = self.runCodegenWithInterface(interface_xml, "--output", "-", "--body")
interface_xml, "--output", "stdout", "--body"
)
stripped_out = result.out.strip() stripped_out = result.out.strip()
self.assertFalse(result.err) self.assertFalse(result.err)
self.assertIs(stripped_out.count("g_cclosure_marshal_generic"), 0) self.assertIs(stripped_out.count("g_cclosure_marshal_generic"), 0)
@ -1144,9 +1132,7 @@ G_END_DECLS
</interface> </interface>
</node>""" </node>"""
result = self.runCodegenWithInterface( result = self.runCodegenWithInterface(interface_xml, "--output", "-", "--body")
interface_xml, "--output", "stdout", "--body"
)
stripped_out = result.out.strip() stripped_out = result.out.strip()
self.assertFalse(result.err) self.assertFalse(result.err)
self.assertIs(stripped_out.count("g_cclosure_marshal_generic"), 0) self.assertIs(stripped_out.count("g_cclosure_marshal_generic"), 0)
@ -1190,7 +1176,7 @@ G_END_DECLS
</node>""" </node>"""
result = self.runCodegenWithInterface( result = self.runCodegenWithInterface(
interface_xml, "--output", "stdout", "--body" interface_xml, "--output", "-", "--body"
) )
stripped_out = result.out.strip() stripped_out = result.out.strip()
self.assertFalse(result.err) self.assertFalse(result.err)
@ -1228,7 +1214,7 @@ G_END_DECLS
</node>""" </node>"""
result = self.runCodegenWithInterface( result = self.runCodegenWithInterface(
interface_xml, "--output", "stdout", "--body" interface_xml, "--output", "-", "--body"
) )
stripped_out = result.out.strip() stripped_out = result.out.strip()
self.assertFalse(result.err) self.assertFalse(result.err)
@ -1271,9 +1257,7 @@ G_END_DECLS
</interface> </interface>
</node>""" </node>"""
result = self.runCodegenWithInterface( result = self.runCodegenWithInterface(interface_xml, "--output", "-", "--body")
interface_xml, "--output", "stdout", "--body"
)
stripped_out = result.out.strip() stripped_out = result.out.strip()
self.assertFalse(result.err) self.assertFalse(result.err)
self.assertIs(stripped_out.count("g_cclosure_marshal_generic"), 0) self.assertIs(stripped_out.count("g_cclosure_marshal_generic"), 0)
@ -1331,9 +1315,7 @@ G_END_DECLS
</interface> </interface>
</node>""" </node>"""
result = self.runCodegenWithInterface( result = self.runCodegenWithInterface(interface_xml, "--output", "-", "--body")
interface_xml, "--output", "stdout", "--body"
)
stripped_out = result.out.strip() stripped_out = result.out.strip()
self.assertFalse(result.err) self.assertFalse(result.err)
self.assertIs(stripped_out.count("g_cclosure_marshal_generic"), 0) self.assertIs(stripped_out.count("g_cclosure_marshal_generic"), 0)
@ -1375,9 +1357,7 @@ G_END_DECLS
</interface> </interface>
</node>""" </node>"""
result = self.runCodegenWithInterface( result = self.runCodegenWithInterface(interface_xml, "--output", "-", "--body")
interface_xml, "--output", "stdout", "--body"
)
stripped_out = result.out.strip() stripped_out = result.out.strip()
self.assertFalse(result.err) self.assertFalse(result.err)
self.assertIs(stripped_out.count("g_cclosure_marshal_generic"), 0) self.assertIs(stripped_out.count("g_cclosure_marshal_generic"), 0)