Coverage Report

Created: 2025-12-07 07:03

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
6.84M
{
12
6.84M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
6.84M
    const void *idata = PyUnicode_DATA(unicode);
14
6.84M
    int ikind = PyUnicode_KIND(unicode);
15
16
6.84M
    *odata++ = quote;
17
190M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
183M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
183M
        if ((ch == quote) || (ch == '\\')) {
22
212k
            *odata++ = '\\';
23
212k
            *odata++ = ch;
24
212k
            continue;
25
212k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
183M
        if (ch == '\t') {
29
456k
            *odata++ = '\\';
30
456k
            *odata++ = 't';
31
456k
        }
32
183M
        else if (ch == '\n') {
33
4.93M
            *odata++ = '\\';
34
4.93M
            *odata++ = 'n';
35
4.93M
        }
36
178M
        else if (ch == '\r') {
37
84.8k
            *odata++ = '\\';
38
84.8k
            *odata++ = 'r';
39
84.8k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
178M
        else if (ch < ' ' || ch == 0x7F) {
43
123M
            *odata++ = '\\';
44
123M
            *odata++ = 'x';
45
123M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
123M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
123M
        }
48
49
        /* Copy ASCII characters as-is */
50
54.9M
        else if (ch < 0x7F) {
51
44.1M
            *odata++ = ch;
52
44.1M
        }
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
226k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
226k
                if (ch <= 0xff) {
63
54.1k
                    *odata++ = 'x';
64
54.1k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
54.1k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
54.1k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
172k
                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
68.6k
                else {
77
68.6k
                    *odata++ = 'U';
78
68.6k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
68.6k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
68.6k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
68.6k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
68.6k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
68.6k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
68.6k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
68.6k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
68.6k
                }
87
226k
            }
88
            /* Copy characters as-is */
89
10.5M
            else {
90
10.5M
                *odata++ = ch;
91
10.5M
            }
92
10.7M
        }
93
183M
    }
94
6.84M
    *odata = quote;
95
6.84M
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
6.55M
{
12
6.55M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
6.55M
    const void *idata = PyUnicode_DATA(unicode);
14
6.55M
    int ikind = PyUnicode_KIND(unicode);
15
16
6.55M
    *odata++ = quote;
17
69.3M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
62.8M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
62.8M
        if ((ch == quote) || (ch == '\\')) {
22
139k
            *odata++ = '\\';
23
139k
            *odata++ = ch;
24
139k
            continue;
25
139k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
62.6M
        if (ch == '\t') {
29
434k
            *odata++ = '\\';
30
434k
            *odata++ = 't';
31
434k
        }
32
62.2M
        else if (ch == '\n') {
33
4.71M
            *odata++ = '\\';
34
4.71M
            *odata++ = 'n';
35
4.71M
        }
36
57.5M
        else if (ch == '\r') {
37
44.2k
            *odata++ = '\\';
38
44.2k
            *odata++ = 'r';
39
44.2k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
57.4M
        else if (ch < ' ' || ch == 0x7F) {
43
35.8M
            *odata++ = '\\';
44
35.8M
            *odata++ = 'x';
45
35.8M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
35.8M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
35.8M
        }
48
49
        /* Copy ASCII characters as-is */
50
21.6M
        else if (ch < 0x7F) {
51
21.5M
            *odata++ = ch;
52
21.5M
        }
53
54
        /* Non-ASCII characters */
55
76.8k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
76.8k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
67.6k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
67.6k
                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
44.6k
                else if (ch <= 0xffff) {
69
40.3k
                    *odata++ = 'u';
70
40.3k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
40.3k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
40.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
40.3k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
40.3k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
4.26k
                else {
77
4.26k
                    *odata++ = 'U';
78
4.26k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
4.26k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
4.26k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
4.26k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
4.26k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
4.26k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
4.26k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
4.26k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
4.26k
                }
87
67.6k
            }
88
            /* Copy characters as-is */
89
9.17k
            else {
90
9.17k
                *odata++ = ch;
91
9.17k
            }
92
76.8k
        }
93
62.6M
    }
94
6.55M
    *odata = quote;
95
6.55M
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
289k
{
12
289k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
289k
    const void *idata = PyUnicode_DATA(unicode);
14
289k
    int ikind = PyUnicode_KIND(unicode);
15
16
289k
    *odata++ = quote;
17
107M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
107M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
107M
        if ((ch == quote) || (ch == '\\')) {
22
64.2k
            *odata++ = '\\';
23
64.2k
            *odata++ = ch;
24
64.2k
            continue;
25
64.2k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
107M
        if (ch == '\t') {
29
19.9k
            *odata++ = '\\';
30
19.9k
            *odata++ = 't';
31
19.9k
        }
32
107M
        else if (ch == '\n') {
33
224k
            *odata++ = '\\';
34
224k
            *odata++ = 'n';
35
224k
        }
36
107M
        else if (ch == '\r') {
37
37.8k
            *odata++ = '\\';
38
37.8k
            *odata++ = 'r';
39
37.8k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
107M
        else if (ch < ' ' || ch == 0x7F) {
43
74.8M
            *odata++ = '\\';
44
74.8M
            *odata++ = 'x';
45
74.8M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
74.8M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
74.8M
        }
48
49
        /* Copy ASCII characters as-is */
50
32.3M
        else if (ch < 0x7F) {
51
21.8M
            *odata++ = ch;
52
21.8M
        }
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
74.0k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
74.0k
                if (ch <= 0xff) {
63
29.4k
                    *odata++ = 'x';
64
29.4k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
29.4k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
29.4k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
44.5k
                else if (ch <= 0xffff) {
69
20.2k
                    *odata++ = 'u';
70
20.2k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
20.2k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
20.2k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
20.2k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
20.2k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
24.3k
                else {
77
24.3k
                    *odata++ = 'U';
78
24.3k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
24.3k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
24.3k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
24.3k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
24.3k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
24.3k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
24.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
24.3k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
24.3k
                }
87
74.0k
            }
88
            /* Copy characters as-is */
89
10.3M
            else {
90
10.3M
                *odata++ = ch;
91
10.3M
            }
92
10.4M
        }
93
107M
    }
94
289k
    *odata = quote;
95
289k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
5.57k
{
12
5.57k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
5.57k
    const void *idata = PyUnicode_DATA(unicode);
14
5.57k
    int ikind = PyUnicode_KIND(unicode);
15
16
5.57k
    *odata++ = quote;
17
13.4M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
13.4M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
13.4M
        if ((ch == quote) || (ch == '\\')) {
22
8.24k
            *odata++ = '\\';
23
8.24k
            *odata++ = ch;
24
8.24k
            continue;
25
8.24k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
13.4M
        if (ch == '\t') {
29
1.69k
            *odata++ = '\\';
30
1.69k
            *odata++ = 't';
31
1.69k
        }
32
13.4M
        else if (ch == '\n') {
33
3.40k
            *odata++ = '\\';
34
3.40k
            *odata++ = 'n';
35
3.40k
        }
36
13.4M
        else if (ch == '\r') {
37
2.69k
            *odata++ = '\\';
38
2.69k
            *odata++ = 'r';
39
2.69k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
13.4M
        else if (ch < ' ' || ch == 0x7F) {
43
12.4M
            *odata++ = '\\';
44
12.4M
            *odata++ = 'x';
45
12.4M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
12.4M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
12.4M
        }
48
49
        /* Copy ASCII characters as-is */
50
985k
        else if (ch < 0x7F) {
51
690k
            *odata++ = ch;
52
690k
        }
53
54
        /* Non-ASCII characters */
55
294k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
294k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
84.4k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
84.4k
                if (ch <= 0xff) {
63
1.64k
                    *odata++ = 'x';
64
1.64k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
1.64k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
1.64k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
82.8k
                else if (ch <= 0xffff) {
69
42.6k
                    *odata++ = 'u';
70
42.6k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
42.6k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
42.6k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
42.6k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
42.6k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
40.1k
                else {
77
40.1k
                    *odata++ = 'U';
78
40.1k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
40.1k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
40.1k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
40.1k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
40.1k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
40.1k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
40.1k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
40.1k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
40.1k
                }
87
84.4k
            }
88
            /* Copy characters as-is */
89
210k
            else {
90
210k
                *odata++ = ch;
91
210k
            }
92
294k
        }
93
13.4M
    }
94
5.57k
    *odata = quote;
95
5.57k
}