Mercurial > cpython-lru_cache-weakref
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 |
| 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 |
