Coverage Report

Created: 2025-07-04 06:49

/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
595k
{
12
595k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
595k
    const void *idata = PyUnicode_DATA(unicode);
14
595k
    int ikind = PyUnicode_KIND(unicode);
15
16
595k
    *odata++ = quote;
17
124M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
123M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
123M
        if ((ch == quote) || (ch == '\\')) {
22
367k
            *odata++ = '\\';
23
367k
            *odata++ = ch;
24
367k
            continue;
25
367k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
123M
        if (ch == '\t') {
29
28.9k
            *odata++ = '\\';
30
28.9k
            *odata++ = 't';
31
28.9k
        }
32
123M
        else if (ch == '\n') {
33
2.39k
            *odata++ = '\\';
34
2.39k
            *odata++ = 'n';
35
2.39k
        }
36
123M
        else if (ch == '\r') {
37
2.35k
            *odata++ = '\\';
38
2.35k
            *odata++ = 'r';
39
2.35k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
123M
        else if (ch < ' ' || ch == 0x7F) {
43
88.4M
            *odata++ = '\\';
44
88.4M
            *odata++ = 'x';
45
88.4M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
88.4M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
88.4M
        }
48
49
        /* Copy ASCII characters as-is */
50
35.0M
        else if (ch < 0x7F) {
51
27.2M
            *odata++ = ch;
52
27.2M
        }
53
54
        /* Non-ASCII characters */
55
7.75M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
7.75M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
103k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
103k
                if (ch <= 0xff) {
63
21.1k
                    *odata++ = 'x';
64
21.1k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
21.1k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
21.1k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
82.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
43.0k
                else {
77
43.0k
                    *odata++ = 'U';
78
43.0k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
43.0k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
43.0k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
43.0k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
43.0k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
43.0k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
43.0k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
43.0k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
43.0k
                }
87
103k
            }
88
            /* Copy characters as-is */
89
7.65M
            else {
90
7.65M
                *odata++ = ch;
91
7.65M
            }
92
7.75M
        }
93
123M
    }
94
595k
    *odata = quote;
95
595k
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
410k
{
12
410k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
410k
    const void *idata = PyUnicode_DATA(unicode);
14
410k
    int ikind = PyUnicode_KIND(unicode);
15
16
410k
    *odata++ = quote;
17
26.4M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
26.0M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
26.0M
        if ((ch == quote) || (ch == '\\')) {
22
196k
            *odata++ = '\\';
23
196k
            *odata++ = ch;
24
196k
            continue;
25
196k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
25.8M
        if (ch == '\t') {
29
15.2k
            *odata++ = '\\';
30
15.2k
            *odata++ = 't';
31
15.2k
        }
32
25.8M
        else if (ch == '\n') {
33
1.01k
            *odata++ = '\\';
34
1.01k
            *odata++ = 'n';
35
1.01k
        }
36
25.8M
        else if (ch == '\r') {
37
1.17k
            *odata++ = '\\';
38
1.17k
            *odata++ = 'r';
39
1.17k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
25.8M
        else if (ch < ' ' || ch == 0x7F) {
43
19.4M
            *odata++ = '\\';
44
19.4M
            *odata++ = 'x';
45
19.4M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
19.4M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
19.4M
        }
48
49
        /* Copy ASCII characters as-is */
50
6.33M
        else if (ch < 0x7F) {
51
6.29M
            *odata++ = ch;
52
6.29M
        }
53
54
        /* Non-ASCII characters */
55
46.1k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
46.1k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
37.2k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
37.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
25.6k
                else if (ch <= 0xffff) {
69
23.3k
                    *odata++ = 'u';
70
23.3k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
23.3k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
23.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
23.3k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
23.3k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
2.32k
                else {
77
2.32k
                    *odata++ = 'U';
78
2.32k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
2.32k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
2.32k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
2.32k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
2.32k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
2.32k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
2.32k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
2.32k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
2.32k
                }
87
37.2k
            }
88
            /* Copy characters as-is */
89
8.82k
            else {
90
8.82k
                *odata++ = ch;
91
8.82k
            }
92
46.1k
        }
93
25.8M
    }
94
410k
    *odata = quote;
95
410k
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
181k
{
12
181k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
181k
    const void *idata = PyUnicode_DATA(unicode);
14
181k
    int ikind = PyUnicode_KIND(unicode);
15
16
181k
    *odata++ = quote;
17
83.4M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
83.2M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
83.2M
        if ((ch == quote) || (ch == '\\')) {
22
144k
            *odata++ = '\\';
23
144k
            *odata++ = ch;
24
144k
            continue;
25
144k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
83.0M
        if (ch == '\t') {
29
11.5k
            *odata++ = '\\';
30
11.5k
            *odata++ = 't';
31
11.5k
        }
32
83.0M
        else if (ch == '\n') {
33
583
            *odata++ = '\\';
34
583
            *odata++ = 'n';
35
583
        }
36
83.0M
        else if (ch == '\r') {
37
709
            *odata++ = '\\';
38
709
            *odata++ = 'r';
39
709
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
83.0M
        else if (ch < ' ' || ch == 0x7F) {
43
55.3M
            *odata++ = '\\';
44
55.3M
            *odata++ = 'x';
45
55.3M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
55.3M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
55.3M
        }
48
49
        /* Copy ASCII characters as-is */
50
27.7M
        else if (ch < 0x7F) {
51
20.2M
            *odata++ = ch;
52
20.2M
        }
53
54
        /* Non-ASCII characters */
55
7.45M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
7.45M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
61.6k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
61.6k
                if (ch <= 0xff) {
63
8.65k
                    *odata++ = 'x';
64
8.65k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
8.65k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
8.65k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
53.0k
                else if (ch <= 0xffff) {
69
14.8k
                    *odata++ = 'u';
70
14.8k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
14.8k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
14.8k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
14.8k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
14.8k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
38.2k
                else {
77
38.2k
                    *odata++ = 'U';
78
38.2k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
38.2k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
38.2k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
38.2k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
38.2k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
38.2k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
38.2k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
38.2k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
38.2k
                }
87
61.6k
            }
88
            /* Copy characters as-is */
89
7.39M
            else {
90
7.39M
                *odata++ = ch;
91
7.39M
            }
92
7.45M
        }
93
83.0M
    }
94
181k
    *odata = quote;
95
181k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
3.92k
{
12
3.92k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
3.92k
    const void *idata = PyUnicode_DATA(unicode);
14
3.92k
    int ikind = PyUnicode_KIND(unicode);
15
16
3.92k
    *odata++ = quote;
17
14.5M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
14.5M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
14.5M
        if ((ch == quote) || (ch == '\\')) {
22
25.8k
            *odata++ = '\\';
23
25.8k
            *odata++ = ch;
24
25.8k
            continue;
25
25.8k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
14.5M
        if (ch == '\t') {
29
2.10k
            *odata++ = '\\';
30
2.10k
            *odata++ = 't';
31
2.10k
        }
32
14.5M
        else if (ch == '\n') {
33
795
            *odata++ = '\\';
34
795
            *odata++ = 'n';
35
795
        }
36
14.5M
        else if (ch == '\r') {
37
468
            *odata++ = '\\';
38
468
            *odata++ = 'r';
39
468
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
14.5M
        else if (ch < ' ' || ch == 0x7F) {
43
13.5M
            *odata++ = '\\';
44
13.5M
            *odata++ = 'x';
45
13.5M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
13.5M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
13.5M
        }
48
49
        /* Copy ASCII characters as-is */
50
933k
        else if (ch < 0x7F) {
51
678k
            *odata++ = ch;
52
678k
        }
53
54
        /* Non-ASCII characters */
55
255k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
255k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
4.91k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
4.91k
                if (ch <= 0xff) {
63
882
                    *odata++ = 'x';
64
882
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
882
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
882
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
4.03k
                else if (ch <= 0xffff) {
69
1.50k
                    *odata++ = 'u';
70
1.50k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
1.50k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
1.50k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
1.50k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
1.50k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
2.52k
                else {
77
2.52k
                    *odata++ = 'U';
78
2.52k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
2.52k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
2.52k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
2.52k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
2.52k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
2.52k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
2.52k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
2.52k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
2.52k
                }
87
4.91k
            }
88
            /* Copy characters as-is */
89
250k
            else {
90
250k
                *odata++ = ch;
91
250k
            }
92
255k
        }
93
14.5M
    }
94
3.92k
    *odata = quote;
95
3.92k
}