util/gen_xmlpool: Don't write via shell redirection
authorDylan Baker <dylan@pnwbakers.com>
Wed, 24 Oct 2018 19:20:48 +0000 (12:20 -0700)
committerDylan Baker <dylan@pnwbakers.com>
Wed, 31 Oct 2018 23:37:46 +0000 (16:37 -0700)
Using shell redirection to write to a file is more complicated than
necessary, and has the potential to run into unicode encoding problems.
It's also less code.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=108530

v2: - update commit message to say less about LANG=C
    - use flags instead of positional arguments for the script (Emil)

Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
src/util/Android.mk
src/util/xmlpool/Makefile.am
src/util/xmlpool/SConscript
src/util/xmlpool/gen_xmlpool.py
src/util/xmlpool/meson.build

index 993a7f179f4ff629ee2c8b6c97033d00aaaddbaa..2d59e1ae15e8fbc6535bfeb98588504c27fcefac 100644 (file)
@@ -101,8 +101,11 @@ $(UTIL_GENERATED_SOURCES): PRIVATE_CUSTOM_TOOL = $(PRIVATE_PYTHON) $^ > $@
 $(UTIL_GENERATED_SOURCES): $(intermediates)/%.c: $(LOCAL_PATH)/%.py
        $(transform-generated-source)
 
-$(MESA_DRI_OPTIONS_H): PRIVATE_CUSTOM_TOOL = $(PRIVATE_PYTHON) $< $(PRIVATE_TEMPLATE_HEADER) \
-               $(PRIVATE_LOCALEDIR) $(MESA_DRI_OPTIONS_LANGS) > $@
+$(MESA_DRI_OPTIONS_H): PRIVATE_CUSTOM_TOOL = $(PRIVATE_PYTHON) $< \
+               --template $(PRIVATE_TEMPLATE_HEADER) \
+               --output $@ \
+               --localedir $(PRIVATE_LOCALEDIR) \
+               --languages $(MESA_DRI_OPTIONS_LANGS)
 $(MESA_DRI_OPTIONS_H): $(PRIVATE_SCRIPT) $(PRIVATE_TEMPLATE_HEADER) $(PRIVATE_MO_FILES)
        $(transform-generated-source)
 
index f993070ef67b5210c2bec6725735873c4a27b9d1..2b01391401b1081db3e8a244d23a82b4cc6bb527 100644 (file)
@@ -75,7 +75,11 @@ clean-local:
 # Default target options.h
 LOCALEDIR := .
 options.h: t_options.h $(MOS)
-       $(AM_V_GEN) $(PYTHON) $(PYTHON_FLAGS) $(srcdir)/gen_xmlpool.py $(srcdir)/t_options.h $(LOCALEDIR) $(LANGS) > options.h
+       $(AM_V_GEN) $(PYTHON) $(PYTHON_FLAGS) $(srcdir)/gen_xmlpool.py \
+       --template $(srcdir)/t_options.h \
+       --output options.h \
+       --localedir $(LOCALEDIR) \
+       --languages $(LANGS)
 
 # Update .mo files from the corresponding .po files.
 %.gmo: %.po
index fa42554d3a5a7582473cc6376e6ea28fbadcefb1..0a00cefa655619c89b6ac657f1d2e85dc8ff8fd5 100644 (file)
@@ -8,7 +8,7 @@ xmlpool_options, = env.CodeGenerate(
     target = 'options.h',
     script = 'gen_xmlpool.py',
     source = ['t_options.h'],
-    command = python_cmd + ' $SCRIPT $SOURCE ' + LOCALEDIR + ' > $TARGET'
+    command = python_cmd + ' $SCRIPT --template $SOURCE --output $TARGET --localedir ' + LOCALEDIR
 )
 
 Export('xmlpool_options')
index 6a5dcee0a87afa27f834e3073dbc88da441db230..078bced73396bfca7cb091b57b51aa841527ac2e 100644 (file)
@@ -7,7 +7,7 @@
 # `{localedir}/{language}/LC_MESSAGES/options.mo`.
 #
 
-from __future__ import print_function
+from __future__ import print_function, unicode_literals
 import argparse
 import gettext
 import io
@@ -114,7 +114,7 @@ def expandCString(s):
 #
 # DESC, DESC_BEGIN format: \1 \2=<lang> \3 \4=gettext(" \5=<text> \6=") \7
 # ENUM format:             \1 \2=gettext(" \3=<text> \4=") \5
-def expandMatches(matches, translations, end=None):
+def expandMatches(matches, translations, outfile, end=None):
     assert len(matches) > 0
     nTranslations = len(translations)
     i = 0
@@ -131,12 +131,7 @@ def expandMatches(matches, translations, end=None):
             matches[0].expand (r'\5'))))
         text = (matches[0].expand(r'\1' + lang + r'\3"' + text + r'"\7') + suffix)
 
-        # In Python 2, stdout expects encoded byte strings, or else it will
-        # encode them with the ascii 'codec'
-        if sys.version_info.major == 2:
-            text = text.encode('utf-8')
-
-        print(text)
+        outfile.write(text + '\n')
 
         # Expand any subsequent enum lines
         for match in matches[1:]:
