| 
									
										
										
										
											2007-10-16 06:31:30 +00:00
										 |  |  | /* NOTE: this API is -ONLY- for use with single byte character strings. */ | 
					
						
							|  |  |  | /* Do not use it with Unicode. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* the more complicated methods.  parts of these should be pulled out into the
 | 
					
						
							|  |  |  |    shared code in bytes_methods.c to cut down on duplicate code bloat.  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(expandtabs__doc__, | 
					
						
							| 
									
										
										
										
											2007-11-06 21:34:58 +00:00
										 |  |  | "B.expandtabs([tabsize]) -> copy of B\n\
 | 
					
						
							| 
									
										
										
										
											2007-10-16 06:31:30 +00:00
										 |  |  | \n\ | 
					
						
							|  |  |  | Return a copy of B where all tab characters are expanded using spaces.\n\ | 
					
						
							|  |  |  | If tabsize is not given, a tab size of 8 characters is assumed."); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject* | 
					
						
							|  |  |  | stringlib_expandtabs(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const char *e, *p; | 
					
						
							|  |  |  |     char *q; | 
					
						
							| 
									
										
										
										
											2009-01-13 22:59:11 +00:00
										 |  |  |     size_t i, j; | 
					
						
							| 
									
										
										
										
											2007-10-16 06:31:30 +00:00
										 |  |  |     PyObject *u; | 
					
						
							|  |  |  |     int tabsize = 8; | 
					
						
							| 
									
										
										
										
											2013-04-21 04:07:51 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-16 06:31:30 +00:00
										 |  |  |     if (!PyArg_ParseTuple(args, "|i:expandtabs", &tabsize)) | 
					
						
							| 
									
										
										
										
											2009-01-13 22:59:11 +00:00
										 |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2013-04-21 04:07:51 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-16 06:31:30 +00:00
										 |  |  |     /* First pass: determine size of output string */ | 
					
						
							| 
									
										
										
										
											2009-01-13 22:59:11 +00:00
										 |  |  |     i = j = 0; | 
					
						
							| 
									
										
										
										
											2007-10-16 06:31:30 +00:00
										 |  |  |     e = STRINGLIB_STR(self) + STRINGLIB_LEN(self); | 
					
						
							|  |  |  |     for (p = STRINGLIB_STR(self); p < e; p++) | 
					
						
							|  |  |  |         if (*p == '\t') { | 
					
						
							| 
									
										
										
										
											2009-01-13 22:59:11 +00:00
										 |  |  |             if (tabsize > 0) { | 
					
						
							|  |  |  |                 j += tabsize - (j % tabsize); | 
					
						
							|  |  |  |                 if (j > PY_SSIZE_T_MAX) { | 
					
						
							|  |  |  |                     PyErr_SetString(PyExc_OverflowError, | 
					
						
							|  |  |  |                                     "result is too long"); | 
					
						
							|  |  |  |                     return NULL; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2007-10-16 06:31:30 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2009-01-13 22:59:11 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2007-10-16 06:31:30 +00:00
										 |  |  |         else { | 
					
						
							|  |  |  |             j++; | 
					
						
							|  |  |  |             if (*p == '\n' || *p == '\r') { | 
					
						
							|  |  |  |                 i += j; | 
					
						
							| 
									
										
										
										
											2009-01-13 22:59:11 +00:00
										 |  |  |                 j = 0; | 
					
						
							|  |  |  |                 if (i > PY_SSIZE_T_MAX) { | 
					
						
							| 
									
										
										
										
											2007-10-16 06:31:30 +00:00
										 |  |  |                     PyErr_SetString(PyExc_OverflowError, | 
					
						
							|  |  |  |                                     "result is too long"); | 
					
						
							|  |  |  |                     return NULL; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2013-04-21 04:07:51 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-13 22:59:11 +00:00
										 |  |  |     if ((i + j) > PY_SSIZE_T_MAX) { | 
					
						
							| 
									
										
										
										
											2007-10-16 06:31:30 +00:00
										 |  |  |         PyErr_SetString(PyExc_OverflowError, "result is too long"); | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-04-21 04:07:51 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-16 06:31:30 +00:00
										 |  |  |     /* Second pass: create output string and fill it */ | 
					
						
							|  |  |  |     u = STRINGLIB_NEW(NULL, i + j); | 
					
						
							|  |  |  |     if (!u) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2013-04-21 04:07:51 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-16 06:31:30 +00:00
										 |  |  |     j = 0; | 
					
						
							|  |  |  |     q = STRINGLIB_STR(u); | 
					
						
							| 
									
										
										
										
											2013-04-21 04:07:51 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-16 06:31:30 +00:00
										 |  |  |     for (p = STRINGLIB_STR(self); p < e; p++) | 
					
						
							|  |  |  |         if (*p == '\t') { | 
					
						
							| 
									
										
										
										
											2009-01-13 22:59:11 +00:00
										 |  |  |             if (tabsize > 0) { | 
					
						
							|  |  |  |                 i = tabsize - (j % tabsize); | 
					
						
							|  |  |  |                 j += i; | 
					
						
							|  |  |  |                 while (i--) | 
					
						
							|  |  |  |                     *q++ = ' '; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							| 
									
										
										
										
											2007-10-16 06:31:30 +00:00
										 |  |  |             j++; | 
					
						
							| 
									
										
										
										
											2009-01-13 22:59:11 +00:00
										 |  |  |             *q++ = *p; | 
					
						
							| 
									
										
										
										
											2007-10-16 06:31:30 +00:00
										 |  |  |             if (*p == '\n' || *p == '\r') | 
					
						
							|  |  |  |                 j = 0; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2013-04-21 04:07:51 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-16 06:31:30 +00:00
										 |  |  |     return u; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Py_LOCAL_INLINE(PyObject *) | 
					
						
							|  |  |  | pad(PyObject *self, Py_ssize_t left, Py_ssize_t right, char fill) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyObject *u; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (left < 0) | 
					
						
							|  |  |  |         left = 0; | 
					
						
							|  |  |  |     if (right < 0) | 
					
						
							|  |  |  |         right = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (left == 0 && right == 0 && STRINGLIB_CHECK_EXACT(self)) { | 
					
						
							|  |  |  | #if STRINGLIB_MUTABLE
 | 
					
						
							|  |  |  |         /* We're defined as returning a copy;  If the object is mutable
 | 
					
						
							|  |  |  |          * that means we must make an identical copy. */ | 
					
						
							|  |  |  |         return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self)); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |         Py_INCREF(self); | 
					
						
							|  |  |  |         return (PyObject *)self; | 
					
						
							|  |  |  | #endif /* STRINGLIB_MUTABLE */
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     u = STRINGLIB_NEW(NULL, | 
					
						
							|  |  |  | 				   left + STRINGLIB_LEN(self) + right); | 
					
						
							|  |  |  |     if (u) { | 
					
						
							|  |  |  |         if (left) | 
					
						
							|  |  |  |             memset(STRINGLIB_STR(u), fill, left); | 
					
						
							|  |  |  |         Py_MEMCPY(STRINGLIB_STR(u) + left, | 
					
						
							|  |  |  | 	       STRINGLIB_STR(self), | 
					
						
							|  |  |  | 	       STRINGLIB_LEN(self)); | 
					
						
							|  |  |  |         if (right) | 
					
						
							|  |  |  |             memset(STRINGLIB_STR(u) + left + STRINGLIB_LEN(self), | 
					
						
							|  |  |  | 		   fill, right); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return u; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(ljust__doc__, | 
					
						
							| 
									
										
										
										
											2007-11-06 21:34:58 +00:00
										 |  |  | "B.ljust(width[, fillchar]) -> copy of B\n" | 
					
						
							| 
									
										
										
										
											2007-10-16 06:31:30 +00:00
										 |  |  | "\n" | 
					
						
							|  |  |  | "Return B left justified in a string of length width. Padding is\n" | 
					
						
							|  |  |  | "done using the specified fill character (default is a space)."); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | stringlib_ljust(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Py_ssize_t width; | 
					
						
							|  |  |  |     char fillchar = ' '; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "n|c:ljust", &width, &fillchar)) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (STRINGLIB_LEN(self) >= width && STRINGLIB_CHECK_EXACT(self)) { | 
					
						
							|  |  |  | #if STRINGLIB_MUTABLE
 | 
					
						
							|  |  |  |         /* We're defined as returning a copy;  If the object is mutable
 | 
					
						
							|  |  |  |          * that means we must make an identical copy. */ | 
					
						
							|  |  |  |         return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self)); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |         Py_INCREF(self); | 
					
						
							|  |  |  |         return (PyObject*) self; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return pad(self, 0, width - STRINGLIB_LEN(self), fillchar); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(rjust__doc__, | 
					
						
							| 
									
										
										
										
											2007-11-06 21:34:58 +00:00
										 |  |  | "B.rjust(width[, fillchar]) -> copy of B\n" | 
					
						
							| 
									
										
										
										
											2007-10-16 06:31:30 +00:00
										 |  |  | "\n" | 
					
						
							|  |  |  | "Return B right justified in a string of length width. Padding is\n" | 
					
						
							|  |  |  | "done using the specified fill character (default is a space)"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | stringlib_rjust(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Py_ssize_t width; | 
					
						
							|  |  |  |     char fillchar = ' '; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "n|c:rjust", &width, &fillchar)) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (STRINGLIB_LEN(self) >= width && STRINGLIB_CHECK_EXACT(self)) { | 
					
						
							|  |  |  | #if STRINGLIB_MUTABLE
 | 
					
						
							|  |  |  |         /* We're defined as returning a copy;  If the object is mutable
 | 
					
						
							|  |  |  |          * that means we must make an identical copy. */ | 
					
						
							|  |  |  |         return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self)); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |         Py_INCREF(self); | 
					
						
							|  |  |  |         return (PyObject*) self; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return pad(self, width - STRINGLIB_LEN(self), 0, fillchar); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(center__doc__, | 
					
						
							| 
									
										
										
										
											2007-11-06 21:34:58 +00:00
										 |  |  | "B.center(width[, fillchar]) -> copy of B\n" | 
					
						
							| 
									
										
										
										
											2007-10-16 06:31:30 +00:00
										 |  |  | "\n" | 
					
						
							| 
									
										
										
										
											2007-11-06 21:34:58 +00:00
										 |  |  | "Return B centered in a string of length width.  Padding is\n" | 
					
						
							|  |  |  | "done using the specified fill character (default is a space)."); | 
					
						
							| 
									
										
										
										
											2007-10-16 06:31:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | stringlib_center(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Py_ssize_t marg, left; | 
					
						
							|  |  |  |     Py_ssize_t width; | 
					
						
							|  |  |  |     char fillchar = ' '; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "n|c:center", &width, &fillchar)) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (STRINGLIB_LEN(self) >= width && STRINGLIB_CHECK_EXACT(self)) { | 
					
						
							|  |  |  | #if STRINGLIB_MUTABLE
 | 
					
						
							|  |  |  |         /* We're defined as returning a copy;  If the object is mutable
 | 
					
						
							|  |  |  |          * that means we must make an identical copy. */ | 
					
						
							|  |  |  |         return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self)); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |         Py_INCREF(self); | 
					
						
							|  |  |  |         return (PyObject*) self; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     marg = width - STRINGLIB_LEN(self); | 
					
						
							|  |  |  |     left = marg / 2 + (marg & width & 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return pad(self, left, marg - left, fillchar); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyDoc_STRVAR(zfill__doc__, | 
					
						
							| 
									
										
										
										
											2007-11-06 21:34:58 +00:00
										 |  |  | "B.zfill(width) -> copy of B\n" | 
					
						
							| 
									
										
										
										
											2007-10-16 06:31:30 +00:00
										 |  |  | "\n" | 
					
						
							|  |  |  | "Pad a numeric string B with zeros on the left, to fill a field\n" | 
					
						
							|  |  |  | "of the specified width.  B is never truncated."); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | stringlib_zfill(PyObject *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Py_ssize_t fill; | 
					
						
							|  |  |  |     PyObject *s; | 
					
						
							|  |  |  |     char *p; | 
					
						
							|  |  |  |     Py_ssize_t width; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!PyArg_ParseTuple(args, "n:zfill", &width)) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (STRINGLIB_LEN(self) >= width) { | 
					
						
							|  |  |  |         if (STRINGLIB_CHECK_EXACT(self)) { | 
					
						
							|  |  |  | #if STRINGLIB_MUTABLE
 | 
					
						
							|  |  |  |             /* We're defined as returning a copy;  If the object is mutable
 | 
					
						
							|  |  |  |              * that means we must make an identical copy. */ | 
					
						
							|  |  |  |             return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self)); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |             Py_INCREF(self); | 
					
						
							|  |  |  |             return (PyObject*) self; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             return STRINGLIB_NEW( | 
					
						
							|  |  |  |                 STRINGLIB_STR(self), | 
					
						
							|  |  |  |                 STRINGLIB_LEN(self) | 
					
						
							|  |  |  |             ); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     fill = width - STRINGLIB_LEN(self); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s = pad(self, fill, 0, '0'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (s == NULL) | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     p = STRINGLIB_STR(s); | 
					
						
							|  |  |  |     if (p[fill] == '+' || p[fill] == '-') { | 
					
						
							|  |  |  |         /* move sign to beginning of string */ | 
					
						
							|  |  |  |         p[0] = p[fill]; | 
					
						
							|  |  |  |         p[fill] = '0'; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return (PyObject*) s; | 
					
						
							|  |  |  | } |