diff --git a/util/locale_database/cldr2qlocalexml.py b/util/locale_database/cldr2qlocalexml.py index 5f67ee708b..6ebf62e95a 100755 --- a/util/locale_database/cldr2qlocalexml.py +++ b/util/locale_database/cldr2qlocalexml.py @@ -27,7 +27,7 @@ ## $QT_END_LICENSE$ ## ############################################################################# -"""Convert CLDR data to qLocaleXML +"""Convert CLDR data to QLocaleXML The CLDR data can be downloaded from CLDR_, which has a sub-directory for each version; you need the ``core.zip`` file for your version of @@ -51,53 +51,49 @@ order. While updating the locale data, check also for updates to MS-Win's time zone names; see cldr2qtimezone.py for details. +All the scripts mentioned support --help to tell you how to use them. + .. _CLDR: ftp://unicode.org/Public/cldr/ """ import os import sys +import argparse from cldr import CldrReader from qlocalexml import QLocaleXmlWriter -def usage(name, err, message = ''): - err.write(f"""Usage: {name} path/to/cldr/common/main [out-file.xml] -""") # TODO: expand command-line, improve help message - if message: - err.write(f'\n{message}\n') -def main(args, out, err): - # TODO: make calendars a command-line option - calendars = ['gregorian', 'persian', 'islamic'] # 'hebrew' +def main(out, err): + all_calendars = ['gregorian', 'persian', 'islamic'] # 'hebrew' - # TODO: make argument parsing more sophisticated - name = args.pop(0) - if not args: - usage(name, err, 'Where is your CLDR data tree ?') - return 1 + parser = argparse.ArgumentParser( + description='Generate QLocaleXML from CLDR data.', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument('cldr_path', help='path to the root of the CLDR tree') + parser.add_argument('out_file', help='output XML file name', + nargs='?', metavar='out-file.xml') + parser.add_argument('--calendars', help='select calendars to emit data for', + nargs='+', metavar='CALENDAR', + choices=all_calendars, default=all_calendars) - root = args.pop(0) + args = parser.parse_args() + + root = args.cldr_path if not os.path.exists(os.path.join(root, 'common', 'main', 'root.xml')): - usage(name, err, 'First argument is the root of the CLDR tree: ' - f'found no common/main/root.xml under {root}') - return 1 + parser.error('First argument is the root of the CLDR tree: ' + f'found no common/main/root.xml under {root}') - xml = args.pop(0) if args else None + xml = args.out_file if not xml or xml == '-': emit = out elif not xml.endswith('.xml'): - usage(name, err, f'Please use a .xml extension on your output file name, not {xml}') - return 1 + parser.error(f'Please use a .xml extension on your output file name, not {xml}') else: try: emit = open(xml, 'w') except IOError as e: - usage(name, err, f'Failed to open "{xml}" to write output to it\n') - return 1 - - if args: - usage(name, err, 'Too many arguments - excess: ' + ' '.join(args)) - return 1 + parser.error(f'Failed to open "{xml}" to write output to it') # TODO - command line options to tune choice of grumble and whitter: reader = CldrReader(root, err.write, err.write) @@ -106,10 +102,10 @@ def main(args, out, err): writer.version(reader.root.cldrVersion) writer.enumData() writer.likelySubTags(reader.likelySubTags()) - writer.locales(reader.readLocales(calendars), calendars) + writer.locales(reader.readLocales(args.calendars), args.calendars) writer.close(err.write) return 0 if __name__ == '__main__': - sys.exit(main(sys.argv, sys.stdout, sys.stderr)) + sys.exit(main(sys.stdout, sys.stderr)) diff --git a/util/locale_database/cldr2qtimezone.py b/util/locale_database/cldr2qtimezone.py index a51238f114..30e351a7a4 100755 --- a/util/locale_database/cldr2qtimezone.py +++ b/util/locale_database/cldr2qtimezone.py @@ -39,6 +39,7 @@ for use. import os import datetime import textwrap +import argparse from localetools import unicode2hex, wrap_list, Error, SourceFileEditor from cldr import CldrAccess @@ -324,46 +325,41 @@ class ZoneIdWriter (SourceFileEditor): return windowsIdData, ianaIdData -def usage(err, name, message=''): - err.write(f"""Usage: {name} path/to/cldr/root path/to/qtbase -""") # TODO: more interesting message - if message: - err.write(f'\n{message}\n') -def main(args, out, err): +def main(out, err): """Parses CLDR's data and updates Qt's representation of it. - Takes sys.argv, sys.stdout, sys.stderr (or equivalents) as + Takes sys.stdout, sys.stderr (or equivalents) as arguments. Expects two command-line options: the root of the unpacked CLDR data-file tree and the root of the qtbase module's checkout. Updates QTimeZone's private data about Windows time-zone IDs.""" - name = args.pop(0) - if len(args) != 2: - usage(err, name, "Expected two arguments") - return 1 + parser = argparse.ArgumentParser( + description="Update Qt's CLDR-derived timezone data.") + parser.add_argument('cldr_path', help='path to the root of the CLDR tree') + parser.add_argument('qtbase_path', help='path to the root of the qtbase source tree') - cldrPath = args.pop(0) - qtPath = args.pop(0) + args = parser.parse_args() + + cldrPath = args.cldr_path + qtPath = args.qtbase_path if not os.path.isdir(qtPath): - usage(err, name, f"No such Qt directory: {qtPath}") - return 1 + parser.error(f"No such Qt directory: {qtPath}") + if not os.path.isdir(cldrPath): - usage(err, name, f"No such CLDR directory: {cldrPath}") - return 1 + parser.error(f"No such CLDR directory: {cldrPath}") dataFilePath = os.path.join(qtPath, 'src', 'corelib', 'time', 'qtimezoneprivate_data_p.h') if not os.path.isfile(dataFilePath): - usage(err, name, f'No such file: {dataFilePath}') - return 1 + parser.error(f'No such file: {dataFilePath}') try: version, defaults, winIds = CldrAccess(cldrPath).readWindowsTimeZones( dict((name, ind) for ind, name in enumerate((x[0] for x in windowsIdList), 1))) except IOError as e: - usage(err, name, - f'Failed to open common/supplemental/windowsZones.xml: {e}') + parser.error( + f'Failed to open common/supplemental/windowsZones.xml: {e}') return 1 except Error as e: err.write('\n'.join(textwrap.wrap( @@ -391,4 +387,4 @@ def main(args, out, err): if __name__ == '__main__': import sys - sys.exit(main(sys.argv, sys.stdout, sys.stderr)) + sys.exit(main(sys.stdout, sys.stderr)) diff --git a/util/locale_database/qlocalexml2cpp.py b/util/locale_database/qlocalexml2cpp.py index e21577db9e..50a03dc9f3 100755 --- a/util/locale_database/qlocalexml2cpp.py +++ b/util/locale_database/qlocalexml2cpp.py @@ -26,15 +26,16 @@ ## $QT_END_LICENSE$ ## ############################################################################# -"""Script to generate C++ code from CLDR data in qLocaleXML form +"""Script to generate C++ code from CLDR data in QLocaleXML form -See ``cldr2qlocalexml.py`` for how to generate the qLocaleXML data itself. +See ``cldr2qlocalexml.py`` for how to generate the QLocaleXML data itself. Pass the output file from that as first parameter to this script; pass the root of the qtbase check-out as second parameter. """ import os import datetime +import argparse from qlocalexml import QLocaleXmlReader from localetools import unicode2hex, wrap_list, Error, Transcriber, SourceFileEditor @@ -498,30 +499,36 @@ class LocaleHeaderWriter (SourceFileEditor): out('\n };\n') -def usage(name, err, message = ''): - err.write(f"""Usage: {name} path/to/qlocale.xml root/of/qtbase -""") # TODO: elaborate - if message: - err.write('\n' + message + '\n') -def main(args, out, err): - # TODO: Make calendars a command-line parameter +def main(out, err): # map { CLDR name: Qt file name } - calendars = {'gregorian': 'roman', 'persian': 'jalali', 'islamic': 'hijri',} # 'hebrew': 'hebrew', + calendars_map = { + 'gregorian': 'roman', + 'persian': 'jalali', + 'islamic': 'hijri', + # 'hebrew': 'hebrew' + } + all_calendars = list(calendars_map.keys()) - name = args.pop(0) - if len(args) != 2: - usage(name, err, 'I expect two arguments') - return 1 + parser = argparse.ArgumentParser( + description='Generate C++ code from CLDR data in QLocaleXML form.', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument('input_file', help='input XML file name', + metavar='input-file.xml') + parser.add_argument('qtbase_path', help='path to the root of the qtbase source tree') + parser.add_argument('--calendars', help='select calendars to emit data for', + nargs='+', metavar='CALENDAR', + choices=all_calendars, default=all_calendars) + args = parser.parse_args() - qlocalexml = args.pop(0) - qtsrcdir = args.pop(0) + qlocalexml = args.input_file + qtsrcdir = args.qtbase_path + calendars = {cal: calendars_map[cal] for cal in args.calendars} if not (os.path.isdir(qtsrcdir) and all(os.path.isfile(os.path.join(qtsrcdir, 'src', 'corelib', 'text', leaf)) for leaf in ('qlocale_data_p.h', 'qlocale.h', 'qlocale.qdoc'))): - usage(name, err, f'Missing expected files under qtbase source root {qtsrcdir}') - return 1 + parser.error(f'Missing expected files under qtbase source root {qtsrcdir}') reader = QLocaleXmlReader(qlocalexml) locale_map = dict(reader.loadLocaleMap(calendars, err.write)) @@ -617,4 +624,4 @@ def main(args, out, err): if __name__ == "__main__": import sys - sys.exit(main(sys.argv, sys.stdout, sys.stderr)) + sys.exit(main(sys.stdout, sys.stderr))