Coverage Report

Created: 2025-08-29 07:13

/src/cpython3/Objects/stringlib/repr.h
Line
Count
Source (jump to first uncovered line)
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
7.19k
{
12
7.19k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
7.19k
    const void *idata = PyUnicode_DATA(unicode);
14
7.19k
    int ikind = PyUnicode_KIND(unicode);
15
16
0
    *odata++ = quote;
17
4.83M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
4.82M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
4.82M
        if ((ch == quote) || (ch == '\\')) {
22
54.6k
            *odata++ = '\\';
23
54.6k
            *odata++ = ch;
24
54.6k
            continue;
25
54.6k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
4.76M
        if (ch == '\t') {
29
6.38k
            *odata++ = '\\';
30
6.38k
            *odata++ = 't';
31
6.38k
        }
32
4.76M
        else if (ch == '\n') {
33
23.3k
            *odata++ = '\\';
34
23.3k
            *odata++ = 'n';
35
23.3k
        }
36
4.73M
        else if (ch == '\r') {
37
7.09k
            *odata++ = '\\';
38
7.09k
            *odata++ = 'r';
39
7.09k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
4.73M
        else if (ch < ' ' || ch == 0x7F) {
43
1.54M
            *odata++ = '\\';
44
1.54M
            *odata++ = 'x';
45
1.54M
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
1.54M
            *odata++ = Py_hexdigits[ch & 0x000F];
47
1.54M
        }
48
49
        /* Copy ASCII characters as-is */
50
3.18M
        else if (ch < 0x7F) {
51
2.10M
            *odata++ = ch;
52
2.10M
        }
53
54
        /* Non-ASCII characters */
55
1.07M
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
1.07M
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
877k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
877k
                if (ch <= 0xff) {
63
815k
                    *odata++ = 'x';
64
815k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
815k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
815k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
61.4k
                else if (ch <= 0xffff) {
69
57.0k
                    *odata++ = 'u';
70
57.0k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
57.0k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
57.0k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
57.0k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
57.0k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
4.41k
                else {
77
4.41k
                    *odata++ = 'U';
78
4.41k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
4.41k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
4.41k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
4.41k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
4.41k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
4.41k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
4.41k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
4.41k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
4.41k
                }
87
877k
            }
88
            /* Copy characters as-is */
89
198k
            else {
90
198k
                *odata++ = ch;
91
198k
            }
92
1.07M
        }
93
4.76M
    }
94
7.19k
    *odata = quote;
95
7.19k
}
unicodeobject.c:ucs1lib_repr
Line
Count
Source
11
3.83k
{
12
3.83k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
3.83k
    const void *idata = PyUnicode_DATA(unicode);
14
3.83k
    int ikind = PyUnicode_KIND(unicode);
15
16
0
    *odata++ = quote;
17
2.24M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
2.24M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
2.24M
        if ((ch == quote) || (ch == '\\')) {
22
15.2k
            *odata++ = '\\';
23
15.2k
            *odata++ = ch;
24
15.2k
            continue;
25
15.2k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
2.22M
        if (ch == '\t') {
29
2.94k
            *odata++ = '\\';
30
2.94k
            *odata++ = 't';
31
2.94k
        }
32
2.22M
        else if (ch == '\n') {
33
10.5k
            *odata++ = '\\';
34
10.5k
            *odata++ = 'n';
35
10.5k
        }
36
2.21M
        else if (ch == '\r') {
37
4.53k
            *odata++ = '\\';
38
4.53k
            *odata++ = 'r';
39
4.53k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
2.20M
        else if (ch < ' ' || ch == 0x7F) {
43
481k
            *odata++ = '\\';
44
481k
            *odata++ = 'x';
45
481k
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
481k
            *odata++ = Py_hexdigits[ch & 0x000F];
47
481k
        }
48
49
        /* Copy ASCII characters as-is */
50
1.72M
        else if (ch < 0x7F) {
51
782k
            *odata++ = ch;
52
782k
        }
53
54
        /* Non-ASCII characters */
55
944k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
944k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
817k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
817k
                if (ch <= 0xff) {
63
809k
                    *odata++ = 'x';
64
809k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
809k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
809k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
7.99k
                else if (ch <= 0xffff) {
69
6.00k
                    *odata++ = 'u';
70
6.00k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
6.00k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
6.00k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
6.00k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
6.00k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
1.98k
                else {
77
1.98k
                    *odata++ = 'U';
78
1.98k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
1.98k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
1.98k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
1.98k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
1.98k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
1.98k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
1.98k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
1.98k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
1.98k
                }
87
817k
            }
88
            /* Copy characters as-is */
89
126k
            else {
90
126k
                *odata++ = ch;
91
126k
            }
92
944k
        }
93
2.22M
    }
94
3.83k
    *odata = quote;
95
3.83k
}
unicodeobject.c:ucs2lib_repr
Line
Count
Source
11
1.92k
{
12
1.92k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
1.92k
    const void *idata = PyUnicode_DATA(unicode);
14
1.92k
    int ikind = PyUnicode_KIND(unicode);
15
16
0
    *odata++ = quote;
17
1.55M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
1.55M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
1.55M
        if ((ch == quote) || (ch == '\\')) {
22
20.3k
            *odata++ = '\\';
23
20.3k
            *odata++ = ch;
24
20.3k
            continue;
25
20.3k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
1.53M
        if (ch == '\t') {
29
2.38k
            *odata++ = '\\';
30
2.38k
            *odata++ = 't';
31
2.38k
        }
32
1.53M
        else if (ch == '\n') {
33
3.56k
            *odata++ = '\\';
34
3.56k
            *odata++ = 'n';
35
3.56k
        }
36
1.52M
        else if (ch == '\r') {
37
1.49k
            *odata++ = '\\';
38
1.49k
            *odata++ = 'r';
39
1.49k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
1.52M
        else if (ch < ' ' || ch == 0x7F) {
43
568k
            *odata++ = '\\';
44
568k
            *odata++ = 'x';
45
568k
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
568k
            *odata++ = Py_hexdigits[ch & 0x000F];
47
568k
        }
48
49
        /* Copy ASCII characters as-is */
50
959k
        else if (ch < 0x7F) {
51
844k
            *odata++ = ch;
52
844k
        }
53
54
        /* Non-ASCII characters */
55
115k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
115k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
52.9k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
52.9k
                if (ch <= 0xff) {
63
4.45k
                    *odata++ = 'x';
64
4.45k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
4.45k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
4.45k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
48.5k
                else if (ch <= 0xffff) {
69
47.4k
                    *odata++ = 'u';
70
47.4k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
47.4k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
47.4k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
47.4k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
47.4k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
1.06k
                else {
77
1.06k
                    *odata++ = 'U';
78
1.06k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
1.06k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
1.06k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
1.06k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
1.06k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
1.06k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
1.06k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
1.06k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
1.06k
                }
87
52.9k
            }
88
            /* Copy characters as-is */
89
62.5k
            else {
90
62.5k
                *odata++ = ch;
91
62.5k
            }
92
115k
        }
93
1.53M
    }
94
1.92k
    *odata = quote;
95
1.92k
}
unicodeobject.c:ucs4lib_repr
Line
Count
Source
11
1.43k
{
12
1.43k
    Py_ssize_t isize = PyUnicode_GET_LENGTH(unicode);
13
1.43k
    const void *idata = PyUnicode_DATA(unicode);
14
1.43k
    int ikind = PyUnicode_KIND(unicode);
15
16
0
    *odata++ = quote;
17
1.02M
    for (Py_ssize_t i = 0; i < isize; i++) {
18
1.02M
        Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
19
20
        /* Escape quotes and backslashes */
21
1.02M
        if ((ch == quote) || (ch == '\\')) {
22
19.0k
            *odata++ = '\\';
23
19.0k
            *odata++ = ch;
24
19.0k
            continue;
25
19.0k
        }
26
27
        /* Map special whitespace to '\t', \n', '\r' */
28
1.00M
        if (ch == '\t') {
29
1.05k
            *odata++ = '\\';
30
1.05k
            *odata++ = 't';
31
1.05k
        }
32
1.00M
        else if (ch == '\n') {
33
9.17k
            *odata++ = '\\';
34
9.17k
            *odata++ = 'n';
35
9.17k
        }
36
996k
        else if (ch == '\r') {
37
1.07k
            *odata++ = '\\';
38
1.07k
            *odata++ = 'r';
39
1.07k
        }
40
41
        /* Map non-printable US ASCII to '\xhh' */
42
995k
        else if (ch < ' ' || ch == 0x7F) {
43
499k
            *odata++ = '\\';
44
499k
            *odata++ = 'x';
45
499k
            *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
46
499k
            *odata++ = Py_hexdigits[ch & 0x000F];
47
499k
        }
48
49
        /* Copy ASCII characters as-is */
50
495k
        else if (ch < 0x7F) {
51
479k
            *odata++ = ch;
52
479k
        }
53
54
        /* Non-ASCII characters */
55
15.4k
        else {
56
            /* Map Unicode whitespace and control characters
57
               (categories Z* and C* except ASCII space)
58
            */
59
15.4k
            if (!Py_UNICODE_ISPRINTABLE(ch)) {
60
6.61k
                *odata++ = '\\';
61
                /* Map 8-bit characters to '\xhh' */
62
6.61k
                if (ch <= 0xff) {
63
1.65k
                    *odata++ = 'x';
64
1.65k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0x000F];
65
1.65k
                    *odata++ = Py_hexdigits[ch & 0x000F];
66
1.65k
                }
67
                /* Map 16-bit characters to '\uxxxx' */
68
4.95k
                else if (ch <= 0xffff) {
69
3.58k
                    *odata++ = 'u';
70
3.58k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
71
3.58k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
72
3.58k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
73
3.58k
                    *odata++ = Py_hexdigits[ch & 0xF];
74
3.58k
                }
75
                /* Map 21-bit characters to '\U00xxxxxx' */
76
1.36k
                else {
77
1.36k
                    *odata++ = 'U';
78
1.36k
                    *odata++ = Py_hexdigits[(ch >> 28) & 0xF];
79
1.36k
                    *odata++ = Py_hexdigits[(ch >> 24) & 0xF];
80
1.36k
                    *odata++ = Py_hexdigits[(ch >> 20) & 0xF];
81
1.36k
                    *odata++ = Py_hexdigits[(ch >> 16) & 0xF];
82
1.36k
                    *odata++ = Py_hexdigits[(ch >> 12) & 0xF];
83
1.36k
                    *odata++ = Py_hexdigits[(ch >> 8) & 0xF];
84
1.36k
                    *odata++ = Py_hexdigits[(ch >> 4) & 0xF];
85
1.36k
                    *odata++ = Py_hexdigits[ch & 0xF];
86
1.36k
                }
87
6.61k
            }
88
            /* Copy characters as-is */
89
8.85k
            else {
90
8.85k
                *odata++ = ch;
91
8.85k
            }
92
15.4k
        }
93
1.00M
    }
94
1.43k
    *odata = quote;
95
1.43k
}