Coverage Report

Created: 2025-09-05 07:10

/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
547k
{
12
547k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
547k
    const void *idata = PyUnicode_DATA(unicode);
14
547k
    int ikind = PyUnicode_KIND(unicode);
15
16
547k
    *odata++ = quote;
17
108M
    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
162k
            *odata++ = '\\';
23
162k
            *odata++ = ch;
24
162k
            continue;
25
162k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
107M
        if (ch == '\t') {
29
16.5k
            *odata++ = '\\';
30
16.5k
            *odata++ = 't';
31
16.5k
        }
32
107M
        else if (ch == '\n') {
33
2.13k
            *odata++ = '\\';
34
2.13k
            *odata++ = 'n';
35
2.13k
        }
36
107M
        else if (ch == '\r') {
37
2.11k
            *odata++ = '\\';
38
2.11k
            *odata++ = 'r';
39
2.11k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
107M
        else if (ch < ' ' || ch == 0x7F) {
43
77.6M
            *odata++ = '\\';
44
77.6M
            *odata++ = 'x';
45
77.6M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
77.6M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
77.6M
        }
48
49
        /* Copy ASCII characters as-is */
50
29.6M
        else if (ch < 0x7F) {
51
23.2M
            *odata++ = ch;
52
23.2M
        }
53
54
        /* Non-ASCII characters */
55
6.44M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
6.44M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
93.9k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
93.9k
                if (ch <= 0xff) {
63
26.2k
                    *odata++ = 'x';
64
26.2k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
26.2k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
26.2k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
67.7k
                else if (ch <= 0xffff) {
69
45.0k
                    *odata++ = 'u';
70
45.0k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
45.0k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
45.0k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
45.0k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
45.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
93.9k
            }
88
            /* Copy characters as-is */
89
6.34M
            else {
90
6.34M
                *odata++ = ch;
91
6.34M
            }
92
6.44M
        }
93
107M
    }
94
547k
    *odata = quote;
95
547k
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
347k
{
12
347k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
347k
    const void *idata = PyUnicode_DATA(unicode);
14
347k
    int ikind = PyUnicode_KIND(unicode);
15
16
347k
    *odata++ = quote;
17
24.1M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
23.7M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
23.7M
        if ((ch == quote) || (ch == '\\')) {
22
69.5k
            *odata++ = '\\';
23
69.5k
            *odata++ = ch;
24
69.5k
            continue;
25
69.5k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
23.6M
        if (ch == '\t') {
29
10.5k
            *odata++ = '\\';
30
10.5k
            *odata++ = 't';
31
10.5k
        }
32
23.6M
        else if (ch == '\n') {
33
1.18k
            *odata++ = '\\';
34
1.18k
            *odata++ = 'n';
35
1.18k
        }
36
23.6M
        else if (ch == '\r') {
37
1.26k
            *odata++ = '\\';
38
1.26k
            *odata++ = 'r';
39
1.26k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
23.6M
        else if (ch < ' ' || ch == 0x7F) {
43
17.8M
            *odata++ = '\\';
44
17.8M
            *odata++ = 'x';
45
17.8M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
17.8M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
17.8M
        }
48
49
        /* Copy ASCII characters as-is */
50
5.88M
        else if (ch < 0x7F) {
51
5.82M
            *odata++ = ch;
52
5.82M
        }
53
54
        /* Non-ASCII characters */
55
50.9k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
50.9k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
45.7k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
45.7k
                if (ch <= 0xff) {
63
13.3k
                    *odata++ = 'x';
64
13.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
13.3k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
13.3k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
32.4k
                else if (ch <= 0xffff) {
69
29.1k
                    *odata++ = 'u';
70
29.1k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
29.1k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
29.1k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
29.1k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
29.1k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
3.25k
                else {
77
3.25k
                    *odata++ = 'U';
78
3.25k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
3.25k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
3.25k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
3.25k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
3.25k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
3.25k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
3.25k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
3.25k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
3.25k
                }
87
45.7k
            }
88
            /* Copy characters as-is */
89
5.16k
            else {
90
5.16k
                *odata++ = ch;
91
5.16k
            }
92
50.9k
        }
93
23.6M
    }
94
347k
    *odata = quote;
95
347k
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
196k
{
12
196k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
196k
    const void *idata = PyUnicode_DATA(unicode);
14
196k
    int ikind = PyUnicode_KIND(unicode);
15
16
196k
    *odata++ = quote;
17
71.2M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
71.0M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
71.0M
        if ((ch == quote) || (ch == '\\')) {
22
72.4k
            *odata++ = '\\';
23
72.4k
            *odata++ = ch;
24
72.4k
            continue;
25
72.4k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
71.0M
        if (ch == '\t') {
29
5.05k
            *odata++ = '\\';
30
5.05k
            *odata++ = 't';
31
5.05k
        }
32
71.0M
        else if (ch == '\n') {
33
680
            *odata++ = '\\';
34
680
            *odata++ = 'n';
35
680
        }
36
71.0M
        else if (ch == '\r') {
37
470
            *odata++ = '\\';
38
470
            *odata++ = 'r';
39
470
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
71.0M
        else if (ch < ' ' || ch == 0x7F) {
43
47.9M
            *odata++ = '\\';
44
47.9M
            *odata++ = 'x';
45
47.9M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
47.9M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
47.9M
        }
48
49
        /* Copy ASCII characters as-is */
50
23.0M
        else if (ch < 0x7F) {
51
16.7M
            *odata++ = ch;
52
16.7M
        }
53
54
        /* Non-ASCII characters */
55
6.29M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
6.29M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
43.3k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
43.3k
                if (ch <= 0xff) {
63
11.7k
                    *odata++ = 'x';
64
11.7k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
11.7k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
11.7k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
31.5k
                else if (ch <= 0xffff) {
69
12.8k
                    *odata++ = 'u';
70
12.8k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
12.8k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
12.8k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
12.8k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
12.8k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
18.6k
                else {
77
18.6k
                    *odata++ = 'U';
78
18.6k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
18.6k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
18.6k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
18.6k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
18.6k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
18.6k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
18.6k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
18.6k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
18.6k
                }
87
43.3k
            }
88
            /* Copy characters as-is */
89
6.25M
            else {
90
6.25M
                *odata++ = ch;
91
6.25M
            }
92
6.29M
        }
93
71.0M
    }
94
196k
    *odata = quote;
95
196k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
3.36k
{
12
3.36k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
3.36k
    const void *idata = PyUnicode_DATA(unicode);
14
3.36k
    int ikind = PyUnicode_KIND(unicode);
15
16
3.36k
    *odata++ = quote;
17
12.6M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
12.6M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
12.6M
        if ((ch == quote) || (ch == '\\')) {
22
20.5k
            *odata++ = '\\';
23
20.5k
            *odata++ = ch;
24
20.5k
            continue;
25
20.5k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
12.6M
        if (ch == '\t') {
29
869
            *odata++ = '\\';
30
869
            *odata++ = 't';
31
869
        }
32
12.6M
        else if (ch == '\n') {
33
269
            *odata++ = '\\';
34
269
            *odata++ = 'n';
35
269
        }
36
12.6M
        else if (ch == '\r') {
37
380
            *odata++ = '\\';
38
380
            *odata++ = 'r';
39
380
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
12.6M
        else if (ch < ' ' || ch == 0x7F) {
43
11.9M
            *odata++ = '\\';
44
11.9M
            *odata++ = 'x';
45
11.9M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
11.9M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
11.9M
        }
48
49
        /* Copy ASCII characters as-is */
50
700k
        else if (ch < 0x7F) {
51
605k
            *odata++ = ch;
52
605k
        }
53
54
        /* Non-ASCII characters */
55
95.0k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
95.0k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
4.85k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
4.85k
                if (ch <= 0xff) {
63
1.13k
                    *odata++ = 'x';
64
1.13k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
1.13k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
1.13k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
3.71k
                else if (ch <= 0xffff) {
69
2.94k
                    *odata++ = 'u';
70
2.94k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
2.94k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
2.94k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
2.94k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
2.94k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
774
                else {
77
774
                    *odata++ = 'U';
78
774
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
774
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
774
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
774
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
774
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
774
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
774
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
774
                    *odata++ = Py_hexdigits[ch & 0xF];
86
774
                }
87
4.85k
            }
88
            /* Copy characters as-is */
89
90.1k
            else {
90
90.1k
                *odata++ = ch;
91
90.1k
            }
92
95.0k
        }
93
12.6M
    }
94
3.36k
    *odata = quote;
95
3.36k
}