X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Futil%2Fxmlpool%2Fgen_xmlpool.py;h=3a352312644218ff52b10b7a102655deb5e95739;hb=d415748955034b659c8b577adc727b1fd39948b8;hp=9d932f3e85cc444d8177ecbe1445fbb40198175a;hpb=187fad5c0b21f57a073cb797bfdf7eed961e9405;p=mesa.git diff --git a/src/util/xmlpool/gen_xmlpool.py b/src/util/xmlpool/gen_xmlpool.py index 9d932f3e85c..3a352312644 100644 --- a/src/util/xmlpool/gen_xmlpool.py +++ b/src/util/xmlpool/gen_xmlpool.py @@ -1,4 +1,4 @@ - +# encoding=utf-8 # # Usage: # gen_xmlpool.py /path/to/t_option.h localedir lang lang lang ... @@ -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 @@ -15,12 +15,6 @@ import os import re import sys -parser = argparse.ArgumentParser() -parser.add_argument('template') -parser.add_argument('localedir') -parser.add_argument('languages', nargs='*') -args = parser.parse_args() - if sys.version_info < (3, 0): gettext_method = 'ugettext' else: @@ -33,25 +27,24 @@ def escapeCString(s): # " -> '' is a hack. Quotes (") aren't possible in XML attributes. # Better use Unicode characters for typographic quotes in option # descriptions and translations. + last_quote = '”' i = 0 r = '' - while i < len(s): - # Special case: escape double quote with \u201c or \u201d, depending + for c in s: + # Special case: escape double quote with “ or ”, depending # on whether it's an open or close quote. This is needed because plain # double quotes are not possible in XML attributes. - if s[i] == '"': - if i == len(s) - 1 or s[i + 1].isspace(): - # close quote - q = u'\u201c' + if c == '"': + if last_quote == '”': + q = '“' else: - # open quote - q = u'\u201d' + q = '”' + last_quote = q r = r + q - elif s[i] in escapeSeqs: - r = r + escapeSeqs[s[i]] + elif c in escapeSeqs: + r = r + escapeSeqs[c] else: - r = r + s[i] - i = i + 1 + r = r + c return r # Expand escape sequences in C strings (needed for gettext lookup) @@ -59,24 +52,23 @@ def expandCString(s): escapeSeqs = {'a' : '\a', 'b' : '\b', 'f' : '\f', 'n' : '\n', 'r' : '\r', 't' : '\t', 'v' : '\v', '"' : '"', '\\' : '\\'} - i = 0 escape = False hexa = False octa = False num = 0 digits = 0 r = u'' - while i < len(s): + for c in s: if not escape: - if s[i] == '\\': + if c == '\\': escape = True else: - r = r + s[i] + r = r + c elif hexa: - if (s[i] >= '0' and s[i] <= '9') or \ - (s[i] >= 'a' and s[i] <= 'f') or \ - (s[i] >= 'A' and s[i] <= 'F'): - num = num * 16 + int(s[i],16) + if (c >= '0' and c <= '9') or \ + (c >= 'a' and c <= 'f') or \ + (c >= 'A' and c <= 'F'): + num = num * 16 + int(c, 16) digits = digits + 1 else: digits = 2 @@ -85,8 +77,8 @@ def expandCString(s): escape = False r = r + chr(num) elif octa: - if s[i] >= '0' and s[i] <= '7': - num = num * 8 + int(s[i],8) + if c >= '0' and c <= '7': + num = num * 8 + int(c, 8) digits = digits + 1 else: digits = 3 @@ -95,24 +87,23 @@ def expandCString(s): escape = False r = r + chr(num) else: - if s[i] in escapeSeqs: - r = r + escapeSeqs[s[i]] + if c in escapeSeqs: + r = r + escapeSeqs[c] escape = False - elif s[i] >= '0' and s[i] <= '7': + elif c >= '0' and c <= '7': octa = True - num = int(s[i],8) + num = int(c, 8) if num <= 3: digits = 1 else: digits = 2 - elif s[i] == 'x' or s[i] == 'X': + elif c == 'x' or c == 'X': hexa = True num = 0 digits = 0 else: - r = r + s[i] + r = r + c escape = False - i = i + 1 return r # Expand matches. The first match is always a DESC or DESC_BEGIN match. @@ -120,7 +111,7 @@ def expandCString(s): # # DESC, DESC_BEGIN format: \1 \2= \3 \4=gettext(" \5= \6=") \7 # ENUM format: \1 \2=gettext(" \3= \4=") \5 -def expandMatches(matches, translations, end=None): +def expandMatches(matches, translations, outfile, end=None): assert len(matches) > 0 nTranslations = len(translations) i = 0 @@ -137,12 +128,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:]: @@ -150,29 +136,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='') - -# Compile a list of translation classes to all supported languages. -# The first translation is always a NullTranslations. -translations = [("en", gettext.NullTranslations())] -for lang in args.languages: - try: - filename = os.path.join(args.localedir, '{}.gmo'.format(lang)) - with io.open(filename, 'rb') as f: - trans = gettext.GNUTranslations(f) - except (IOError, OSError): - print("Warning: language '%s' not found." % lang, file=sys.stderr) - continue - translations.append((lang, trans)) + outfile.write(end) # Regular expressions: reLibintl_h = re.compile(r'#\s*include\s*') @@ -181,50 +149,68 @@ reDESC_BEGIN = re.compile(r'(\s*DRI_CONF_DESC_BEGIN\s*\(\s*)([a-z]+)(\s*,\s*)(ge reENUM = re.compile(r'(\s*DRI_CONF_ENUM\s*\([^,]+,\s*)(gettext\s*\(\s*")(.*)("\s*\))(\s*\)[ \t]*\\?)$') reDESC_END = re.compile(r'\s*DRI_CONF_DESC_END') -# Print a header -print("/***********************************************************************\n" \ -" *** THIS FILE IS GENERATED AUTOMATICALLY. DON'T EDIT! ***\n" \ -" ***********************************************************************/") - -# Process the options template and generate options.h with all -# translations. -template = io.open(args.template, mode="rt", encoding='utf-8') -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) + +def main(): + parser = argparse.ArgumentParser() + 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. + # The first translation is always a NullTranslations. + translations = [("en", gettext.NullTranslations())] + for lang in args.languages: + try: + filename = os.path.join(args.localedir, '{}.gmo'.format(lang)) + with io.open(filename, 'rb') as f: + trans = gettext.GNUTranslations(f) + except (IOError, OSError): + print("Warning: language '%s' not found." % lang, file=sys.stderr) + continue + translations.append((lang, trans)) + + 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 = [] - else: - print("Warning: unexpected line inside description dropped:\n", line, - file=sys.stderr) - continue - if reLibintl_h.search(line): - # Ignore (comment out) #include - 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='') - -template.close() - -if len(descMatches) > 0: - print("Warning: unterminated description at end of file.", file=sys.stderr) - expandMatches(descMatches, translations) + for line in template: + if descMatches: + 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 + 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 not descMatches + expandMatches([matchDESC], translations, output) + elif matchDESC_BEGIN: + assert not descMatches + descMatches = [matchDESC_BEGIN] + else: + + output.write(line) + + if descMatches: + print("Warning: unterminated description at end of file.", file=sys.stderr) + expandMatches(descMatches, translations, output) + + +if __name__ == '__main__': + main()