1 /* NOTE: this API is -ONLY- for use with single byte character strings. */
2 /* Do not use it with Unicode. */
4 #include "bytes_methods.h"
6 #ifndef STRINGLIB_MUTABLE
7 #warning "STRINGLIB_MUTABLE not defined before #include, assuming 0"
8 #define STRINGLIB_MUTABLE 0
11 /* the more complicated methods. parts of these should be pulled out into the
12 shared code in bytes_methods.c to cut down on duplicate code bloat. */
14 PyDoc_STRVAR(expandtabs__doc__
,
15 "B.expandtabs([tabsize]) -> copy of B\n\
17 Return a copy of B where all tab characters are expanded using spaces.\n\
18 If tabsize is not given, a tab size of 8 characters is assumed.");
21 stringlib_expandtabs(PyObject
*self
, PyObject
*args
)
25 Py_ssize_t i
, j
, old_j
;
29 if (!PyArg_ParseTuple(args
, "|i:expandtabs", &tabsize
))
32 /* First pass: determine size of output string */
34 e
= STRINGLIB_STR(self
) + STRINGLIB_LEN(self
);
35 for (p
= STRINGLIB_STR(self
); p
< e
; p
++)
38 j
+= tabsize
- (j
% tabsize
);
39 /* XXX: this depends on a signed integer overflow to < 0 */
40 /* C compilers, including gcc, do -NOT- guarantee this. */
42 PyErr_SetString(PyExc_OverflowError
,
43 "result is too long");
51 if (*p
== '\n' || *p
== '\r') {
54 /* XXX: this depends on a signed integer overflow to < 0 */
55 /* C compilers, including gcc, do -NOT- guarantee this. */
57 PyErr_SetString(PyExc_OverflowError
,
58 "result is too long");
65 /* XXX: this depends on a signed integer overflow to < 0 */
66 /* C compilers, including gcc, do -NOT- guarantee this. */
67 PyErr_SetString(PyExc_OverflowError
, "result is too long");
71 /* Second pass: create output string and fill it */
72 u
= STRINGLIB_NEW(NULL
, i
+ j
);
79 for (p
= STRINGLIB_STR(self
); p
< e
; p
++)
82 i
= tabsize
- (j
% tabsize
);
91 if (*p
== '\n' || *p
== '\r')
98 Py_LOCAL_INLINE(PyObject
*)
99 pad(PyObject
*self
, Py_ssize_t left
, Py_ssize_t right
, char fill
)
108 if (left
== 0 && right
== 0 && STRINGLIB_CHECK_EXACT(self
)) {
109 #if STRINGLIB_MUTABLE
110 /* We're defined as returning a copy; If the object is mutable
111 * that means we must make an identical copy. */
112 return STRINGLIB_NEW(STRINGLIB_STR(self
), STRINGLIB_LEN(self
));
115 return (PyObject
*)self
;
116 #endif /* STRINGLIB_MUTABLE */
119 u
= STRINGLIB_NEW(NULL
,
120 left
+ STRINGLIB_LEN(self
) + right
);
123 memset(STRINGLIB_STR(u
), fill
, left
);
124 Py_MEMCPY(STRINGLIB_STR(u
) + left
,
126 STRINGLIB_LEN(self
));
128 memset(STRINGLIB_STR(u
) + left
+ STRINGLIB_LEN(self
),
135 PyDoc_STRVAR(ljust__doc__
,
136 "B.ljust(width[, fillchar]) -> copy of B\n"
138 "Return B left justified in a string of length width. Padding is\n"
139 "done using the specified fill character (default is a space).");
142 stringlib_ljust(PyObject
*self
, PyObject
*args
)
147 if (!PyArg_ParseTuple(args
, "n|c:ljust", &width
, &fillchar
))
150 if (STRINGLIB_LEN(self
) >= width
&& STRINGLIB_CHECK_EXACT(self
)) {
151 #if STRINGLIB_MUTABLE
152 /* We're defined as returning a copy; If the object is mutable
153 * that means we must make an identical copy. */
154 return STRINGLIB_NEW(STRINGLIB_STR(self
), STRINGLIB_LEN(self
));
157 return (PyObject
*) self
;
161 return pad(self
, 0, width
- STRINGLIB_LEN(self
), fillchar
);
165 PyDoc_STRVAR(rjust__doc__
,
166 "B.rjust(width[, fillchar]) -> copy of B\n"
168 "Return B right justified in a string of length width. Padding is\n"
169 "done using the specified fill character (default is a space)");
172 stringlib_rjust(PyObject
*self
, PyObject
*args
)
177 if (!PyArg_ParseTuple(args
, "n|c:rjust", &width
, &fillchar
))
180 if (STRINGLIB_LEN(self
) >= width
&& STRINGLIB_CHECK_EXACT(self
)) {
181 #if STRINGLIB_MUTABLE
182 /* We're defined as returning a copy; If the object is mutable
183 * that means we must make an identical copy. */
184 return STRINGLIB_NEW(STRINGLIB_STR(self
), STRINGLIB_LEN(self
));
187 return (PyObject
*) self
;
191 return pad(self
, width
- STRINGLIB_LEN(self
), 0, fillchar
);
195 PyDoc_STRVAR(center__doc__
,
196 "B.center(width[, fillchar]) -> copy of B\n"
198 "Return B centered in a string of length width. Padding is\n"
199 "done using the specified fill character (default is a space).");
202 stringlib_center(PyObject
*self
, PyObject
*args
)
204 Py_ssize_t marg
, left
;
208 if (!PyArg_ParseTuple(args
, "n|c:center", &width
, &fillchar
))
211 if (STRINGLIB_LEN(self
) >= width
&& STRINGLIB_CHECK_EXACT(self
)) {
212 #if STRINGLIB_MUTABLE
213 /* We're defined as returning a copy; If the object is mutable
214 * that means we must make an identical copy. */
215 return STRINGLIB_NEW(STRINGLIB_STR(self
), STRINGLIB_LEN(self
));
218 return (PyObject
*) self
;
222 marg
= width
- STRINGLIB_LEN(self
);
223 left
= marg
/ 2 + (marg
& width
& 1);
225 return pad(self
, left
, marg
- left
, fillchar
);
228 PyDoc_STRVAR(zfill__doc__
,
229 "B.zfill(width) -> copy of B\n"
231 "Pad a numeric string B with zeros on the left, to fill a field\n"
232 "of the specified width. B is never truncated.");
235 stringlib_zfill(PyObject
*self
, PyObject
*args
)
242 if (!PyArg_ParseTuple(args
, "n:zfill", &width
))
245 if (STRINGLIB_LEN(self
) >= width
) {
246 if (STRINGLIB_CHECK_EXACT(self
)) {
247 #if STRINGLIB_MUTABLE
248 /* We're defined as returning a copy; If the object is mutable
249 * that means we must make an identical copy. */
250 return STRINGLIB_NEW(STRINGLIB_STR(self
), STRINGLIB_LEN(self
));
253 return (PyObject
*) self
;
257 return STRINGLIB_NEW(
263 fill
= width
- STRINGLIB_LEN(self
);
265 s
= pad(self
, fill
, 0, '0');
270 p
= STRINGLIB_STR(s
);
271 if (p
[fill
] == '+' || p
[fill
] == '-') {
272 /* move sign to beginning of string */
277 return (PyObject
*) s
;
281 #define _STRINGLIB_SPLIT_APPEND(data, left, right) \
282 str = STRINGLIB_NEW((data) + (left), \
286 if (PyList_Append(list, str)) { \
293 PyDoc_STRVAR(splitlines__doc__
,
294 "B.splitlines([keepends]) -> list of lines\n\
296 Return a list of the lines in B, breaking at line boundaries.\n\
297 Line breaks are not included in the resulting list unless keepends\n\
298 is given and true.");
301 stringlib_splitlines(PyObject
*self
, PyObject
*args
)
303 register Py_ssize_t i
;
304 register Py_ssize_t j
;
311 if (!PyArg_ParseTuple(args
, "|i:splitlines", &keepends
))
314 data
= STRINGLIB_STR(self
);
315 len
= STRINGLIB_LEN(self
);
317 /* This does not use the preallocated list because splitlines is
318 usually run with hundreds of newlines. The overhead of
319 switching between PyList_SET_ITEM and append causes about a
320 2-3% slowdown for that common case. A smarter implementation
321 could move the if check out, so the SET_ITEMs are done first
322 and the appends only done when the prealloc buffer is full.
323 That's too much work for little gain.*/
325 list
= PyList_New(0);
329 for (i
= j
= 0; i
< len
; ) {
332 /* Find a line and append it */
333 while (i
< len
&& data
[i
] != '\n' && data
[i
] != '\r')
336 /* Skip the line break reading CRLF as one line break */
339 if (data
[i
] == '\r' && i
+ 1 < len
&&
347 _STRINGLIB_SPLIT_APPEND(data
, j
, eol
);
351 _STRINGLIB_SPLIT_APPEND(data
, j
, len
);
361 #undef _STRINGLIB_SPLIT_APPEND