Coverage Report

Created: 2025-11-30 06:38

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
7.61M
{
12
7.61M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
7.61M
    const void *idata = PyUnicode_DATA(unicode);
14
7.61M
    int ikind = PyUnicode_KIND(unicode);
15
16
7.61M
    *odata++ = quote;
17
200M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
193M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
193M
        if ((ch == quote) || (ch == '\\')) {
22
234k
            *odata++ = '\\';
23
234k
            *odata++ = ch;
24
234k
            continue;
25
234k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
193M
        if (ch == '\t') {
29
463k
            *odata++ = '\\';
30
463k
            *odata++ = 't';
31
463k
        }
32
192M
        else if (ch == '\n') {
33
5.36M
            *odata++ = '\\';
34
5.36M
            *odata++ = 'n';
35
5.36M
        }
36
187M
        else if (ch == '\r') {
37
85.6k
            *odata++ = '\\';
38
85.6k
            *odata++ = 'r';
39
85.6k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
187M
        else if (ch < ' ' || ch == 0x7F) {
43
131M
            *odata++ = '\\';
44
131M
            *odata++ = 'x';
45
131M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
131M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
131M
        }
48
49
        /* Copy ASCII characters as-is */
50
55.8M
        else if (ch < 0x7F) {
51
45.0M
            *odata++ = ch;
52
45.0M
        }
53
54
        /* Non-ASCII characters */
55
10.7M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
10.7M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
222k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
222k
                if (ch <= 0xff) {
63
45.8k
                    *odata++ = 'x';
64
45.8k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
45.8k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
45.8k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
176k
                else if (ch <= 0xffff) {
69
103k
                    *odata++ = 'u';
70
103k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
103k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
103k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
103k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
103k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
72.5k
                else {
77
72.5k
                    *odata++ = 'U';
78
72.5k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
72.5k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
72.5k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
72.5k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
72.5k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
72.5k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
72.5k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
72.5k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
72.5k
                }
87
222k
            }
88
            /* Copy characters as-is */
89
10.5M
            else {
90
10.5M
                *odata++ = ch;
91
10.5M
            }
92
10.7M
        }
93
193M
    }
94
7.61M
    *odata = quote;
95
7.61M
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
7.30M
{
12
7.30M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
7.30M
    const void *idata = PyUnicode_DATA(unicode);
14
7.30M
    int ikind = PyUnicode_KIND(unicode);
15
16
7.30M
    *odata++ = quote;
17
73.5M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
66.2M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
66.2M
        if ((ch == quote) || (ch == '\\')) {
22
157k
            *odata++ = '\\';
23
157k
            *odata++ = ch;
24
157k
            continue;
25
157k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
66.1M
        if (ch == '\t') {
29
439k
            *odata++ = '\\';
30
439k
            *odata++ = 't';
31
439k
        }
32
65.6M
        else if (ch == '\n') {
33
5.08M
            *odata++ = '\\';
34
5.08M
            *odata++ = 'n';
35
5.08M
        }
36
60.5M
        else if (ch == '\r') {
37
44.4k
            *odata++ = '\\';
38
44.4k
            *odata++ = 'r';
39
44.4k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
60.5M
        else if (ch < ' ' || ch == 0x7F) {
43
39.0M
            *odata++ = '\\';
44
39.0M
            *odata++ = 'x';
45
39.0M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
39.0M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
39.0M
        }
48
49
        /* Copy ASCII characters as-is */
50
21.5M
        else if (ch < 0x7F) {
51
21.4M
            *odata++ = ch;
52
21.4M
        }
53
54
        /* Non-ASCII characters */
55
70.6k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
70.6k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
57.0k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
57.0k
                if (ch <= 0xff) {
63
17.2k
                    *odata++ = 'x';
64
17.2k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
17.2k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
17.2k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
39.8k
                else if (ch <= 0xffff) {
69
35.6k
                    *odata++ = 'u';
70
35.6k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
35.6k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
35.6k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
35.6k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
35.6k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
4.19k
                else {
77
4.19k
                    *odata++ = 'U';
78
4.19k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
4.19k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
4.19k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
4.19k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
4.19k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
4.19k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
4.19k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
4.19k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
4.19k
                }
87
57.0k
            }
88
            /* Copy characters as-is */
89
13.5k
            else {
90
13.5k
                *odata++ = ch;
91
13.5k
            }
92
70.6k
        }
93
66.1M
    }
94
7.30M
    *odata = quote;
95
7.30M
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
306k
{
12
306k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
306k
    const void *idata = PyUnicode_DATA(unicode);
14
306k
    int ikind = PyUnicode_KIND(unicode);
15
16
306k
    *odata++ = quote;
17
112M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
111M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
111M
        if ((ch == quote) || (ch == '\\')) {
22
69.8k
            *odata++ = '\\';
23
69.8k
            *odata++ = ch;
24
69.8k
            continue;
25
69.8k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
111M
        if (ch == '\t') {
29
22.3k
            *odata++ = '\\';
30
22.3k
            *odata++ = 't';
31
22.3k
        }
32
111M
        else if (ch == '\n') {
33
276k
            *odata++ = '\\';
34
276k
            *odata++ = 'n';
35
276k
        }
36
111M
        else if (ch == '\r') {
37
38.6k
            *odata++ = '\\';
38
38.6k
            *odata++ = 'r';
39
38.6k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
111M
        else if (ch < ' ' || ch == 0x7F) {
43
79.2M
            *odata++ = '\\';
44
79.2M
            *odata++ = 'x';
45
79.2M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
79.2M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
79.2M
        }
48
49
        /* Copy ASCII characters as-is */
50
32.3M
        else if (ch < 0x7F) {
51
21.9M
            *odata++ = ch;
52
21.9M
        }
53
54
        /* Non-ASCII characters */
55
10.4M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
10.4M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
73.4k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
73.4k
                if (ch <= 0xff) {
63
26.9k
                    *odata++ = 'x';
64
26.9k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
26.9k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
26.9k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
46.5k
                else if (ch <= 0xffff) {
69
21.3k
                    *odata++ = 'u';
70
21.3k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
21.3k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
21.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
21.3k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
21.3k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
25.1k
                else {
77
25.1k
                    *odata++ = 'U';
78
25.1k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
25.1k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
25.1k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
25.1k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
25.1k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
25.1k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
25.1k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
25.1k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
25.1k
                }
87
73.4k
            }
88
            /* Copy characters as-is */
89
10.3M
            else {
90
10.3M
                *odata++ = ch;
91
10.3M
            }
92
10.4M
        }
93
111M
    }
94
306k
    *odata = quote;
95
306k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
5.71k
{
12
5.71k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
5.71k
    const void *idata = PyUnicode_DATA(unicode);
14
5.71k
    int ikind = PyUnicode_KIND(unicode);
15
16
5.71k
    *odata++ = quote;
17
15.0M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
15.0M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
15.0M
        if ((ch == quote) || (ch == '\\')) {
22
7.75k
            *odata++ = '\\';
23
7.75k
            *odata++ = ch;
24
7.75k
            continue;
25
7.75k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
15.0M
        if (ch == '\t') {
29
1.60k
            *odata++ = '\\';
30
1.60k
            *odata++ = 't';
31
1.60k
        }
32
15.0M
        else if (ch == '\n') {
33
3.03k
            *odata++ = '\\';
34
3.03k
            *odata++ = 'n';
35
3.03k
        }
36
15.0M
        else if (ch == '\r') {
37
2.53k
            *odata++ = '\\';
38
2.53k
            *odata++ = 'r';
39
2.53k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
15.0M
        else if (ch < ' ' || ch == 0x7F) {
43
13.0M
            *odata++ = '\\';
44
13.0M
            *odata++ = 'x';
45
13.0M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
13.0M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
13.0M
        }
48
49
        /* Copy ASCII characters as-is */
50
1.98M
        else if (ch < 0x7F) {
51
1.67M
            *odata++ = ch;
52
1.67M
        }
53
54
        /* Non-ASCII characters */
55
306k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
306k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
91.5k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
91.5k
                if (ch <= 0xff) {
63
1.72k
                    *odata++ = 'x';
64
1.72k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
1.72k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
1.72k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
89.8k
                else if (ch <= 0xffff) {
69
46.5k
                    *odata++ = 'u';
70
46.5k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
46.5k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
46.5k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
46.5k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
46.5k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
43.2k
                else {
77
43.2k
                    *odata++ = 'U';
78
43.2k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
43.2k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
43.2k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
43.2k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
43.2k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
43.2k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
43.2k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
43.2k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
43.2k
                }
87
91.5k
            }
88
            /* Copy characters as-is */
89
215k
            else {
90
215k
                *odata++ = ch;
91
215k
            }
92
306k
        }
93
15.0M
    }
94
5.71k
    *odata = quote;
95
5.71k
}