Coverage Report

Created: 2025-11-02 06:30

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
699k
{
12
699k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
699k
    const void *idata = PyUnicode_DATA(unicode);
14
699k
    int ikind = PyUnicode_KIND(unicode);
15
16
699k
    *odata++ = quote;
17
106M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
106M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
106M
        if ((ch == quote) || (ch == '\\')) {
22
263k
            *odata++ = '\\';
23
263k
            *odata++ = ch;
24
263k
            continue;
25
263k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
105M
        if (ch == '\t') {
29
21.4k
            *odata++ = '\\';
30
21.4k
            *odata++ = 't';
31
21.4k
        }
32
105M
        else if (ch == '\n') {
33
1.83k
            *odata++ = '\\';
34
1.83k
            *odata++ = 'n';
35
1.83k
        }
36
105M
        else if (ch == '\r') {
37
2.19k
            *odata++ = '\\';
38
2.19k
            *odata++ = 'r';
39
2.19k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
105M
        else if (ch < ' ' || ch == 0x7F) {
43
76.5M
            *odata++ = '\\';
44
76.5M
            *odata++ = 'x';
45
76.5M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
76.5M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
76.5M
        }
48
49
        /* Copy ASCII characters as-is */
50
29.4M
        else if (ch < 0x7F) {
51
23.6M
            *odata++ = ch;
52
23.6M
        }
53
54
        /* Non-ASCII characters */
55
5.81M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
5.81M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
95.8k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
95.8k
                if (ch <= 0xff) {
63
28.6k
                    *odata++ = 'x';
64
28.6k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
28.6k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
28.6k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
67.1k
                else if (ch <= 0xffff) {
69
49.8k
                    *odata++ = 'u';
70
49.8k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
49.8k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
49.8k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
49.8k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
49.8k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
17.2k
                else {
77
17.2k
                    *odata++ = 'U';
78
17.2k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
17.2k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
17.2k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
17.2k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
17.2k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
17.2k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
17.2k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
17.2k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
17.2k
                }
87
95.8k
            }
88
            /* Copy characters as-is */
89
5.71M
            else {
90
5.71M
                *odata++ = ch;
91
5.71M
            }
92
5.81M
        }
93
105M
    }
94
699k
    *odata = quote;
95
699k
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
482k
{
12
482k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
482k
    const void *idata = PyUnicode_DATA(unicode);
14
482k
    int ikind = PyUnicode_KIND(unicode);
15
16
482k
    *odata++ = quote;
17
23.9M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
23.4M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
23.4M
        if ((ch == quote) || (ch == '\\')) {
22
185k
            *odata++ = '\\';
23
185k
            *odata++ = ch;
24
185k
            continue;
25
185k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
23.2M
        if (ch == '\t') {
29
13.0k
            *odata++ = '\\';
30
13.0k
            *odata++ = 't';
31
13.0k
        }
32
23.2M
        else if (ch == '\n') {
33
1.03k
            *odata++ = '\\';
34
1.03k
            *odata++ = 'n';
35
1.03k
        }
36
23.2M
        else if (ch == '\r') {
37
1.16k
            *odata++ = '\\';
38
1.16k
            *odata++ = 'r';
39
1.16k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
23.2M
        else if (ch < ' ' || ch == 0x7F) {
43
16.5M
            *odata++ = '\\';
44
16.5M
            *odata++ = 'x';
45
16.5M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
16.5M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
16.5M
        }
48
49
        /* Copy ASCII characters as-is */
50
6.76M
        else if (ch < 0x7F) {
51
6.71M
            *odata++ = ch;
52
6.71M
        }
53
54
        /* Non-ASCII characters */
55
54.5k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
54.5k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
47.5k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
47.5k
                if (ch <= 0xff) {
63
15.4k
                    *odata++ = 'x';
64
15.4k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
15.4k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
15.4k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
32.1k
                else if (ch <= 0xffff) {
69
29.5k
                    *odata++ = 'u';
70
29.5k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
29.5k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
29.5k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
29.5k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
29.5k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
2.63k
                else {
77
2.63k
                    *odata++ = 'U';
78
2.63k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
2.63k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
2.63k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
2.63k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
2.63k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
2.63k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
2.63k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
2.63k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
2.63k
                }
87
47.5k
            }
88
            /* Copy characters as-is */
89
6.98k
            else {
90
6.98k
                *odata++ = ch;
91
6.98k
            }
92
54.5k
        }
93
23.2M
    }
94
482k
    *odata = quote;
95
482k
}
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
70.1M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
69.8M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
69.8M
        if ((ch == quote) || (ch == '\\')) {
22
72.2k
            *odata++ = '\\';
23
72.2k
            *odata++ = ch;
24
72.2k
            continue;
25
72.2k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
69.8M
        if (ch == '\t') {
29
7.65k
            *odata++ = '\\';
30
7.65k
            *odata++ = 't';
31
7.65k
        }
32
69.8M
        else if (ch == '\n') {
33
532
            *odata++ = '\\';
34
532
            *odata++ = 'n';
35
532
        }
36
69.8M
        else if (ch == '\r') {
37
470
            *odata++ = '\\';
38
470
            *odata++ = 'r';
39
470
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
69.8M
        else if (ch < ' ' || ch == 0x7F) {
43
47.6M
            *odata++ = '\\';
44
47.6M
            *odata++ = 'x';
45
47.6M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
47.6M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
47.6M
        }
48
49
        /* Copy ASCII characters as-is */
50
22.1M
        else if (ch < 0x7F) {
51
16.5M
            *odata++ = ch;
52
16.5M
        }
53
54
        /* Non-ASCII characters */
55
5.64M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
5.64M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
41.2k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
41.2k
                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
29.6k
                else if (ch <= 0xffff) {
69
15.5k
                    *odata++ = 'u';
70
15.5k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
15.5k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
15.5k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
15.5k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
15.5k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
14.1k
                else {
77
14.1k
                    *odata++ = 'U';
78
14.1k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
14.1k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
14.1k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
14.1k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
14.1k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
14.1k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
14.1k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
14.1k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
14.1k
                }
87
41.2k
            }
88
            /* Copy characters as-is */
89
5.60M
            else {
90
5.60M
                *odata++ = ch;
91
5.60M
            }
92
5.64M
        }
93
69.8M
    }
94
213k
    *odata = quote;
95
213k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
4.03k
{
12
4.03k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
4.03k
    const void *idata = PyUnicode_DATA(unicode);
14
4.03k
    int ikind = PyUnicode_KIND(unicode);
15
16
4.03k
    *odata++ = quote;
17
12.8M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
12.8M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
12.8M
        if ((ch == quote) || (ch == '\\')) {
22
6.38k
            *odata++ = '\\';
23
6.38k
            *odata++ = ch;
24
6.38k
            continue;
25
6.38k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
12.8M
        if (ch == '\t') {
29
646
            *odata++ = '\\';
30
646
            *odata++ = 't';
31
646
        }
32
12.8M
        else if (ch == '\n') {
33
269
            *odata++ = '\\';
34
269
            *odata++ = 'n';
35
269
        }
36
12.8M
        else if (ch == '\r') {
37
563
            *odata++ = '\\';
38
563
            *odata++ = 'r';
39
563
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
12.8M
        else if (ch < ' ' || ch == 0x7F) {
43
12.3M
            *odata++ = '\\';
44
12.3M
            *odata++ = 'x';
45
12.3M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
12.3M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
12.3M
        }
48
49
        /* Copy ASCII characters as-is */
50
501k
        else if (ch < 0x7F) {
51
386k
            *odata++ = ch;
52
386k
        }
53
54
        /* Non-ASCII characters */
55
114k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
114k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
6.97k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
6.97k
                if (ch <= 0xff) {
63
1.60k
                    *odata++ = 'x';
64
1.60k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
1.60k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
1.60k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
5.37k
                else if (ch <= 0xffff) {
69
4.83k
                    *odata++ = 'u';
70
4.83k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
4.83k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
4.83k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
4.83k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
4.83k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
535
                else {
77
535
                    *odata++ = 'U';
78
535
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
535
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
535
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
535
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
535
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
535
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
535
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
535
                    *odata++ = Py_hexdigits[ch & 0xF];
86
535
                }
87
6.97k
            }
88
            /* Copy characters as-is */
89
107k
            else {
90
107k
                *odata++ = ch;
91
107k
            }
92
114k
        }
93
12.8M
    }
94
4.03k
    *odata = quote;
95
4.03k
}