Coverage Report

Created: 2025-11-24 06:11

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.94M
{
12
6.94M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
6.94M
    const void *idata = PyUnicode_DATA(unicode);
14
6.94M
    int ikind = PyUnicode_KIND(unicode);
15
16
6.94M
    *odata++ = quote;
17
192M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
185M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
185M
        if ((ch == quote) || (ch == '\\')) {
22
239k
            *odata++ = '\\';
23
239k
            *odata++ = ch;
24
239k
            continue;
25
239k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
184M
        if (ch == '\t') {
29
990k
            *odata++ = '\\';
30
990k
            *odata++ = 't';
31
990k
        }
32
183M
        else if (ch == '\n') {
33
4.09M
            *odata++ = '\\';
34
4.09M
            *odata++ = 'n';
35
4.09M
        }
36
179M
        else if (ch == '\r') {
37
94.1k
            *odata++ = '\\';
38
94.1k
            *odata++ = 'r';
39
94.1k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
179M
        else if (ch < ' ' || ch == 0x7F) {
43
122M
            *odata++ = '\\';
44
122M
            *odata++ = 'x';
45
122M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
122M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
122M
        }
48
49
        /* Copy ASCII characters as-is */
50
57.0M
        else if (ch < 0x7F) {
51
45.7M
            *odata++ = ch;
52
45.7M
        }
53
54
        /* Non-ASCII characters */
55
11.2M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
11.2M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
138k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
138k
                if (ch <= 0xff) {
63
45.3k
                    *odata++ = 'x';
64
45.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
45.3k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
45.3k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
93.2k
                else if (ch <= 0xffff) {
69
64.1k
                    *odata++ = 'u';
70
64.1k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
64.1k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
64.1k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
64.1k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
64.1k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
29.0k
                else {
77
29.0k
                    *odata++ = 'U';
78
29.0k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
29.0k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
29.0k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
29.0k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
29.0k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
29.0k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
29.0k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
29.0k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
29.0k
                }
87
138k
            }
88
            /* Copy characters as-is */
89
11.1M
            else {
90
11.1M
                *odata++ = ch;
91
11.1M
            }
92
11.2M
        }
93
184M
    }
94
6.94M
    *odata = quote;
95
6.94M
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
6.62M
{
12
6.62M
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
6.62M
    const void *idata = PyUnicode_DATA(unicode);
14
6.62M
    int ikind = PyUnicode_KIND(unicode);
15
16
6.62M
    *odata++ = quote;
17
71.7M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
65.1M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
65.1M
        if ((ch == quote) || (ch == '\\')) {
22
162k
            *odata++ = '\\';
23
162k
            *odata++ = ch;
24
162k
            continue;
25
162k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
64.9M
        if (ch == '\t') {
29
440k
            *odata++ = '\\';
30
440k
            *odata++ = 't';
31
440k
        }
32
64.5M
        else if (ch == '\n') {
33
3.87M
            *odata++ = '\\';
34
3.87M
            *odata++ = 'n';
35
3.87M
        }
36
60.6M
        else if (ch == '\r') {
37
44.6k
            *odata++ = '\\';
38
44.6k
            *odata++ = 'r';
39
44.6k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
60.6M
        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
74.3k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
74.3k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
60.3k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
60.3k
                if (ch <= 0xff) {
63
16.5k
                    *odata++ = 'x';
64
16.5k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
16.5k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
16.5k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
43.7k
                else if (ch <= 0xffff) {
69
39.6k
                    *odata++ = 'u';
70
39.6k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
39.6k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
39.6k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
39.6k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
39.6k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
4.11k
                else {
77
4.11k
                    *odata++ = 'U';
78
4.11k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
4.11k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
4.11k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
4.11k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
4.11k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
4.11k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
4.11k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
4.11k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
4.11k
                }
87
60.3k
            }
88
            /* Copy characters as-is */
89
14.0k
            else {
90
14.0k
                *odata++ = ch;
91
14.0k
            }
92
74.3k
        }
93
64.9M
    }
94
6.62M
    *odata = quote;
95
6.62M
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
307k
{
12
307k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
307k
    const void *idata = PyUnicode_DATA(unicode);
14
307k
    int ikind = PyUnicode_KIND(unicode);
15
16
307k
    *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
69.4k
            *odata++ = '\\';
23
69.4k
            *odata++ = ch;
24
69.4k
            continue;
25
69.4k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
106M
        if (ch == '\t') {
29
548k
            *odata++ = '\\';
30
548k
            *odata++ = 't';
31
548k
        }
32
105M
        else if (ch == '\n') {
33
225k
            *odata++ = '\\';
34
225k
            *odata++ = 'n';
35
225k
        }
36
105M
        else if (ch == '\r') {
37
47.3k
            *odata++ = '\\';
38
47.3k
            *odata++ = 'r';
39
47.3k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
105M
        else if (ch < ' ' || ch == 0x7F) {
43
70.5M
            *odata++ = '\\';
44
70.5M
            *odata++ = 'x';
45
70.5M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
70.5M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
70.5M
        }
48
49
        /* Copy ASCII characters as-is */
50
34.6M
        else if (ch < 0x7F) {
51
23.5M
            *odata++ = ch;
52
23.5M
        }
53
54
        /* Non-ASCII characters */
55
11.0M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
11.0M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
70.9k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
70.9k
                if (ch <= 0xff) {
63
27.0k
                    *odata++ = 'x';
64
27.0k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
27.0k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
27.0k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
43.8k
                else if (ch <= 0xffff) {
69
20.3k
                    *odata++ = 'u';
70
20.3k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
20.3k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
20.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
20.3k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
20.3k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
23.5k
                else {
77
23.5k
                    *odata++ = 'U';
78
23.5k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
23.5k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
23.5k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
23.5k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
23.5k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
23.5k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
23.5k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
23.5k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
23.5k
                }
87
70.9k
            }
88
            /* Copy characters as-is */
89
10.9M
            else {
90
10.9M
                *odata++ = ch;
91
10.9M
            }
92
11.0M
        }
93
106M
    }
94
307k
    *odata = quote;
95
307k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
5.58k
{
12
5.58k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
5.58k
    const void *idata = PyUnicode_DATA(unicode);
14
5.58k
    int ikind = PyUnicode_KIND(unicode);
15
16
5.58k
    *odata++ = quote;
17
13.8M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
13.8M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
13.8M
        if ((ch == quote) || (ch == '\\')) {
22
7.14k
            *odata++ = '\\';
23
7.14k
            *odata++ = ch;
24
7.14k
            continue;
25
7.14k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
13.8M
        if (ch == '\t') {
29
1.43k
            *odata++ = '\\';
30
1.43k
            *odata++ = 't';
31
1.43k
        }
32
13.8M
        else if (ch == '\n') {
33
2.40k
            *odata++ = '\\';
34
2.40k
            *odata++ = 'n';
35
2.40k
        }
36
13.8M
        else if (ch == '\r') {
37
2.17k
            *odata++ = '\\';
38
2.17k
            *odata++ = 'r';
39
2.17k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
13.8M
        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
840k
        else if (ch < 0x7F) {
51
709k
            *odata++ = ch;
52
709k
        }
53
54
        /* Non-ASCII characters */
55
131k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
131k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
7.28k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
7.28k
                if (ch <= 0xff) {
63
1.68k
                    *odata++ = 'x';
64
1.68k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
1.68k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
1.68k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
5.60k
                else if (ch <= 0xffff) {
69
4.26k
                    *odata++ = 'u';
70
4.26k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
4.26k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
4.26k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
4.26k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
4.26k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
1.33k
                else {
77
1.33k
                    *odata++ = 'U';
78
1.33k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
1.33k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
1.33k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
1.33k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
1.33k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
1.33k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
1.33k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
1.33k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
1.33k
                }
87
7.28k
            }
88
            /* Copy characters as-is */
89
123k
            else {
90
123k
                *odata++ = ch;
91
123k
            }
92
131k
        }
93
13.8M
    }
94
5.58k
    *odata = quote;
95
5.58k
}