[glib: 1/2] glib-mkenums: Support reading @rspfiles for arguments



commit 17316b2c16cf17ae9692ed2733f776f1082e74e5
Author: Nirbheek Chauhan <nirbheek centricular com>
Date:   Tue Nov 20 14:25:23 2018 +0530

    glib-mkenums: Support reading @rspfiles for arguments
    
    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.

 docs/reference/gobject/glib-mkenums.xml |  9 +++++++++
 gobject/glib-mkenums.in                 | 35 +++++++++++++++++++++++++++++++--
 gobject/tests/mkenums.py                | 21 +++++++++++++++++++-
 3 files changed, 62 insertions(+), 3 deletions(-)
---
diff --git a/docs/reference/gobject/glib-mkenums.xml b/docs/reference/gobject/glib-mkenums.xml
index 2573bb3e9..84023e9b1 100644
--- a/docs/reference/gobject/glib-mkenums.xml
+++ b/docs/reference/gobject/glib-mkenums.xml
@@ -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>
 
diff --git a/gobject/glib-mkenums.in b/gobject/glib-mkenums.in
index 985edd2f7..91ad77942 100755
--- a/gobject/glib-mkenums.in
+++ b/gobject/glib-mkenums.in
@@ -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)
@@ -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)
diff --git a/gobject/tests/mkenums.py b/gobject/tests/mkenums.py
index bb5443394..d18536b13 100644
--- a/gobject/tests/mkenums.py
+++ b/gobject/tests/mkenums.py
@@ -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
@@ -57,12 +58,25 @@ class TestMkenums(unittest.TestCase):
                              '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)
@@ -448,5 +462,10 @@ comment: {standard_bottom_comment}
 '''.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())


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]