Coverage Report

Created: 2025-10-10 06:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
598k
{
12
598k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
598k
    const void *idata = PyUnicode_DATA(unicode);
14
598k
    int ikind = PyUnicode_KIND(unicode);
15
16
598k
    *odata++ = quote;
17
116M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
116M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
116M
        if ((ch == quote) || (ch == '\\')) {
22
164k
            *odata++ = '\\';
23
164k
            *odata++ = ch;
24
164k
            continue;
25
164k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
116M
        if (ch == '\t') {
29
21.9k
            *odata++ = '\\';
30
21.9k
            *odata++ = 't';
31
21.9k
        }
32
116M
        else if (ch == '\n') {
33
1.82k
            *odata++ = '\\';
34
1.82k
            *odata++ = 'n';
35
1.82k
        }
36
116M
        else if (ch == '\r') {
37
2.56k
            *odata++ = '\\';
38
2.56k
            *odata++ = 'r';
39
2.56k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
116M
        else if (ch < ' ' || ch == 0x7F) {
43
83.4M
            *odata++ = '\\';
44
83.4M
            *odata++ = 'x';
45
83.4M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
83.4M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
83.4M
        }
48
49
        /* Copy ASCII characters as-is */
50
32.5M
        else if (ch < 0x7F) {
51
25.6M
            *odata++ = ch;
52
25.6M
        }
53
54
        /* Non-ASCII characters */
55
6.86M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
6.86M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
98.6k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
98.6k
                if (ch <= 0xff) {
63
26.7k
                    *odata++ = 'x';
64
26.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
26.7k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
26.7k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
71.8k
                else if (ch <= 0xffff) {
69
49.3k
                    *odata++ = 'u';
70
49.3k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
49.3k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
49.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
49.3k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
49.3k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
22.5k
                else {
77
22.5k
                    *odata++ = 'U';
78
22.5k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
22.5k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
22.5k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
22.5k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
22.5k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
22.5k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
22.5k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
22.5k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
22.5k
                }
87
98.6k
            }
88
            /* Copy characters as-is */
89
6.77M
            else {
90
6.77M
                *odata++ = ch;
91
6.77M
            }
92
6.86M
        }
93
116M
    }
94
598k
    *odata = quote;
95
598k
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
381k
{
12
381k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
381k
    const void *idata = PyUnicode_DATA(unicode);
14
381k
    int ikind = PyUnicode_KIND(unicode);
15
16
381k
    *odata++ = quote;
17
24.3M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
23.9M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
23.9M
        if ((ch == quote) || (ch == '\\')) {
22
73.6k
            *odata++ = '\\';
23
73.6k
            *odata++ = ch;
24
73.6k
            continue;
25
73.6k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
23.9M
        if (ch == '\t') {
29
12.7k
            *odata++ = '\\';
30
12.7k
            *odata++ = 't';
31
12.7k
        }
32
23.9M
        else if (ch == '\n') {
33
1.02k
            *odata++ = '\\';
34
1.02k
            *odata++ = 'n';
35
1.02k
        }
36
23.9M
        else if (ch == '\r') {
37
1.43k
            *odata++ = '\\';
38
1.43k
            *odata++ = 'r';
39
1.43k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
23.9M
        else if (ch < ' ' || ch == 0x7F) {
43
17.0M
            *odata++ = '\\';
44
17.0M
            *odata++ = 'x';
45
17.0M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
17.0M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
17.0M
        }
48
49
        /* Copy ASCII characters as-is */
50
6.87M
        else if (ch < 0x7F) {
51
6.82M
            *odata++ = ch;
52
6.82M
        }
53
54
        /* Non-ASCII characters */
55
54.4k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
54.4k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
48.5k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
48.5k
                if (ch <= 0xff) {
63
14.0k
                    *odata++ = 'x';
64
14.0k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
14.0k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
14.0k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
34.5k
                else if (ch <= 0xffff) {
69
31.8k
                    *odata++ = 'u';
70
31.8k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
31.8k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
31.8k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
31.8k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
31.8k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
2.74k
                else {
77
2.74k
                    *odata++ = 'U';
78
2.74k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
2.74k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
2.74k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
2.74k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
2.74k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
2.74k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
2.74k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
2.74k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
2.74k
                }
87
48.5k
            }
88
            /* Copy characters as-is */
89
5.92k
            else {
90
5.92k
                *odata++ = ch;
91
5.92k
            }
92
54.4k
        }
93
23.9M
    }
94
381k
    *odata = quote;
95
381k
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
213k
{
12
213k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
213k
    const void *idata = PyUnicode_DATA(unicode);
14
213k
    int ikind = PyUnicode_KIND(unicode);
15
16
213k
    *odata++ = quote;
17
78.0M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
77.8M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
77.8M
        if ((ch == quote) || (ch == '\\')) {
22
66.3k
            *odata++ = '\\';
23
66.3k
            *odata++ = ch;
24
66.3k
            continue;
25
66.3k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
77.7M
        if (ch == '\t') {
29
8.49k
            *odata++ = '\\';
30
8.49k
            *odata++ = 't';
31
8.49k
        }
32
77.7M
        else if (ch == '\n') {
33
536
            *odata++ = '\\';
34
536
            *odata++ = 'n';
35
536
        }
36
77.7M
        else if (ch == '\r') {
37
629
            *odata++ = '\\';
38
629
            *odata++ = 'r';
39
629
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
77.7M
        else if (ch < ' ' || ch == 0x7F) {
43
52.7M
            *odata++ = '\\';
44
52.7M
            *odata++ = 'x';
45
52.7M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
52.7M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
52.7M
        }
48
49
        /* Copy ASCII characters as-is */
50
24.9M
        else if (ch < 0x7F) {
51
18.2M
            *odata++ = ch;
52
18.2M
        }
53
54
        /* Non-ASCII characters */
55
6.69M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
6.69M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
44.0k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
44.0k
                if (ch <= 0xff) {
63
11.6k
                    *odata++ = 'x';
64
11.6k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
11.6k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
11.6k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
32.4k
                else if (ch <= 0xffff) {
69
13.4k
                    *odata++ = 'u';
70
13.4k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
13.4k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
13.4k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
13.4k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
13.4k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
19.0k
                else {
77
19.0k
                    *odata++ = 'U';
78
19.0k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
19.0k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
19.0k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
19.0k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
19.0k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
19.0k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
19.0k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
19.0k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
19.0k
                }
87
44.0k
            }
88
            /* Copy characters as-is */
89
6.65M
            else {
90
6.65M
                *odata++ = ch;
91
6.65M
            }
92
6.69M
        }
93
77.7M
    }
94
213k
    *odata = quote;
95
213k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
4.10k
{
12
4.10k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
4.10k
    const void *idata = PyUnicode_DATA(unicode);
14
4.10k
    int ikind = PyUnicode_KIND(unicode);
15
16
4.10k
    *odata++ = quote;
17
14.3M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
14.3M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
14.3M
        if ((ch == quote) || (ch == '\\')) {
22
24.5k
            *odata++ = '\\';
23
24.5k
            *odata++ = ch;
24
24.5k
            continue;
25
24.5k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
14.3M
        if (ch == '\t') {
29
721
            *odata++ = '\\';
30
721
            *odata++ = 't';
31
721
        }
32
14.3M
        else if (ch == '\n') {
33
269
            *odata++ = '\\';
34
269
            *odata++ = 'n';
35
269
        }
36
14.3M
        else if (ch == '\r') {
37
496
            *odata++ = '\\';
38
496
            *odata++ = 'r';
39
496
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
14.3M
        else if (ch < ' ' || ch == 0x7F) {
43
13.6M
            *odata++ = '\\';
44
13.6M
            *odata++ = 'x';
45
13.6M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
13.6M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
13.6M
        }
48
49
        /* Copy ASCII characters as-is */
50
690k
        else if (ch < 0x7F) {
51
572k
            *odata++ = ch;
52
572k
        }
53
54
        /* Non-ASCII characters */
55
117k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
117k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
6.04k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
6.04k
                if (ch <= 0xff) {
63
1.15k
                    *odata++ = 'x';
64
1.15k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
1.15k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
1.15k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
4.89k
                else if (ch <= 0xffff) {
69
4.09k
                    *odata++ = 'u';
70
4.09k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
4.09k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
4.09k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
4.09k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
4.09k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
802
                else {
77
802
                    *odata++ = 'U';
78
802
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
802
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
802
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
802
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
802
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
802
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
802
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
802
                    *odata++ = Py_hexdigits[ch & 0xF];
86
802
                }
87
6.04k
            }
88
            /* Copy characters as-is */
89
111k
            else {
90
111k
                *odata++ = ch;
91
111k
            }
92
117k
        }
93
14.3M
    }
94
4.10k
    *odata = quote;
95
4.10k
}