Coverage Report

Created: 2025-10-12 06:48

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
632k
{
12
632k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
632k
    const void *idata = PyUnicode_DATA(unicode);
14
632k
    int ikind = PyUnicode_KIND(unicode);
15
16
632k
    *odata++ = quote;
17
121M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
121M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
121M
        if ((ch == quote) || (ch == '\\')) {
22
179k
            *odata++ = '\\';
23
179k
            *odata++ = ch;
24
179k
            continue;
25
179k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
120M
        if (ch == '\t') {
29
21.4k
            *odata++ = '\\';
30
21.4k
            *odata++ = 't';
31
21.4k
        }
32
120M
        else if (ch == '\n') {
33
1.82k
            *odata++ = '\\';
34
1.82k
            *odata++ = 'n';
35
1.82k
        }
36
120M
        else if (ch == '\r') {
37
2.47k
            *odata++ = '\\';
38
2.47k
            *odata++ = 'r';
39
2.47k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
120M
        else if (ch < ' ' || ch == 0x7F) {
43
89.2M
            *odata++ = '\\';
44
89.2M
            *odata++ = 'x';
45
89.2M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
89.2M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
89.2M
        }
48
49
        /* Copy ASCII characters as-is */
50
31.6M
        else if (ch < 0x7F) {
51
25.5M
            *odata++ = ch;
52
25.5M
        }
53
54
        /* Non-ASCII characters */
55
6.13M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
6.13M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
103k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
103k
                if (ch <= 0xff) {
63
28.8k
                    *odata++ = 'x';
64
28.8k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
28.8k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
28.8k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
74.8k
                else if (ch <= 0xffff) {
69
52.0k
                    *odata++ = 'u';
70
52.0k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
52.0k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
52.0k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
52.0k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
52.0k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
22.7k
                else {
77
22.7k
                    *odata++ = 'U';
78
22.7k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
22.7k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
22.7k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
22.7k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
22.7k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
22.7k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
22.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
22.7k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
22.7k
                }
87
103k
            }
88
            /* Copy characters as-is */
89
6.02M
            else {
90
6.02M
                *odata++ = ch;
91
6.02M
            }
92
6.13M
        }
93
120M
    }
94
632k
    *odata = quote;
95
632k
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
409k
{
12
409k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
409k
    const void *idata = PyUnicode_DATA(unicode);
14
409k
    int ikind = PyUnicode_KIND(unicode);
15
16
409k
    *odata++ = quote;
17
26.5M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
26.1M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
26.1M
        if ((ch == quote) || (ch == '\\')) {
22
85.9k
            *odata++ = '\\';
23
85.9k
            *odata++ = ch;
24
85.9k
            continue;
25
85.9k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
26.0M
        if (ch == '\t') {
29
12.6k
            *odata++ = '\\';
30
12.6k
            *odata++ = 't';
31
12.6k
        }
32
26.0M
        else if (ch == '\n') {
33
1.02k
            *odata++ = '\\';
34
1.02k
            *odata++ = 'n';
35
1.02k
        }
36
26.0M
        else if (ch == '\r') {
37
1.33k
            *odata++ = '\\';
38
1.33k
            *odata++ = 'r';
39
1.33k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
26.0M
        else if (ch < ' ' || ch == 0x7F) {
43
19.0M
            *odata++ = '\\';
44
19.0M
            *odata++ = 'x';
45
19.0M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
19.0M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
19.0M
        }
48
49
        /* Copy ASCII characters as-is */
50
6.97M
        else if (ch < 0x7F) {
51
6.92M
            *odata++ = ch;
52
6.92M
        }
53
54
        /* Non-ASCII characters */
55
58.9k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
58.9k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
53.1k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
53.1k
                if (ch <= 0xff) {
63
15.0k
                    *odata++ = 'x';
64
15.0k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
15.0k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
15.0k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
38.0k
                else if (ch <= 0xffff) {
69
34.2k
                    *odata++ = 'u';
70
34.2k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
34.2k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
34.2k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
34.2k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
34.2k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
3.79k
                else {
77
3.79k
                    *odata++ = 'U';
78
3.79k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
3.79k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
3.79k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
3.79k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
3.79k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
3.79k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
3.79k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
3.79k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
3.79k
                }
87
53.1k
            }
88
            /* Copy characters as-is */
89
5.82k
            else {
90
5.82k
                *odata++ = ch;
91
5.82k
            }
92
58.9k
        }
93
26.0M
    }
94
409k
    *odata = quote;
95
409k
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
218k
{
12
218k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
218k
    const void *idata = PyUnicode_DATA(unicode);
14
218k
    int ikind = PyUnicode_KIND(unicode);
15
16
218k
    *odata++ = quote;
17
78.8M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
78.5M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
78.5M
        if ((ch == quote) || (ch == '\\')) {
22
68.6k
            *odata++ = '\\';
23
68.6k
            *odata++ = ch;
24
68.6k
            continue;
25
68.6k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
78.5M
        if (ch == '\t') {
29
8.02k
            *odata++ = '\\';
30
8.02k
            *odata++ = 't';
31
8.02k
        }
32
78.5M
        else if (ch == '\n') {
33
534
            *odata++ = '\\';
34
534
            *odata++ = 'n';
35
534
        }
36
78.5M
        else if (ch == '\r') {
37
629
            *odata++ = '\\';
38
629
            *odata++ = 'r';
39
629
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
78.5M
        else if (ch < ' ' || ch == 0x7F) {
43
54.5M
            *odata++ = '\\';
44
54.5M
            *odata++ = 'x';
45
54.5M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
54.5M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
54.5M
        }
48
49
        /* Copy ASCII characters as-is */
50
23.9M
        else if (ch < 0x7F) {
51
18.0M
            *odata++ = ch;
52
18.0M
        }
53
54
        /* Non-ASCII characters */
55
5.95M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
5.95M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
44.3k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
44.3k
                if (ch <= 0xff) {
63
12.6k
                    *odata++ = 'x';
64
12.6k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
12.6k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
12.6k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
31.7k
                else if (ch <= 0xffff) {
69
13.5k
                    *odata++ = 'u';
70
13.5k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
13.5k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
13.5k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
13.5k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
13.5k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
18.1k
                else {
77
18.1k
                    *odata++ = 'U';
78
18.1k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
18.1k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
18.1k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
18.1k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
18.1k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
18.1k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
18.1k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
18.1k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
18.1k
                }
87
44.3k
            }
88
            /* Copy characters as-is */
89
5.90M
            else {
90
5.90M
                *odata++ = ch;
91
5.90M
            }
92
5.95M
        }
93
78.5M
    }
94
218k
    *odata = quote;
95
218k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
4.14k
{
12
4.14k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
4.14k
    const void *idata = PyUnicode_DATA(unicode);
14
4.14k
    int ikind = PyUnicode_KIND(unicode);
15
16
4.14k
    *odata++ = quote;
17
16.4M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
16.4M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
16.4M
        if ((ch == quote) || (ch == '\\')) {
22
24.4k
            *odata++ = '\\';
23
24.4k
            *odata++ = ch;
24
24.4k
            continue;
25
24.4k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
16.3M
        if (ch == '\t') {
29
753
            *odata++ = '\\';
30
753
            *odata++ = 't';
31
753
        }
32
16.3M
        else if (ch == '\n') {
33
269
            *odata++ = '\\';
34
269
            *odata++ = 'n';
35
269
        }
36
16.3M
        else if (ch == '\r') {
37
509
            *odata++ = '\\';
38
509
            *odata++ = 'r';
39
509
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
16.3M
        else if (ch < ' ' || ch == 0x7F) {
43
15.6M
            *odata++ = '\\';
44
15.6M
            *odata++ = 'x';
45
15.6M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
15.6M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
15.6M
        }
48
49
        /* Copy ASCII characters as-is */
50
704k
        else if (ch < 0x7F) {
51
585k
            *odata++ = ch;
52
585k
        }
53
54
        /* Non-ASCII characters */
55
119k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
119k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
6.19k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
6.19k
                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
5.04k
                else if (ch <= 0xffff) {
69
4.24k
                    *odata++ = 'u';
70
4.24k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
4.24k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
4.24k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
4.24k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
4.24k
                }
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.19k
            }
88
            /* Copy characters as-is */
89
112k
            else {
90
112k
                *odata++ = ch;
91
112k
            }
92
119k
        }
93
16.3M
    }
94
4.14k
    *odata = quote;
95
4.14k
}