annotate Objects/stringlib/split.h @ 87690:66c1c9f32567 default tip

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