annotate Objects/stringlib/split.h @ 80661:94de77bd0b4b 2.7

Issue #16194: document imp.load_dynamic problems when read several extension modules from the same binary object file.
author Andrew Svetlov <andrew.svetlov@gmail.com>
date Thu, 29 Nov 2012 19:51:28 +0200
parents 66f1d4a4c799
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
58288
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
1 /* stringlib: split implementation */
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
2
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
3 #ifndef STRINGLIB_SPLIT_H
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
4 #define STRINGLIB_SPLIT_H
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
5
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
6 #ifndef STRINGLIB_FASTSEARCH_H
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
7 #error must include "stringlib/fastsearch.h" before including this module
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
8 #endif
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
9
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
10 /* Overallocate the initial list to reduce the number of reallocs for small
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
11 split sizes. Eg, "A A A A A A A A A A".split() (10 elements) has three
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
12 resizes, to sizes 4, 8, then 16. Most observed string splits are for human
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
13 text (roughly 11 words per line) and field delimited data (usually 1-10
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
14 fields). For large strings the split algorithms are bandwidth limited
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
15 so increasing the preallocation likely will not improve things.*/
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
16
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
17 #define MAX_PREALLOC 12
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
18
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
19 /* 5 splits gives 6 elements */
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
20 #define PREALLOC_SIZE(maxsplit) \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
21 (maxsplit >= MAX_PREALLOC ? MAX_PREALLOC : maxsplit+1)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
22
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
23 #define SPLIT_APPEND(data, left, right) \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
24 sub = STRINGLIB_NEW((data) + (left), \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
25 (right) - (left)); \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
26 if (sub == NULL) \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
27 goto onError; \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
28 if (PyList_Append(list, sub)) { \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
29 Py_DECREF(sub); \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
30 goto onError; \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
31 } \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
32 else \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
33 Py_DECREF(sub);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
34
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
35 #define SPLIT_ADD(data, left, right) { \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
36 sub = STRINGLIB_NEW((data) + (left), \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
37 (right) - (left)); \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
38 if (sub == NULL) \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
39 goto onError; \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
40 if (count < MAX_PREALLOC) { \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
41 PyList_SET_ITEM(list, count, sub); \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
42 } else { \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
43 if (PyList_Append(list, sub)) { \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
44 Py_DECREF(sub); \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
45 goto onError; \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
46 } \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
47 else \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
48 Py_DECREF(sub); \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
49 } \
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
50 count++; }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
51
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
52
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
53 /* Always force the list to the expected size. */
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
54 #define FIX_PREALLOC_SIZE(list) Py_SIZE(list) = count
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
55
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
56 Py_LOCAL_INLINE(PyObject *)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
57 stringlib_split_whitespace(PyObject* str_obj,
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
58 const STRINGLIB_CHAR* str, Py_ssize_t str_len,
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
59 Py_ssize_t maxcount)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
60 {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
61 Py_ssize_t i, j, count=0;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
62 PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
63 PyObject *sub;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
64
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
65 if (list == NULL)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
66 return NULL;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
67
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
68 i = j = 0;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
69 while (maxcount-- > 0) {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
70 while (i < str_len && STRINGLIB_ISSPACE(str[i]))
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
71 i++;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
72 if (i == str_len) break;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
73 j = i; i++;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
74 while (i < str_len && !STRINGLIB_ISSPACE(str[i]))
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
75 i++;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
76 #ifndef STRINGLIB_MUTABLE
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
77 if (j == 0 && i == str_len && STRINGLIB_CHECK_EXACT(str_obj)) {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
78 /* No whitespace in str_obj, so just use it as list[0] */
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
79 Py_INCREF(str_obj);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
80 PyList_SET_ITEM(list, 0, (PyObject *)str_obj);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
81 count++;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
82 break;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
83 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
84 #endif
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
85 SPLIT_ADD(str, j, i);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
86 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
87
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
88 if (i < str_len) {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
89 /* Only occurs when maxcount was reached */
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
90 /* Skip any remaining whitespace and copy to end of string */
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
91 while (i < str_len && STRINGLIB_ISSPACE(str[i]))
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
92 i++;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
93 if (i != str_len)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
94 SPLIT_ADD(str, i, str_len);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
95 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
96 FIX_PREALLOC_SIZE(list);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
97 return list;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
98
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
99 onError:
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
100 Py_DECREF(list);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
101 return NULL;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
102 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
103
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
104 Py_LOCAL_INLINE(PyObject *)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
105 stringlib_split_char(PyObject* str_obj,
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
106 const STRINGLIB_CHAR* str, Py_ssize_t str_len,
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
107 const STRINGLIB_CHAR ch,
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
108 Py_ssize_t maxcount)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
109 {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
110 Py_ssize_t i, j, count=0;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
111 PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
112 PyObject *sub;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
113
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
114 if (list == NULL)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
115 return NULL;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
116
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
117 i = j = 0;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
118 while ((j < str_len) && (maxcount-- > 0)) {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
119 for(; j < str_len; j++) {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
120 /* I found that using memchr makes no difference */
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
121 if (str[j] == ch) {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
122 SPLIT_ADD(str, i, j);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
123 i = j = j + 1;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
124 break;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
125 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
126 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
127 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
128 #ifndef STRINGLIB_MUTABLE
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
129 if (count == 0 && STRINGLIB_CHECK_EXACT(str_obj)) {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
130 /* ch not in str_obj, so just use str_obj as list[0] */
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
131 Py_INCREF(str_obj);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
132 PyList_SET_ITEM(list, 0, (PyObject *)str_obj);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
133 count++;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
134 } else
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
135 #endif
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
136 if (i <= str_len) {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
137 SPLIT_ADD(str, i, str_len);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
138 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
139 FIX_PREALLOC_SIZE(list);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
140 return list;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
141
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
142 onError:
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
143 Py_DECREF(list);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
144 return NULL;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
145 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
146
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
147 Py_LOCAL_INLINE(PyObject *)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
148 stringlib_split(PyObject* str_obj,
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
149 const STRINGLIB_CHAR* str, Py_ssize_t str_len,
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
150 const STRINGLIB_CHAR* sep, Py_ssize_t sep_len,
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
151 Py_ssize_t maxcount)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
152 {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
153 Py_ssize_t i, j, pos, count=0;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
154 PyObject *list, *sub;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
155
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
156 if (sep_len == 0) {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
157 PyErr_SetString(PyExc_ValueError, "empty separator");
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
158 return NULL;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
159 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
160 else if (sep_len == 1)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
161 return stringlib_split_char(str_obj, str, str_len, sep[0], maxcount);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
162
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
163 list = PyList_New(PREALLOC_SIZE(maxcount));
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
164 if (list == NULL)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
165 return NULL;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
166
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
167 i = j = 0;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
168 while (maxcount-- > 0) {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
169 pos = fastsearch(str+i, str_len-i, sep, sep_len, -1, FAST_SEARCH);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
170 if (pos < 0)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
171 break;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
172 j = i + pos;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
173 SPLIT_ADD(str, i, j);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
174 i = j + sep_len;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
175 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
176 #ifndef STRINGLIB_MUTABLE
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
177 if (count == 0 && STRINGLIB_CHECK_EXACT(str_obj)) {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
178 /* No match in str_obj, so just use it as list[0] */
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
179 Py_INCREF(str_obj);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
180 PyList_SET_ITEM(list, 0, (PyObject *)str_obj);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
181 count++;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
182 } else
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
183 #endif
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
184 {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
185 SPLIT_ADD(str, i, str_len);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
186 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
187 FIX_PREALLOC_SIZE(list);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
188 return list;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
189
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
190 onError:
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
191 Py_DECREF(list);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
192 return NULL;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
193 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
194
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
195 Py_LOCAL_INLINE(PyObject *)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
196 stringlib_rsplit_whitespace(PyObject* str_obj,
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
197 const STRINGLIB_CHAR* str, Py_ssize_t str_len,
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
198 Py_ssize_t maxcount)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
199 {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
200 Py_ssize_t i, j, count=0;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
201 PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
202 PyObject *sub;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
203
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
204 if (list == NULL)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
205 return NULL;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
206
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
207 i = j = str_len - 1;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
208 while (maxcount-- > 0) {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
209 while (i >= 0 && STRINGLIB_ISSPACE(str[i]))
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
210 i--;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
211 if (i < 0) break;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
212 j = i; i--;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
213 while (i >= 0 && !STRINGLIB_ISSPACE(str[i]))
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
214 i--;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
215 #ifndef STRINGLIB_MUTABLE
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
216 if (j == str_len - 1 && i < 0 && STRINGLIB_CHECK_EXACT(str_obj)) {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
217 /* No whitespace in str_obj, so just use it as list[0] */
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
218 Py_INCREF(str_obj);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
219 PyList_SET_ITEM(list, 0, (PyObject *)str_obj);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
220 count++;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
221 break;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
222 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
223 #endif
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
224 SPLIT_ADD(str, i + 1, j + 1);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
225 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
226
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
227 if (i >= 0) {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
228 /* Only occurs when maxcount was reached */
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
229 /* Skip any remaining whitespace and copy to beginning of string */
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
230 while (i >= 0 && STRINGLIB_ISSPACE(str[i]))
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
231 i--;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
232 if (i >= 0)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
233 SPLIT_ADD(str, 0, i + 1);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
234 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
235 FIX_PREALLOC_SIZE(list);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
236 if (PyList_Reverse(list) < 0)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
237 goto onError;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
238 return list;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
239
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
240 onError:
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
241 Py_DECREF(list);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
242 return NULL;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
243 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
244
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
245 Py_LOCAL_INLINE(PyObject *)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
246 stringlib_rsplit_char(PyObject* str_obj,
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
247 const STRINGLIB_CHAR* str, Py_ssize_t str_len,
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
248 const STRINGLIB_CHAR ch,
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
249 Py_ssize_t maxcount)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
250 {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
251 Py_ssize_t i, j, count=0;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
252 PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
253 PyObject *sub;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
254
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
255 if (list == NULL)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
256 return NULL;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
257
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
258 i = j = str_len - 1;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
259 while ((i >= 0) && (maxcount-- > 0)) {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
260 for(; i >= 0; i--) {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
261 if (str[i] == ch) {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
262 SPLIT_ADD(str, i + 1, j + 1);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
263 j = i = i - 1;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
264 break;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
265 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
266 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
267 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
268 #ifndef STRINGLIB_MUTABLE
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
269 if (count == 0 && STRINGLIB_CHECK_EXACT(str_obj)) {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
270 /* ch not in str_obj, so just use str_obj as list[0] */
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
271 Py_INCREF(str_obj);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
272 PyList_SET_ITEM(list, 0, (PyObject *)str_obj);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
273 count++;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
274 } else
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
275 #endif
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
276 if (j >= -1) {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
277 SPLIT_ADD(str, 0, j + 1);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
278 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
279 FIX_PREALLOC_SIZE(list);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
280 if (PyList_Reverse(list) < 0)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
281 goto onError;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
282 return list;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
283
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
284 onError:
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
285 Py_DECREF(list);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
286 return NULL;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
287 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
288
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
289 Py_LOCAL_INLINE(PyObject *)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
290 stringlib_rsplit(PyObject* str_obj,
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
291 const STRINGLIB_CHAR* str, Py_ssize_t str_len,
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
292 const STRINGLIB_CHAR* sep, Py_ssize_t sep_len,
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
293 Py_ssize_t maxcount)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
294 {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
295 Py_ssize_t j, pos, count=0;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
296 PyObject *list, *sub;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
297
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
298 if (sep_len == 0) {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
299 PyErr_SetString(PyExc_ValueError, "empty separator");
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
300 return NULL;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
301 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
302 else if (sep_len == 1)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
303 return stringlib_rsplit_char(str_obj, str, str_len, sep[0], maxcount);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
304
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
305 list = PyList_New(PREALLOC_SIZE(maxcount));
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
306 if (list == NULL)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
307 return NULL;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
308
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
309 j = str_len;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
310 while (maxcount-- > 0) {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
311 pos = fastsearch(str, j, sep, sep_len, -1, FAST_RSEARCH);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
312 if (pos < 0)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
313 break;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
314 SPLIT_ADD(str, pos + sep_len, j);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
315 j = pos;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
316 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
317 #ifndef STRINGLIB_MUTABLE
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
318 if (count == 0 && STRINGLIB_CHECK_EXACT(str_obj)) {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
319 /* No match in str_obj, so just use it as list[0] */
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
320 Py_INCREF(str_obj);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
321 PyList_SET_ITEM(list, 0, (PyObject *)str_obj);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
322 count++;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
323 } else
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
324 #endif
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
325 {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
326 SPLIT_ADD(str, 0, j);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
327 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
328 FIX_PREALLOC_SIZE(list);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
329 if (PyList_Reverse(list) < 0)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
330 goto onError;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
331 return list;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
332
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
333 onError:
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
334 Py_DECREF(list);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
335 return NULL;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
336 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
337
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
338 Py_LOCAL_INLINE(PyObject *)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
339 stringlib_splitlines(PyObject* str_obj,
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
340 const STRINGLIB_CHAR* str, Py_ssize_t str_len,
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
341 int keepends)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
342 {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
343 /* This does not use the preallocated list because splitlines is
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
344 usually run with hundreds of newlines. The overhead of
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
345 switching between PyList_SET_ITEM and append causes about a
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
346 2-3% slowdown for that common case. A smarter implementation
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
347 could move the if check out, so the SET_ITEMs are done first
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
348 and the appends only done when the prealloc buffer is full.
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
349 That's too much work for little gain.*/
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
350
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
351 register Py_ssize_t i;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
352 register Py_ssize_t j;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
353 PyObject *list = PyList_New(0);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
354 PyObject *sub;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
355
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
356 if (list == NULL)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
357 return NULL;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
358
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
359 for (i = j = 0; i < str_len; ) {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
360 Py_ssize_t eol;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
361
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
362 /* Find a line and append it */
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
363 while (i < str_len && !STRINGLIB_ISLINEBREAK(str[i]))
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
364 i++;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
365
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
366 /* Skip the line break reading CRLF as one line break */
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
367 eol = i;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
368 if (i < str_len) {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
369 if (str[i] == '\r' && i + 1 < str_len && str[i+1] == '\n')
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
370 i += 2;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
371 else
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
372 i++;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
373 if (keepends)
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
374 eol = i;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
375 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
376 #ifndef STRINGLIB_MUTABLE
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
377 if (j == 0 && eol == str_len && STRINGLIB_CHECK_EXACT(str_obj)) {
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
378 /* No linebreak in str_obj, so just use it as list[0] */
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
379 if (PyList_Append(list, str_obj))
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
380 goto onError;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
381 break;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
382 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
383 #endif
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
384 SPLIT_APPEND(str, j, eol);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
385 j = i;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
386 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
387 return list;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
388
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
389 onError:
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
390 Py_DECREF(list);
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
391 return NULL;
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
392 }
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
393
66f1d4a4c799 Issue #7622: Improve the split(), rsplit(), splitlines() and replace()
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
394 #endif