17db96d56Sopenharmony_ci#
27db96d56Sopenharmony_ci# Copyright (c) 2008-2012 Stefan Krah. All rights reserved.
37db96d56Sopenharmony_ci#
47db96d56Sopenharmony_ci# Redistribution and use in source and binary forms, with or without
57db96d56Sopenharmony_ci# modification, are permitted provided that the following conditions
67db96d56Sopenharmony_ci# are met:
77db96d56Sopenharmony_ci#
87db96d56Sopenharmony_ci# 1. Redistributions of source code must retain the above copyright
97db96d56Sopenharmony_ci#    notice, this list of conditions and the following disclaimer.
107db96d56Sopenharmony_ci#
117db96d56Sopenharmony_ci# 2. Redistributions in binary form must reproduce the above copyright
127db96d56Sopenharmony_ci#    notice, this list of conditions and the following disclaimer in the
137db96d56Sopenharmony_ci#    documentation and/or other materials provided with the distribution.
147db96d56Sopenharmony_ci#
157db96d56Sopenharmony_ci# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
167db96d56Sopenharmony_ci# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
177db96d56Sopenharmony_ci# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
187db96d56Sopenharmony_ci# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
197db96d56Sopenharmony_ci# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
207db96d56Sopenharmony_ci# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
217db96d56Sopenharmony_ci# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
227db96d56Sopenharmony_ci# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
237db96d56Sopenharmony_ci# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
247db96d56Sopenharmony_ci# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
257db96d56Sopenharmony_ci# SUCH DAMAGE.
267db96d56Sopenharmony_ci#
277db96d56Sopenharmony_ci
287db96d56Sopenharmony_ci
297db96d56Sopenharmony_ci# Generate PEP-3101 format strings.
307db96d56Sopenharmony_ci
317db96d56Sopenharmony_ci
327db96d56Sopenharmony_ciimport os, sys, locale, random
337db96d56Sopenharmony_ciimport platform, subprocess
347db96d56Sopenharmony_cifrom test.support.import_helper import import_fresh_module
357db96d56Sopenharmony_cifrom distutils.spawn import find_executable
367db96d56Sopenharmony_ci
377db96d56Sopenharmony_ciC = import_fresh_module('decimal', fresh=['_decimal'])
387db96d56Sopenharmony_ciP = import_fresh_module('decimal', blocked=['_decimal'])
397db96d56Sopenharmony_ci
407db96d56Sopenharmony_ci
417db96d56Sopenharmony_ciwindows_lang_strings = [
427db96d56Sopenharmony_ci  "chinese", "chinese-simplified", "chinese-traditional", "czech", "danish",
437db96d56Sopenharmony_ci  "dutch", "belgian", "english", "australian", "canadian", "english-nz",
447db96d56Sopenharmony_ci  "english-uk", "english-us", "finnish", "french", "french-belgian",
457db96d56Sopenharmony_ci  "french-canadian", "french-swiss", "german", "german-austrian",
467db96d56Sopenharmony_ci  "german-swiss", "greek", "hungarian", "icelandic", "italian", "italian-swiss",
477db96d56Sopenharmony_ci  "japanese", "korean", "norwegian", "norwegian-bokmal", "norwegian-nynorsk",
487db96d56Sopenharmony_ci  "polish", "portuguese", "portuguese-brazil", "russian", "slovak", "spanish",
497db96d56Sopenharmony_ci  "spanish-mexican", "spanish-modern", "swedish", "turkish",
507db96d56Sopenharmony_ci]
517db96d56Sopenharmony_ci
527db96d56Sopenharmony_cipreferred_encoding = {
537db96d56Sopenharmony_ci  'cs_CZ': 'ISO8859-2',
547db96d56Sopenharmony_ci  'cs_CZ.iso88592': 'ISO8859-2',
557db96d56Sopenharmony_ci  'czech': 'ISO8859-2',
567db96d56Sopenharmony_ci  'eesti': 'ISO8859-1',
577db96d56Sopenharmony_ci  'estonian': 'ISO8859-1',
587db96d56Sopenharmony_ci  'et_EE': 'ISO8859-15',
597db96d56Sopenharmony_ci  'et_EE.ISO-8859-15': 'ISO8859-15',
607db96d56Sopenharmony_ci  'et_EE.iso885915': 'ISO8859-15',
617db96d56Sopenharmony_ci  'et_EE.iso88591': 'ISO8859-1',
627db96d56Sopenharmony_ci  'fi_FI.iso88591': 'ISO8859-1',
637db96d56Sopenharmony_ci  'fi_FI': 'ISO8859-15',
647db96d56Sopenharmony_ci  'fi_FI@euro': 'ISO8859-15',
657db96d56Sopenharmony_ci  'fi_FI.iso885915@euro': 'ISO8859-15',
667db96d56Sopenharmony_ci  'finnish': 'ISO8859-1',
677db96d56Sopenharmony_ci  'lv_LV': 'ISO8859-13',
687db96d56Sopenharmony_ci  'lv_LV.iso885913': 'ISO8859-13',
697db96d56Sopenharmony_ci  'nb_NO': 'ISO8859-1',
707db96d56Sopenharmony_ci  'nb_NO.iso88591': 'ISO8859-1',
717db96d56Sopenharmony_ci  'bokmal': 'ISO8859-1',
727db96d56Sopenharmony_ci  'nn_NO': 'ISO8859-1',
737db96d56Sopenharmony_ci  'nn_NO.iso88591': 'ISO8859-1',
747db96d56Sopenharmony_ci  'no_NO': 'ISO8859-1',
757db96d56Sopenharmony_ci  'norwegian': 'ISO8859-1',
767db96d56Sopenharmony_ci  'nynorsk': 'ISO8859-1',
777db96d56Sopenharmony_ci  'ru_RU': 'ISO8859-5',
787db96d56Sopenharmony_ci  'ru_RU.iso88595': 'ISO8859-5',
797db96d56Sopenharmony_ci  'russian': 'ISO8859-5',
807db96d56Sopenharmony_ci  'ru_RU.KOI8-R': 'KOI8-R',
817db96d56Sopenharmony_ci  'ru_RU.koi8r': 'KOI8-R',
827db96d56Sopenharmony_ci  'ru_RU.CP1251': 'CP1251',
837db96d56Sopenharmony_ci  'ru_RU.cp1251': 'CP1251',
847db96d56Sopenharmony_ci  'sk_SK': 'ISO8859-2',
857db96d56Sopenharmony_ci  'sk_SK.iso88592': 'ISO8859-2',
867db96d56Sopenharmony_ci  'slovak': 'ISO8859-2',
877db96d56Sopenharmony_ci  'sv_FI': 'ISO8859-1',
887db96d56Sopenharmony_ci  'sv_FI.iso88591': 'ISO8859-1',
897db96d56Sopenharmony_ci  'sv_FI@euro': 'ISO8859-15',
907db96d56Sopenharmony_ci  'sv_FI.iso885915@euro': 'ISO8859-15',
917db96d56Sopenharmony_ci  'uk_UA': 'KOI8-U',
927db96d56Sopenharmony_ci  'uk_UA.koi8u': 'KOI8-U'
937db96d56Sopenharmony_ci}
947db96d56Sopenharmony_ci
957db96d56Sopenharmony_ciintegers = [
967db96d56Sopenharmony_ci  "",
977db96d56Sopenharmony_ci  "1",
987db96d56Sopenharmony_ci  "12",
997db96d56Sopenharmony_ci  "123",
1007db96d56Sopenharmony_ci  "1234",
1017db96d56Sopenharmony_ci  "12345",
1027db96d56Sopenharmony_ci  "123456",
1037db96d56Sopenharmony_ci  "1234567",
1047db96d56Sopenharmony_ci  "12345678",
1057db96d56Sopenharmony_ci  "123456789",
1067db96d56Sopenharmony_ci  "1234567890",
1077db96d56Sopenharmony_ci  "12345678901",
1087db96d56Sopenharmony_ci  "123456789012",
1097db96d56Sopenharmony_ci  "1234567890123",
1107db96d56Sopenharmony_ci  "12345678901234",
1117db96d56Sopenharmony_ci  "123456789012345",
1127db96d56Sopenharmony_ci  "1234567890123456",
1137db96d56Sopenharmony_ci  "12345678901234567",
1147db96d56Sopenharmony_ci  "123456789012345678",
1157db96d56Sopenharmony_ci  "1234567890123456789",
1167db96d56Sopenharmony_ci  "12345678901234567890",
1177db96d56Sopenharmony_ci  "123456789012345678901",
1187db96d56Sopenharmony_ci  "1234567890123456789012",
1197db96d56Sopenharmony_ci]
1207db96d56Sopenharmony_ci
1217db96d56Sopenharmony_cinumbers = [
1227db96d56Sopenharmony_ci  "0", "-0", "+0",
1237db96d56Sopenharmony_ci  "0.0", "-0.0", "+0.0",
1247db96d56Sopenharmony_ci  "0e0", "-0e0", "+0e0",
1257db96d56Sopenharmony_ci  ".0", "-.0",
1267db96d56Sopenharmony_ci  ".1", "-.1",
1277db96d56Sopenharmony_ci  "1.1", "-1.1",
1287db96d56Sopenharmony_ci  "1e1", "-1e1"
1297db96d56Sopenharmony_ci]
1307db96d56Sopenharmony_ci
1317db96d56Sopenharmony_ci# Get the list of available locales.
1327db96d56Sopenharmony_ciif platform.system() == 'Windows':
1337db96d56Sopenharmony_ci    locale_list = windows_lang_strings
1347db96d56Sopenharmony_cielse:
1357db96d56Sopenharmony_ci    locale_list = ['C']
1367db96d56Sopenharmony_ci    if os.path.isfile("/var/lib/locales/supported.d/local"):
1377db96d56Sopenharmony_ci        # On Ubuntu, `locale -a` gives the wrong case for some locales,
1387db96d56Sopenharmony_ci        # so we get the correct names directly:
1397db96d56Sopenharmony_ci        with open("/var/lib/locales/supported.d/local") as f:
1407db96d56Sopenharmony_ci            locale_list = [loc.split()[0] for loc in f.readlines() \
1417db96d56Sopenharmony_ci                           if not loc.startswith('#')]
1427db96d56Sopenharmony_ci    elif find_executable('locale'):
1437db96d56Sopenharmony_ci        locale_list = subprocess.Popen(["locale", "-a"],
1447db96d56Sopenharmony_ci                          stdout=subprocess.PIPE).communicate()[0]
1457db96d56Sopenharmony_ci        try:
1467db96d56Sopenharmony_ci            locale_list = locale_list.decode()
1477db96d56Sopenharmony_ci        except UnicodeDecodeError:
1487db96d56Sopenharmony_ci            # Some distributions insist on using latin-1 characters
1497db96d56Sopenharmony_ci            # in their locale names.
1507db96d56Sopenharmony_ci            locale_list = locale_list.decode('latin-1')
1517db96d56Sopenharmony_ci        locale_list = locale_list.split('\n')
1527db96d56Sopenharmony_citry:
1537db96d56Sopenharmony_ci    locale_list.remove('')
1547db96d56Sopenharmony_ciexcept ValueError:
1557db96d56Sopenharmony_ci    pass
1567db96d56Sopenharmony_ci
1577db96d56Sopenharmony_ci# Debian
1587db96d56Sopenharmony_ciif os.path.isfile("/etc/locale.alias"):
1597db96d56Sopenharmony_ci    with open("/etc/locale.alias") as f:
1607db96d56Sopenharmony_ci        while 1:
1617db96d56Sopenharmony_ci            try:
1627db96d56Sopenharmony_ci                line = f.readline()
1637db96d56Sopenharmony_ci            except UnicodeDecodeError:
1647db96d56Sopenharmony_ci                continue
1657db96d56Sopenharmony_ci            if line == "":
1667db96d56Sopenharmony_ci                break
1677db96d56Sopenharmony_ci            if line.startswith('#'):
1687db96d56Sopenharmony_ci                continue
1697db96d56Sopenharmony_ci            x = line.split()
1707db96d56Sopenharmony_ci            if len(x) == 2:
1717db96d56Sopenharmony_ci                if x[0] in locale_list:
1727db96d56Sopenharmony_ci                    locale_list.remove(x[0])
1737db96d56Sopenharmony_ci
1747db96d56Sopenharmony_ci# FreeBSD
1757db96d56Sopenharmony_ciif platform.system() == 'FreeBSD':
1767db96d56Sopenharmony_ci    # http://www.freebsd.org/cgi/query-pr.cgi?pr=142173
1777db96d56Sopenharmony_ci    # en_GB.US-ASCII has 163 as the currency symbol.
1787db96d56Sopenharmony_ci    for loc in ['it_CH.ISO8859-1', 'it_CH.ISO8859-15', 'it_CH.UTF-8',
1797db96d56Sopenharmony_ci                'it_IT.ISO8859-1', 'it_IT.ISO8859-15', 'it_IT.UTF-8',
1807db96d56Sopenharmony_ci                'sl_SI.ISO8859-2', 'sl_SI.UTF-8',
1817db96d56Sopenharmony_ci                'en_GB.US-ASCII']:
1827db96d56Sopenharmony_ci        try:
1837db96d56Sopenharmony_ci            locale_list.remove(loc)
1847db96d56Sopenharmony_ci        except ValueError:
1857db96d56Sopenharmony_ci            pass
1867db96d56Sopenharmony_ci
1877db96d56Sopenharmony_ci# Print a testcase in the format of the IBM tests (for runtest.c):
1887db96d56Sopenharmony_cidef get_preferred_encoding():
1897db96d56Sopenharmony_ci    loc = locale.setlocale(locale.LC_CTYPE)
1907db96d56Sopenharmony_ci    if loc in preferred_encoding:
1917db96d56Sopenharmony_ci        return preferred_encoding[loc]
1927db96d56Sopenharmony_ci    else:
1937db96d56Sopenharmony_ci        return locale.getpreferredencoding()
1947db96d56Sopenharmony_ci
1957db96d56Sopenharmony_cidef printit(testno, s, fmt, encoding=None):
1967db96d56Sopenharmony_ci    if not encoding:
1977db96d56Sopenharmony_ci        encoding = get_preferred_encoding()
1987db96d56Sopenharmony_ci    try:
1997db96d56Sopenharmony_ci        result = format(P.Decimal(s), fmt)
2007db96d56Sopenharmony_ci        fmt = str(fmt.encode(encoding))[2:-1]
2017db96d56Sopenharmony_ci        result = str(result.encode(encoding))[2:-1]
2027db96d56Sopenharmony_ci        if "'" in result:
2037db96d56Sopenharmony_ci            sys.stdout.write("xfmt%d  format  %s  '%s'  ->  \"%s\"\n"
2047db96d56Sopenharmony_ci                             % (testno, s, fmt, result))
2057db96d56Sopenharmony_ci        else:
2067db96d56Sopenharmony_ci            sys.stdout.write("xfmt%d  format  %s  '%s'  ->  '%s'\n"
2077db96d56Sopenharmony_ci                             % (testno, s, fmt, result))
2087db96d56Sopenharmony_ci    except Exception as err:
2097db96d56Sopenharmony_ci        sys.stderr.write("%s  %s  %s\n" % (err, s, fmt))
2107db96d56Sopenharmony_ci
2117db96d56Sopenharmony_ci
2127db96d56Sopenharmony_ci# Check if an integer can be converted to a valid fill character.
2137db96d56Sopenharmony_cidef check_fillchar(i):
2147db96d56Sopenharmony_ci    try:
2157db96d56Sopenharmony_ci        c = chr(i)
2167db96d56Sopenharmony_ci        c.encode('utf-8').decode()
2177db96d56Sopenharmony_ci        format(P.Decimal(0), c + '<19g')
2187db96d56Sopenharmony_ci        return c
2197db96d56Sopenharmony_ci    except:
2207db96d56Sopenharmony_ci        return None
2217db96d56Sopenharmony_ci
2227db96d56Sopenharmony_ci# Generate all unicode characters that are accepted as
2237db96d56Sopenharmony_ci# fill characters by decimal.py.
2247db96d56Sopenharmony_cidef all_fillchars():
2257db96d56Sopenharmony_ci    for i in range(0, 0x110002):
2267db96d56Sopenharmony_ci        c = check_fillchar(i)
2277db96d56Sopenharmony_ci        if c: yield c
2287db96d56Sopenharmony_ci
2297db96d56Sopenharmony_ci# Return random fill character.
2307db96d56Sopenharmony_cidef rand_fillchar():
2317db96d56Sopenharmony_ci    while 1:
2327db96d56Sopenharmony_ci        i = random.randrange(0, 0x110002)
2337db96d56Sopenharmony_ci        c = check_fillchar(i)
2347db96d56Sopenharmony_ci        if c: return c
2357db96d56Sopenharmony_ci
2367db96d56Sopenharmony_ci# Generate random format strings
2377db96d56Sopenharmony_ci# [[fill]align][sign][#][0][width][.precision][type]
2387db96d56Sopenharmony_cidef rand_format(fill, typespec='EeGgFfn%'):
2397db96d56Sopenharmony_ci    active = sorted(random.sample(range(7), random.randrange(8)))
2407db96d56Sopenharmony_ci    have_align = 0
2417db96d56Sopenharmony_ci    s = ''
2427db96d56Sopenharmony_ci    for elem in active:
2437db96d56Sopenharmony_ci        if elem == 0: # fill+align
2447db96d56Sopenharmony_ci            s += fill
2457db96d56Sopenharmony_ci            s += random.choice('<>=^')
2467db96d56Sopenharmony_ci            have_align = 1
2477db96d56Sopenharmony_ci        elif elem == 1: # sign
2487db96d56Sopenharmony_ci            s += random.choice('+- ')
2497db96d56Sopenharmony_ci        elif elem == 2 and not have_align: # zeropad
2507db96d56Sopenharmony_ci            s += '0'
2517db96d56Sopenharmony_ci        elif elem == 3: # width
2527db96d56Sopenharmony_ci            s += str(random.randrange(1, 100))
2537db96d56Sopenharmony_ci        elif elem == 4: # thousands separator
2547db96d56Sopenharmony_ci            s += ','
2557db96d56Sopenharmony_ci        elif elem == 5: # prec
2567db96d56Sopenharmony_ci            s += '.'
2577db96d56Sopenharmony_ci            s += str(random.randrange(100))
2587db96d56Sopenharmony_ci        elif elem == 6:
2597db96d56Sopenharmony_ci            if 4 in active: c = typespec.replace('n', '')
2607db96d56Sopenharmony_ci            else: c = typespec
2617db96d56Sopenharmony_ci            s += random.choice(c)
2627db96d56Sopenharmony_ci    return s
2637db96d56Sopenharmony_ci
2647db96d56Sopenharmony_ci# Partially brute force all possible format strings containing a thousands
2657db96d56Sopenharmony_ci# separator. Fall back to random where the runtime would become excessive.
2667db96d56Sopenharmony_ci# [[fill]align][sign][#][0][width][,][.precision][type]
2677db96d56Sopenharmony_cidef all_format_sep():
2687db96d56Sopenharmony_ci    for align in ('', '<', '>', '=', '^'):
2697db96d56Sopenharmony_ci        for fill in ('', 'x'):
2707db96d56Sopenharmony_ci            if align == '': fill = ''
2717db96d56Sopenharmony_ci            for sign in ('', '+', '-', ' '):
2727db96d56Sopenharmony_ci                for zeropad in ('', '0'):
2737db96d56Sopenharmony_ci                    if align != '': zeropad = ''
2747db96d56Sopenharmony_ci                    for width in ['']+[str(y) for y in range(1, 15)]+['101']:
2757db96d56Sopenharmony_ci                        for prec in ['']+['.'+str(y) for y in range(15)]:
2767db96d56Sopenharmony_ci                            # for type in ('', 'E', 'e', 'G', 'g', 'F', 'f', '%'):
2777db96d56Sopenharmony_ci                            type = random.choice(('', 'E', 'e', 'G', 'g', 'F', 'f', '%'))
2787db96d56Sopenharmony_ci                            yield ''.join((fill, align, sign, zeropad, width, ',', prec, type))
2797db96d56Sopenharmony_ci
2807db96d56Sopenharmony_ci# Partially brute force all possible format strings with an 'n' specifier.
2817db96d56Sopenharmony_ci# [[fill]align][sign][#][0][width][,][.precision][type]
2827db96d56Sopenharmony_cidef all_format_loc():
2837db96d56Sopenharmony_ci    for align in ('', '<', '>', '=', '^'):
2847db96d56Sopenharmony_ci        for fill in ('', 'x'):
2857db96d56Sopenharmony_ci            if align == '': fill = ''
2867db96d56Sopenharmony_ci            for sign in ('', '+', '-', ' '):
2877db96d56Sopenharmony_ci                for zeropad in ('', '0'):
2887db96d56Sopenharmony_ci                    if align != '': zeropad = ''
2897db96d56Sopenharmony_ci                    for width in ['']+[str(y) for y in range(1, 20)]+['101']:
2907db96d56Sopenharmony_ci                        for prec in ['']+['.'+str(y) for y in range(1, 20)]:
2917db96d56Sopenharmony_ci                            yield ''.join((fill, align, sign, zeropad, width, prec, 'n'))
2927db96d56Sopenharmony_ci
2937db96d56Sopenharmony_ci# Generate random format strings with a unicode fill character
2947db96d56Sopenharmony_ci# [[fill]align][sign][#][0][width][,][.precision][type]
2957db96d56Sopenharmony_cidef randfill(fill):
2967db96d56Sopenharmony_ci    active = sorted(random.sample(range(5), random.randrange(6)))
2977db96d56Sopenharmony_ci    s = ''
2987db96d56Sopenharmony_ci    s += str(fill)
2997db96d56Sopenharmony_ci    s += random.choice('<>=^')
3007db96d56Sopenharmony_ci    for elem in active:
3017db96d56Sopenharmony_ci        if elem == 0: # sign
3027db96d56Sopenharmony_ci            s += random.choice('+- ')
3037db96d56Sopenharmony_ci        elif elem == 1: # width
3047db96d56Sopenharmony_ci            s += str(random.randrange(1, 100))
3057db96d56Sopenharmony_ci        elif elem == 2: # thousands separator
3067db96d56Sopenharmony_ci            s += ','
3077db96d56Sopenharmony_ci        elif elem == 3: # prec
3087db96d56Sopenharmony_ci            s += '.'
3097db96d56Sopenharmony_ci            s += str(random.randrange(100))
3107db96d56Sopenharmony_ci        elif elem == 4:
3117db96d56Sopenharmony_ci            if 2 in active: c = 'EeGgFf%'
3127db96d56Sopenharmony_ci            else: c = 'EeGgFfn%'
3137db96d56Sopenharmony_ci            s += random.choice(c)
3147db96d56Sopenharmony_ci    return s
3157db96d56Sopenharmony_ci
3167db96d56Sopenharmony_ci# Generate random format strings with random locale setting
3177db96d56Sopenharmony_ci# [[fill]align][sign][#][0][width][,][.precision][type]
3187db96d56Sopenharmony_cidef rand_locale():
3197db96d56Sopenharmony_ci    try:
3207db96d56Sopenharmony_ci        loc = random.choice(locale_list)
3217db96d56Sopenharmony_ci        locale.setlocale(locale.LC_ALL, loc)
3227db96d56Sopenharmony_ci    except locale.Error as err:
3237db96d56Sopenharmony_ci        pass
3247db96d56Sopenharmony_ci    active = sorted(random.sample(range(5), random.randrange(6)))
3257db96d56Sopenharmony_ci    s = ''
3267db96d56Sopenharmony_ci    have_align = 0
3277db96d56Sopenharmony_ci    for elem in active:
3287db96d56Sopenharmony_ci        if elem == 0: # fill+align
3297db96d56Sopenharmony_ci            s += chr(random.randrange(32, 128))
3307db96d56Sopenharmony_ci            s += random.choice('<>=^')
3317db96d56Sopenharmony_ci            have_align = 1
3327db96d56Sopenharmony_ci        elif elem == 1: # sign
3337db96d56Sopenharmony_ci            s += random.choice('+- ')
3347db96d56Sopenharmony_ci        elif elem == 2 and not have_align: # zeropad
3357db96d56Sopenharmony_ci            s += '0'
3367db96d56Sopenharmony_ci        elif elem == 3: # width
3377db96d56Sopenharmony_ci            s += str(random.randrange(1, 100))
3387db96d56Sopenharmony_ci        elif elem == 4: # prec
3397db96d56Sopenharmony_ci            s += '.'
3407db96d56Sopenharmony_ci            s += str(random.randrange(100))
3417db96d56Sopenharmony_ci    s += 'n'
3427db96d56Sopenharmony_ci    return s
343