locale_database: Use argparse module to parse command line arguments
arparse is the standard way to parse command line arguments in Python. It provides help and usage information for free and is easier to extend than a custom argument parser. Task-number: QTBUG-83488 Pick-to: 6.2 Change-Id: I1e4c9cd914449e083d01932bc871ef10d26f0bc2 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
parent
41458fafa0
commit
5ef5dce53b
@ -27,7 +27,7 @@
|
|||||||
## $QT_END_LICENSE$
|
## $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
|
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
|
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
|
While updating the locale data, check also for updates to MS-Win's
|
||||||
time zone names; see cldr2qtimezone.py for details.
|
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/
|
.. _CLDR: ftp://unicode.org/Public/cldr/
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
from cldr import CldrReader
|
from cldr import CldrReader
|
||||||
from qlocalexml import QLocaleXmlWriter
|
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):
|
def main(out, err):
|
||||||
# TODO: make calendars a command-line option
|
all_calendars = ['gregorian', 'persian', 'islamic'] # 'hebrew'
|
||||||
calendars = ['gregorian', 'persian', 'islamic'] # 'hebrew'
|
|
||||||
|
|
||||||
# TODO: make argument parsing more sophisticated
|
parser = argparse.ArgumentParser(
|
||||||
name = args.pop(0)
|
description='Generate QLocaleXML from CLDR data.',
|
||||||
if not args:
|
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||||
usage(name, err, 'Where is your CLDR data tree ?')
|
parser.add_argument('cldr_path', help='path to the root of the CLDR tree')
|
||||||
return 1
|
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')):
|
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: '
|
parser.error('First argument is the root of the CLDR tree: '
|
||||||
f'found no common/main/root.xml under {root}')
|
f'found no common/main/root.xml under {root}')
|
||||||
return 1
|
|
||||||
|
|
||||||
xml = args.pop(0) if args else None
|
xml = args.out_file
|
||||||
if not xml or xml == '-':
|
if not xml or xml == '-':
|
||||||
emit = out
|
emit = out
|
||||||
elif not xml.endswith('.xml'):
|
elif not xml.endswith('.xml'):
|
||||||
usage(name, err, f'Please use a .xml extension on your output file name, not {xml}')
|
parser.error(f'Please use a .xml extension on your output file name, not {xml}')
|
||||||
return 1
|
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
emit = open(xml, 'w')
|
emit = open(xml, 'w')
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
usage(name, err, f'Failed to open "{xml}" to write output to it\n')
|
parser.error(f'Failed to open "{xml}" to write output to it')
|
||||||
return 1
|
|
||||||
|
|
||||||
if args:
|
|
||||||
usage(name, err, 'Too many arguments - excess: ' + ' '.join(args))
|
|
||||||
return 1
|
|
||||||
|
|
||||||
# TODO - command line options to tune choice of grumble and whitter:
|
# TODO - command line options to tune choice of grumble and whitter:
|
||||||
reader = CldrReader(root, err.write, err.write)
|
reader = CldrReader(root, err.write, err.write)
|
||||||
@ -106,10 +102,10 @@ def main(args, out, err):
|
|||||||
writer.version(reader.root.cldrVersion)
|
writer.version(reader.root.cldrVersion)
|
||||||
writer.enumData()
|
writer.enumData()
|
||||||
writer.likelySubTags(reader.likelySubTags())
|
writer.likelySubTags(reader.likelySubTags())
|
||||||
writer.locales(reader.readLocales(calendars), calendars)
|
writer.locales(reader.readLocales(args.calendars), args.calendars)
|
||||||
|
|
||||||
writer.close(err.write)
|
writer.close(err.write)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
sys.exit(main(sys.argv, sys.stdout, sys.stderr))
|
sys.exit(main(sys.stdout, sys.stderr))
|
||||||
|
@ -39,6 +39,7 @@ for use.
|
|||||||
import os
|
import os
|
||||||
import datetime
|
import datetime
|
||||||
import textwrap
|
import textwrap
|
||||||
|
import argparse
|
||||||
|
|
||||||
from localetools import unicode2hex, wrap_list, Error, SourceFileEditor
|
from localetools import unicode2hex, wrap_list, Error, SourceFileEditor
|
||||||
from cldr import CldrAccess
|
from cldr import CldrAccess
|
||||||
@ -324,46 +325,41 @@ class ZoneIdWriter (SourceFileEditor):
|
|||||||
|
|
||||||
return windowsIdData, ianaIdData
|
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.
|
"""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
|
arguments. Expects two command-line options: the root of the
|
||||||
unpacked CLDR data-file tree and the root of the qtbase module's
|
unpacked CLDR data-file tree and the root of the qtbase module's
|
||||||
checkout. Updates QTimeZone's private data about Windows time-zone
|
checkout. Updates QTimeZone's private data about Windows time-zone
|
||||||
IDs."""
|
IDs."""
|
||||||
name = args.pop(0)
|
parser = argparse.ArgumentParser(
|
||||||
if len(args) != 2:
|
description="Update Qt's CLDR-derived timezone data.")
|
||||||
usage(err, name, "Expected two arguments")
|
parser.add_argument('cldr_path', help='path to the root of the CLDR tree')
|
||||||
return 1
|
parser.add_argument('qtbase_path', help='path to the root of the qtbase source tree')
|
||||||
|
|
||||||
cldrPath = args.pop(0)
|
args = parser.parse_args()
|
||||||
qtPath = args.pop(0)
|
|
||||||
|
cldrPath = args.cldr_path
|
||||||
|
qtPath = args.qtbase_path
|
||||||
|
|
||||||
if not os.path.isdir(qtPath):
|
if not os.path.isdir(qtPath):
|
||||||
usage(err, name, f"No such Qt directory: {qtPath}")
|
parser.error(f"No such Qt directory: {qtPath}")
|
||||||
return 1
|
|
||||||
if not os.path.isdir(cldrPath):
|
if not os.path.isdir(cldrPath):
|
||||||
usage(err, name, f"No such CLDR directory: {cldrPath}")
|
parser.error(f"No such CLDR directory: {cldrPath}")
|
||||||
return 1
|
|
||||||
|
|
||||||
dataFilePath = os.path.join(qtPath, 'src', 'corelib', 'time', 'qtimezoneprivate_data_p.h')
|
dataFilePath = os.path.join(qtPath, 'src', 'corelib', 'time', 'qtimezoneprivate_data_p.h')
|
||||||
if not os.path.isfile(dataFilePath):
|
if not os.path.isfile(dataFilePath):
|
||||||
usage(err, name, f'No such file: {dataFilePath}')
|
parser.error(f'No such file: {dataFilePath}')
|
||||||
return 1
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
version, defaults, winIds = CldrAccess(cldrPath).readWindowsTimeZones(
|
version, defaults, winIds = CldrAccess(cldrPath).readWindowsTimeZones(
|
||||||
dict((name, ind) for ind, name in enumerate((x[0] for x in windowsIdList), 1)))
|
dict((name, ind) for ind, name in enumerate((x[0] for x in windowsIdList), 1)))
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
usage(err, name,
|
parser.error(
|
||||||
f'Failed to open common/supplemental/windowsZones.xml: {e}')
|
f'Failed to open common/supplemental/windowsZones.xml: {e}')
|
||||||
return 1
|
return 1
|
||||||
except Error as e:
|
except Error as e:
|
||||||
err.write('\n'.join(textwrap.wrap(
|
err.write('\n'.join(textwrap.wrap(
|
||||||
@ -391,4 +387,4 @@ def main(args, out, err):
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import sys
|
import sys
|
||||||
sys.exit(main(sys.argv, sys.stdout, sys.stderr))
|
sys.exit(main(sys.stdout, sys.stderr))
|
||||||
|
@ -26,15 +26,16 @@
|
|||||||
## $QT_END_LICENSE$
|
## $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
|
Pass the output file from that as first parameter to this script; pass
|
||||||
the root of the qtbase check-out as second parameter.
|
the root of the qtbase check-out as second parameter.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import datetime
|
import datetime
|
||||||
|
import argparse
|
||||||
|
|
||||||
from qlocalexml import QLocaleXmlReader
|
from qlocalexml import QLocaleXmlReader
|
||||||
from localetools import unicode2hex, wrap_list, Error, Transcriber, SourceFileEditor
|
from localetools import unicode2hex, wrap_list, Error, Transcriber, SourceFileEditor
|
||||||
@ -498,30 +499,36 @@ class LocaleHeaderWriter (SourceFileEditor):
|
|||||||
|
|
||||||
out('\n };\n')
|
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):
|
def main(out, err):
|
||||||
# TODO: Make calendars a command-line parameter
|
|
||||||
# map { CLDR name: Qt file name }
|
# 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)
|
parser = argparse.ArgumentParser(
|
||||||
if len(args) != 2:
|
description='Generate C++ code from CLDR data in QLocaleXML form.',
|
||||||
usage(name, err, 'I expect two arguments')
|
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||||
return 1
|
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)
|
qlocalexml = args.input_file
|
||||||
qtsrcdir = args.pop(0)
|
qtsrcdir = args.qtbase_path
|
||||||
|
calendars = {cal: calendars_map[cal] for cal in args.calendars}
|
||||||
|
|
||||||
if not (os.path.isdir(qtsrcdir)
|
if not (os.path.isdir(qtsrcdir)
|
||||||
and all(os.path.isfile(os.path.join(qtsrcdir, 'src', 'corelib', 'text', leaf))
|
and all(os.path.isfile(os.path.join(qtsrcdir, 'src', 'corelib', 'text', leaf))
|
||||||
for leaf in ('qlocale_data_p.h', 'qlocale.h', 'qlocale.qdoc'))):
|
for leaf in ('qlocale_data_p.h', 'qlocale.h', 'qlocale.qdoc'))):
|
||||||
usage(name, err, f'Missing expected files under qtbase source root {qtsrcdir}')
|
parser.error(f'Missing expected files under qtbase source root {qtsrcdir}')
|
||||||
return 1
|
|
||||||
|
|
||||||
reader = QLocaleXmlReader(qlocalexml)
|
reader = QLocaleXmlReader(qlocalexml)
|
||||||
locale_map = dict(reader.loadLocaleMap(calendars, err.write))
|
locale_map = dict(reader.loadLocaleMap(calendars, err.write))
|
||||||
@ -617,4 +624,4 @@ def main(args, out, err):
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import sys
|
import sys
|
||||||
sys.exit(main(sys.argv, sys.stdout, sys.stderr))
|
sys.exit(main(sys.stdout, sys.stderr))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user