Coverage Report

Created: 2025-07-11 06:24

/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
546k
{
12
546k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
546k
    const void *idata = PyUnicode_DATA(unicode);
14
546k
    int ikind = PyUnicode_KIND(unicode);
15
16
546k
    *odata++ = quote;
17
126M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
125M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
125M
        if ((ch == quote) || (ch == '\\')) {
22
304k
            *odata++ = '\\';
23
304k
            *odata++ = ch;
24
304k
            continue;
25
304k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
125M
        if (ch == '\t') {
29
24.8k
            *odata++ = '\\';
30
24.8k
            *odata++ = 't';
31
24.8k
        }
32
125M
        else if (ch == '\n') {
33
2.41k
            *odata++ = '\\';
34
2.41k
            *odata++ = 'n';
35
2.41k
        }
36
125M
        else if (ch == '\r') {
37
2.89k
            *odata++ = '\\';
38
2.89k
            *odata++ = 'r';
39
2.89k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
125M
        else if (ch < ' ' || ch == 0x7F) {
43
90.5M
            *odata++ = '\\';
44
90.5M
            *odata++ = 'x';
45
90.5M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
90.5M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
90.5M
        }
48
49
        /* Copy ASCII characters as-is */
50
34.6M
        else if (ch < 0x7F) {
51
26.9M
            *odata++ = ch;
52
26.9M
        }
53
54
        /* Non-ASCII characters */
55
7.68M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
7.68M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
109k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
109k
                if (ch <= 0xff) {
63
22.1k
                    *odata++ = 'x';
64
22.1k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
22.1k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
22.1k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
87.3k
                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
37.5k
                else {
77
37.5k
                    *odata++ = 'U';
78
37.5k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
37.5k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
37.5k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
37.5k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
37.5k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
37.5k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
37.5k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
37.5k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
37.5k
                }
87
109k
            }
88
            /* Copy characters as-is */
89
7.57M
            else {
90
7.57M
                *odata++ = ch;
91
7.57M
            }
92
7.68M
        }
93
125M
    }
94
546k
    *odata = quote;
95
546k
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
356k
{
12
356k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
356k
    const void *idata = PyUnicode_DATA(unicode);
14
356k
    int ikind = PyUnicode_KIND(unicode);
15
16
356k
    *odata++ = quote;
17
28.0M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
27.6M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
27.6M
        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
27.5M
        if (ch == '\t') {
29
12.8k
            *odata++ = '\\';
30
12.8k
            *odata++ = 't';
31
12.8k
        }
32
27.5M
        else if (ch == '\n') {
33
998
            *odata++ = '\\';
34
998
            *odata++ = 'n';
35
998
        }
36
27.5M
        else if (ch == '\r') {
37
1.43k
            *odata++ = '\\';
38
1.43k
            *odata++ = 'r';
39
1.43k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
27.5M
        else if (ch < ' ' || ch == 0x7F) {
43
21.3M
            *odata++ = '\\';
44
21.3M
            *odata++ = 'x';
45
21.3M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
21.3M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
21.3M
        }
48
49
        /* Copy ASCII characters as-is */
50
6.12M
        else if (ch < 0x7F) {
51
6.07M
            *odata++ = ch;
52
6.07M
        }
53
54
        /* Non-ASCII characters */
55
54.9k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
54.9k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
45.0k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
45.0k
                if (ch <= 0xff) {
63
12.1k
                    *odata++ = 'x';
64
12.1k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
12.1k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
12.1k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
32.9k
                else if (ch <= 0xffff) {
69
30.5k
                    *odata++ = 'u';
70
30.5k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
30.5k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
30.5k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
30.5k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
30.5k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
2.38k
                else {
77
2.38k
                    *odata++ = 'U';
78
2.38k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
2.38k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
2.38k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
2.38k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
2.38k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
2.38k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
2.38k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
2.38k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
2.38k
                }
87
45.0k
            }
88
            /* Copy characters as-is */
89
9.91k
            else {
90
9.91k
                *odata++ = ch;
91
9.91k
            }
92
54.9k
        }
93
27.5M
    }
94
356k
    *odata = quote;
95
356k
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
185k
{
12
185k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
185k
    const void *idata = PyUnicode_DATA(unicode);
14
185k
    int ikind = PyUnicode_KIND(unicode);
15
16
185k
    *odata++ = quote;
17
81.5M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
81.3M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
81.3M
        if ((ch == quote) || (ch == '\\')) {
22
142k
            *odata++ = '\\';
23
142k
            *odata++ = ch;
24
142k
            continue;
25
142k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
81.1M
        if (ch == '\t') {
29
10.1k
            *odata++ = '\\';
30
10.1k
            *odata++ = 't';
31
10.1k
        }
32
81.1M
        else if (ch == '\n') {
33
621
            *odata++ = '\\';
34
621
            *odata++ = 'n';
35
621
        }
36
81.1M
        else if (ch == '\r') {
37
986
            *odata++ = '\\';
38
986
            *odata++ = 'r';
39
986
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
81.1M
        else if (ch < ' ' || ch == 0x7F) {
43
53.5M
            *odata++ = '\\';
44
53.5M
            *odata++ = 'x';
45
53.5M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
53.5M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
53.5M
        }
48
49
        /* Copy ASCII characters as-is */
50
27.6M
        else if (ch < 0x7F) {
51
20.2M
            *odata++ = ch;
52
20.2M
        }
53
54
        /* Non-ASCII characters */
55
7.41M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
7.41M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
59.6k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
59.6k
                if (ch <= 0xff) {
63
8.97k
                    *odata++ = 'x';
64
8.97k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
8.97k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
8.97k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
50.6k
                else if (ch <= 0xffff) {
69
17.3k
                    *odata++ = 'u';
70
17.3k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
17.3k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
17.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
17.3k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
17.3k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
33.3k
                else {
77
33.3k
                    *odata++ = 'U';
78
33.3k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
33.3k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
33.3k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
33.3k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
33.3k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
33.3k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
33.3k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
33.3k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
33.3k
                }
87
59.6k
            }
88
            /* Copy characters as-is */
89
7.35M
            else {
90
7.35M
                *odata++ = ch;
91
7.35M
            }
92
7.41M
        }
93
81.1M
    }
94
185k
    *odata = quote;
95
185k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
4.01k
{
12
4.01k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
4.01k
    const void *idata = PyUnicode_DATA(unicode);
14
4.01k
    int ikind = PyUnicode_KIND(unicode);
15
16
4.01k
    *odata++ = quote;
17
16.5M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
16.5M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
16.5M
        if ((ch == quote) || (ch == '\\')) {
22
22.9k
            *odata++ = '\\';
23
22.9k
            *odata++ = ch;
24
22.9k
            continue;
25
22.9k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
16.5M
        if (ch == '\t') {
29
1.81k
            *odata++ = '\\';
30
1.81k
            *odata++ = 't';
31
1.81k
        }
32
16.5M
        else if (ch == '\n') {
33
797
            *odata++ = '\\';
34
797
            *odata++ = 'n';
35
797
        }
36
16.5M
        else if (ch == '\r') {
37
467
            *odata++ = '\\';
38
467
            *odata++ = 'r';
39
467
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
16.5M
        else if (ch < ' ' || ch == 0x7F) {
43
15.6M
            *odata++ = '\\';
44
15.6M
            *odata++ = 'x';
45
15.6M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
15.6M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
15.6M
        }
48
49
        /* Copy ASCII characters as-is */
50
875k
        else if (ch < 0x7F) {
51
661k
            *odata++ = ch;
52
661k
        }
53
54
        /* Non-ASCII characters */
55
214k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
214k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
4.75k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
4.75k
                if (ch <= 0xff) {
63
1.02k
                    *odata++ = 'x';
64
1.02k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
1.02k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
1.02k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
3.73k
                else if (ch <= 0xffff) {
69
1.93k
                    *odata++ = 'u';
70
1.93k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
1.93k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
1.93k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
1.93k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
1.93k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
1.79k
                else {
77
1.79k
                    *odata++ = 'U';
78
1.79k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
1.79k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
1.79k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
1.79k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
1.79k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
1.79k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
1.79k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
1.79k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
1.79k
                }
87
4.75k
            }
88
            /* Copy characters as-is */
89
209k
            else {
90
209k
                *odata++ = ch;
91
209k
            }
92
214k
        }
93
16.5M
    }
94
4.01k
    *odata = quote;
95
4.01k
}