Skip to content

Commit

Permalink
glib-mkenums: Support reading @rspfiles for arguments
Browse files Browse the repository at this point in the history
This is needed on Windows where the argument list can exceed the
maximum command-line length when lots of sources are passed to
glib-mkenums.
  • Loading branch information
nirbheek committed Dec 4, 2018
1 parent d4cc0b3 commit 17316b2
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 3 deletions.
9 changes: 9 additions & 0 deletions docs/reference/gobject/glib-mkenums.xml
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,15 @@ Write output to FILE instead of stdout.
</para></listitem>
</varlistentry>

<varlistentry>
<term><option>@RSPFILE</option></term>
<listitem><para>
When passed as the sole argument, read and parse the actual arguments from
<literal>RSPFILE</literal>. Useful on systems with a low command-line length
limit. For example, Windows has a limit of 8191 characters.
</para></listitem>
</varlistentry>

</variablelist>
</refsect1>

Expand Down
35 changes: 33 additions & 2 deletions gobject/glib-mkenums.in
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,29 @@ def print_info(msg):
print_color(msg, color=Color.GREEN, prefix='INFO')


def get_rspfile_args(rspfile):
'''
Response files are useful on Windows where there is a command-line character
limit of 8191 because when passing sources as arguments to glib-mkenums this
limit can be exceeded in large codebases.

There is no specification for response files and each tool that supports it
generally writes them out in slightly different ways, but some sources are:
https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-response-files
https://docs.microsoft.com/en-us/windows/desktop/midl/the-response-file-command
'''
import shlex
if not os.path.isfile(rspfile):
sys.exit('Response file {!r} does not exist'.format(rspfile))
try:
with open(rspfile, 'r') as f:
cmdline = f.read()
except OSError as e:
sys.exit('Response file {!r} could not be read: {}'
.format(rspfile, e.strerror))
return shlex.split(cmdline)


def write_output(output):
global output_stream
print(output, file=output_stream)
Expand Down Expand Up @@ -326,9 +349,17 @@ parser.add_argument('--output', default=None, dest='output')
parser.add_argument('--version', '-v', default=False, action='store_true', dest='version',
help='Print version information')
parser.add_argument('args', nargs='*',
help='Input files')
help='One or more input files, or a single argument @rspfile_path '
'pointing to a file that contains the actual arguments')

# Support reading an rspfile of the form @filename which contains the args
# to be parsed
if len(sys.argv) == 2 and sys.argv[1].startswith('@'):
args = get_rspfile_args(sys.argv[1][1:])
else:
args = sys.argv[1:]

options = parser.parse_args()
options = parser.parse_args(args)

if options.version:
print(VERSION_STR)
Expand Down
21 changes: 20 additions & 1 deletion gobject/tests/mkenums.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class TestMkenums(unittest.TestCase):
parsing and generation code out into a library and unit test that, and
convert this test to just check command line behaviour.
"""
rspfile = False

def setUp(self):
self.timeout_seconds = 10 # seconds per test
Expand All @@ -57,12 +58,25 @@ def setUp(self):
'glib-mkenums')
else:
self.__mkenums = os.path.join('/', 'usr', 'bin', 'glib-mkenums')
print('mkenums:', self.__mkenums)
print('rspfile: {}, mkenums:'.format(self.rspfile), self.__mkenums)

def tearDown(self):
self.tmpdir.cleanup()

def _write_rspfile(self, argv):
import shlex
with tempfile.NamedTemporaryFile(dir=self.tmpdir.name, mode='w',
delete=False) as f:
contents = ' '.join([shlex.quote(arg) for arg in argv])
print('Response file contains:', contents)
f.write(contents)
f.flush()
return f.name

def runMkenums(self, *args):
if self.rspfile:
rspfile = self._write_rspfile(args)
args = ['@' + rspfile]
argv = [self.__mkenums]
argv.extend(args)
print('Running:', argv)
Expand Down Expand Up @@ -448,5 +462,10 @@ def test_filename_basename_in_fhead_ftail(self):
'''.format(**result.subs).strip(), result.out)


class TestRspMkenums(TestMkenums):
'''Run all tests again in @rspfile mode'''
rspfile = True


if __name__ == '__main__':
unittest.main(testRunner=taptestrunner.TAPTestRunner())

0 comments on commit 17316b2

Please sign in to comment.