Coverage Report

Created: 2025-08-24 07:03

/src/cpython/Objects/stringlib/repr.h
Line
Count
Source
1
/* stringlib: repr() implementation */
2
3
#ifndef STRINGLIB_FASTSEARCH_H
4
#error must include "stringlib/fastsearch.h" before including this module
5
#endif
6
7
8
static void
9
STRINGLIB(repr)(PyObject *unicode, Py_UCS4 quote,
10
                STRINGLIB_CHAR *odata)
11
523k
{
12
523k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
523k
    const void *idata = PyUnicode_DATA(unicode);
14
523k
    int ikind = PyUnicode_KIND(unicode);
15
16
523k
    *odata++ = quote;
17
110M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
110M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
110M
        if ((ch == quote) || (ch == '\\')) {
22
156k
            *odata++ = '\\';
23
156k
            *odata++ = ch;
24
156k
            continue;
25
156k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
110M
        if (ch == '\t') {
29
16.5k
            *odata++ = '\\';
30
16.5k
            *odata++ = 't';
31
16.5k
        }
32
110M
        else if (ch == '\n') {
33
1.95k
            *odata++ = '\\';
34
1.95k
            *odata++ = 'n';
35
1.95k
        }
36
109M
        else if (ch == '\r') {
37
2.07k
            *odata++ = '\\';
38
2.07k
            *odata++ = 'r';
39
2.07k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
109M
        else if (ch < ' ' || ch == 0x7F) {
43
80.2M
            *odata++ = '\\';
44
80.2M
            *odata++ = 'x';
45
80.2M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
80.2M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
80.2M
        }
48
49
        /* Copy ASCII characters as-is */
50
29.7M
        else if (ch < 0x7F) {
51
23.3M
            *odata++ = ch;
52
23.3M
        }
53
54
        /* Non-ASCII characters */
55
6.36M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
6.36M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
84.8k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
84.8k
                if (ch <= 0xff) {
63
22.9k
                    *odata++ = 'x';
64
22.9k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
22.9k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
22.9k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
61.9k
                else if (ch <= 0xffff) {
69
41.1k
                    *odata++ = 'u';
70
41.1k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
41.1k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
41.1k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
41.1k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
41.1k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
20.7k
                else {
77
20.7k
                    *odata++ = 'U';
78
20.7k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
20.7k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
20.7k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
20.7k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
20.7k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
20.7k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
20.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
20.7k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
20.7k
                }
87
84.8k
            }
88
            /* Copy characters as-is */
89
6.28M
            else {
90
6.28M
                *odata++ = ch;
91
6.28M
            }
92
6.36M
        }
93
110M
    }
94
523k
    *odata = quote;
95
523k
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
336k
{
12
336k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
336k
    const void *idata = PyUnicode_DATA(unicode);
14
336k
    int ikind = PyUnicode_KIND(unicode);
15
16
336k
    *odata++ = quote;
17
23.9M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
23.6M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
23.6M
        if ((ch == quote) || (ch == '\\')) {
22
65.5k
            *odata++ = '\\';
23
65.5k
            *odata++ = ch;
24
65.5k
            continue;
25
65.5k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
23.5M
        if (ch == '\t') {
29
10.4k
            *odata++ = '\\';
30
10.4k
            *odata++ = 't';
31
10.4k
        }
32
23.5M
        else if (ch == '\n') {
33
1.07k
            *odata++ = '\\';
34
1.07k
            *odata++ = 'n';
35
1.07k
        }
36
23.5M
        else if (ch == '\r') {
37
1.24k
            *odata++ = '\\';
38
1.24k
            *odata++ = 'r';
39
1.24k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
23.5M
        else if (ch < ' ' || ch == 0x7F) {
43
17.7M
            *odata++ = '\\';
44
17.7M
            *odata++ = 'x';
45
17.7M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
17.7M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
17.7M
        }
48
49
        /* Copy ASCII characters as-is */
50
5.81M
        else if (ch < 0x7F) {
51
5.76M
            *odata++ = ch;
52
5.76M
        }
53
54
        /* Non-ASCII characters */
55
46.4k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
46.4k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
40.2k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
40.2k
                if (ch <= 0xff) {
63
11.3k
                    *odata++ = 'x';
64
11.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
11.3k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
11.3k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
28.9k
                else if (ch <= 0xffff) {
69
26.6k
                    *odata++ = 'u';
70
26.6k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
26.6k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
26.6k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
26.6k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
26.6k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
2.23k
                else {
77
2.23k
                    *odata++ = 'U';
78
2.23k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
2.23k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
2.23k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
2.23k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
2.23k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
2.23k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
2.23k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
2.23k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
2.23k
                }
87
40.2k
            }
88
            /* Copy characters as-is */
89
6.16k
            else {
90
6.16k
                *odata++ = ch;
91
6.16k
            }
92
46.4k
        }
93
23.5M
    }
94
336k
    *odata = quote;
95
336k
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
184k
{
12
184k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
184k
    const void *idata = PyUnicode_DATA(unicode);
14
184k
    int ikind = PyUnicode_KIND(unicode);
15
16
184k
    *odata++ = quote;
17
71.3M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
71.1M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
71.1M
        if ((ch == quote) || (ch == '\\')) {
22
69.9k
            *odata++ = '\\';
23
69.9k
            *odata++ = ch;
24
69.9k
            continue;
25
69.9k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
71.1M
        if (ch == '\t') {
29
5.17k
            *odata++ = '\\';
30
5.17k
            *odata++ = 't';
31
5.17k
        }
32
71.1M
        else if (ch == '\n') {
33
620
            *odata++ = '\\';
34
620
            *odata++ = 'n';
35
620
        }
36
71.1M
        else if (ch == '\r') {
37
450
            *odata++ = '\\';
38
450
            *odata++ = 'r';
39
450
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
71.1M
        else if (ch < ' ' || ch == 0x7F) {
43
47.9M
            *odata++ = '\\';
44
47.9M
            *odata++ = 'x';
45
47.9M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
47.9M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
47.9M
        }
48
49
        /* Copy ASCII characters as-is */
50
23.1M
        else if (ch < 0x7F) {
51
16.9M
            *odata++ = ch;
52
16.9M
        }
53
54
        /* Non-ASCII characters */
55
6.21M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
6.21M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
39.3k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
39.3k
                if (ch <= 0xff) {
63
10.3k
                    *odata++ = 'x';
64
10.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
10.3k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
10.3k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
29.0k
                else if (ch <= 0xffff) {
69
11.4k
                    *odata++ = 'u';
70
11.4k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
11.4k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
11.4k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
11.4k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
11.4k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
17.6k
                else {
77
17.6k
                    *odata++ = 'U';
78
17.6k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
17.6k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
17.6k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
17.6k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
17.6k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
17.6k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
17.6k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
17.6k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
17.6k
                }
87
39.3k
            }
88
            /* Copy characters as-is */
89
6.18M
            else {
90
6.18M
                *odata++ = ch;
91
6.18M
            }
92
6.21M
        }
93
71.1M
    }
94
184k
    *odata = quote;
95
184k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
3.41k
{
12
3.41k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
3.41k
    const void *idata = PyUnicode_DATA(unicode);
14
3.41k
    int ikind = PyUnicode_KIND(unicode);
15
16
3.41k
    *odata++ = quote;
17
15.3M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
15.3M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
15.3M
        if ((ch == quote) || (ch == '\\')) {
22
21.1k
            *odata++ = '\\';
23
21.1k
            *odata++ = ch;
24
21.1k
            continue;
25
21.1k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
15.3M
        if (ch == '\t') {
29
967
            *odata++ = '\\';
30
967
            *odata++ = 't';
31
967
        }
32
15.3M
        else if (ch == '\n') {
33
269
            *odata++ = '\\';
34
269
            *odata++ = 'n';
35
269
        }
36
15.3M
        else if (ch == '\r') {
37
379
            *odata++ = '\\';
38
379
            *odata++ = 'r';
39
379
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
15.3M
        else if (ch < ' ' || ch == 0x7F) {
43
14.6M
            *odata++ = '\\';
44
14.6M
            *odata++ = 'x';
45
14.6M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
14.6M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
14.6M
        }
48
49
        /* Copy ASCII characters as-is */
50
729k
        else if (ch < 0x7F) {
51
626k
            *odata++ = ch;
52
626k
        }
53
54
        /* Non-ASCII characters */
55
102k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
102k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
5.18k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
5.18k
                if (ch <= 0xff) {
63
1.20k
                    *odata++ = 'x';
64
1.20k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
1.20k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
1.20k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
3.98k
                else if (ch <= 0xffff) {
69
3.07k
                    *odata++ = 'u';
70
3.07k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
3.07k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
3.07k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
3.07k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
3.07k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
903
                else {
77
903
                    *odata++ = 'U';
78
903
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
903
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
903
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
903
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
903
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
903
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
903
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
903
                    *odata++ = Py_hexdigits[ch & 0xF];
86
903
                }
87
5.18k
            }
88
            /* Copy characters as-is */
89
97.6k
            else {
90
97.6k
                *odata++ = ch;
91
97.6k
            }
92
102k
        }
93
15.3M
    }
94
3.41k
    *odata = quote;
95
3.41k
}