@@ -144,16 +139,11 @@ def expandMatches(matches, translations, end=None):
                 match.expand(r'\3'))))
             text = match.expand(r'\1"' + text + r'"\5')
 
-            # In Python 2, stdout expects encoded byte strings, or else it will
-            # encode them with the ascii 'codec'
-            if sys.version_info.major == 2:
-                text = text.encode('utf-8')
-
-            print(text)
+            outfile.write(text + '\n')
 
         # Expand description end
         if end:
-            print(end, end='')
+            outfile.write(end)
 
 # Regular expressions:
 reLibintl_h = re.compile(r'#\s*include\s*<libintl.h>')
@@ -165,9 +155,10 @@ reDESC_END = re.compile(r'\s*DRI_CONF_DESC_END')
 
 def main():
     parser = argparse.ArgumentParser()
-    parser.add_argument('template')
-    parser.add_argument('localedir')
-    parser.add_argument('languages', nargs='*')
+    parser.add_argument('--template', required=True)
+    parser.add_argument('--output', required=True)
+    parser.add_argument('--localedir', required=True)
+    parser.add_argument('--languages', nargs='*', default=[])
     args = parser.parse_args()
 
     # Compile a list of translation classes to all supported languages.
@@ -183,50 +174,45 @@ def main():
             continue
         translations.append((lang, trans))
 
-    print("/***********************************************************************\n" \
-    " ***        THIS FILE IS GENERATED AUTOMATICALLY. DON'T EDIT!        ***\n" \
-    " ***********************************************************************/")
-
-    # Process the options template and generate options.h with all
-    # translations.
-    with io.open(args.template, mode="rt", encoding='utf-8') as template:
-        descMatches = []
-        for line in template:
-            if len(descMatches) > 0:
-                matchENUM = reENUM.match(line)
-                matchDESC_END = reDESC_END.match(line)
-                if matchENUM:
-                    descMatches.append(matchENUM)
-                elif matchDESC_END:
-                    expandMatches(descMatches, translations, line)
-                    descMatches = []
+    with io.open(args.output, mode='wt', encoding='utf-8') as output:
+        output.write("/* This is file is generated automatically. Don't edit!  */\n")
+
+        # Process the options template and generate options.h with all
+        # translations.
+        with io.open(args.template, mode="rt", encoding='utf-8') as template:
+            descMatches = []
+            for line in template:
+                if len(descMatches) > 0:
+                    matchENUM = reENUM.match(line)
+                    matchDESC_END = reDESC_END.match(line)
+                    if matchENUM:
+                        descMatches.append(matchENUM)
+                    elif matchDESC_END:
+                        expandMatches(descMatches, translations, output, line)
+                        descMatches = []
+                    else:
+                        print("Warning: unexpected line inside description dropped:\n",
+                              line, file=sys.stderr)
+                    continue
+                if reLibintl_h.search(line):
+                    # Ignore (comment out) #include <libintl.h>
+                    output.write("/* %s * commented out by gen_xmlpool.py */\n" % line)
+                    continue
+                matchDESC = reDESC.match(line)
+                matchDESC_BEGIN = reDESC_BEGIN.match(line)
+                if matchDESC:
+                    assert len(descMatches) == 0
+                    expandMatches([matchDESC], translations, output)
+                elif matchDESC_BEGIN:
+                    assert len(descMatches) == 0
+                    descMatches = [matchDESC_BEGIN]
                 else:
-                    print("Warning: unexpected line inside description dropped:\n",
-                          line, file=sys.stderr)
-                continue
-            if reLibintl_h.search(line):
-                # Ignore (comment out) #include <libintl.h>
-                print("/* %s * commented out by gen_xmlpool.py */" % line)
-                continue
-            matchDESC = reDESC.match(line)
-            matchDESC_BEGIN = reDESC_BEGIN.match(line)
-            if matchDESC:
-                assert len(descMatches) == 0
-                expandMatches([matchDESC], translations)
-            elif matchDESC_BEGIN:
-                assert len(descMatches) == 0
-                descMatches = [matchDESC_BEGIN]
-            else:
-                # In Python 2, stdout expects encoded byte strings, or else it will
-                # encode them with the ascii 'codec'
-                if sys.version_info.major == 2:
-                   line = line.encode('utf-8')
 
-                print(line, end='')
+                    output.write(line)
 
-    if len(descMatches) > 0:
-        print("Warning: unterminated description at end of file.", file=sys.stderr)
-        expandMatches(descMatches, translations)
+        if len(descMatches) > 0:
+            print("Warning: unterminated description at end of file.", file=sys.stderr)
+            expandMatches(descMatches, translations, output)
 
 
 if __name__ == '__main__':
index ae7c951a097fa5206e5a66567ce9b004af1aaba4..1fce397e4723ef8e809a65c67b8b9e001c2e4523 100644 (file)
@@ -30,9 +30,9 @@ xmlpool_options_h = custom_target(
   input : ['gen_xmlpool.py', 't_options.h'],
   output : 'options.h',
   command : [
-    prog_python, '@INPUT@', meson.current_build_dir(), _langs,
+    prog_python, '@INPUT0@', '--template', '@INPUT1@', '--output', '@OUTPUT@',
+    '--localedir', meson.current_build_dir(), '--languages',  _langs,
   ],
-  capture : true,
   depend_files : _langs_po_files,
 )