1/* NOTE: this API is -ONLY- for use with single byte character strings. */ 2/* Do not use it with Unicode. */ 3 4/* the more complicated methods. parts of these should be pulled out into the 5 shared code in bytes_methods.c to cut down on duplicate code bloat. */ 6 7PyDoc_STRVAR(expandtabs__doc__, 8"B.expandtabs([tabsize]) -> copy of B\n\ 9\n\ 10Return a copy of B where all tab characters are expanded using spaces.\n\ 11If tabsize is not given, a tab size of 8 characters is assumed."); 12 13static PyObject* 14stringlib_expandtabs(PyObject *self, PyObject *args) 15{ 16 const char *e, *p; 17 char *q; 18 Py_ssize_t i, j; 19 PyObject *u; 20 int tabsize = 8; 21 22 if (!PyArg_ParseTuple(args, "|i:expandtabs", &tabsize)) 23 return NULL; 24 25 /* First pass: determine size of output string */ 26 i = j = 0; 27 e = STRINGLIB_STR(self) + STRINGLIB_LEN(self); 28 for (p = STRINGLIB_STR(self); p < e; p++) { 29 if (*p == '\t') { 30 if (tabsize > 0) { 31 Py_ssize_t incr = tabsize - (j % tabsize); 32 if (j > PY_SSIZE_T_MAX - incr) 33 goto overflow; 34 j += incr; 35 } 36 } 37 else { 38 if (j > PY_SSIZE_T_MAX - 1) 39 goto overflow; 40 j++; 41 if (*p == '\n' || *p == '\r') { 42 if (i > PY_SSIZE_T_MAX - j) 43 goto overflow; 44 i += j; 45 j = 0; 46 } 47 } 48 } 49 50 if (i > PY_SSIZE_T_MAX - j) 51 goto overflow; 52 53 /* Second pass: create output string and fill it */ 54 u = STRINGLIB_NEW(NULL, i + j); 55 if (!u) 56 return NULL; 57 58 j = 0; 59 q = STRINGLIB_STR(u); 60 61 for (p = STRINGLIB_STR(self); p < e; p++) { 62 if (*p == '\t') { 63 if (tabsize > 0) { 64 i = tabsize - (j % tabsize); 65 j += i; 66 while (i--) 67 *q++ = ' '; 68 } 69 } 70 else { 71 j++; 72 *q++ = *p; 73 if (*p == '\n' || *p == '\r') 74 j = 0; 75 } 76 } 77 78 return u; 79 overflow: 80 PyErr_SetString(PyExc_OverflowError, "result too long"); 81 return NULL; 82} 83 84Py_LOCAL_INLINE(PyObject *) 85pad(PyObject *self, Py_ssize_t left, Py_ssize_t right, char fill) 86{ 87 PyObject *u; 88 89 if (left < 0) 90 left = 0; 91 if (right < 0) 92 right = 0; 93 94 if (left == 0 && right == 0 && STRINGLIB_CHECK_EXACT(self)) { 95#if STRINGLIB_MUTABLE 96 /* We're defined as returning a copy; If the object is mutable 97 * that means we must make an identical copy. */ 98 return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self)); 99#else 100 Py_INCREF(self); 101 return (PyObject *)self; 102#endif /* STRINGLIB_MUTABLE */ 103 } 104 105 u = STRINGLIB_NEW(NULL, 106 left + STRINGLIB_LEN(self) + right); 107 if (u) { 108 if (left) 109 memset(STRINGLIB_STR(u), fill, left); 110 Py_MEMCPY(STRINGLIB_STR(u) + left, 111 STRINGLIB_STR(self), 112 STRINGLIB_LEN(self)); 113 if (right) 114 memset(STRINGLIB_STR(u) + left + STRINGLIB_LEN(self), 115 fill, right); 116 } 117 118 return u; 119} 120 121PyDoc_STRVAR(ljust__doc__, 122"B.ljust(width[, fillchar]) -> copy of B\n" 123"\n" 124"Return B left justified in a string of length width. Padding is\n" 125"done using the specified fill character (default is a space)."); 126 127static PyObject * 128stringlib_ljust(PyObject *self, PyObject *args) 129{ 130 Py_ssize_t width; 131 char fillchar = ' '; 132 133 if (!PyArg_ParseTuple(args, "n|c:ljust", &width, &fillchar)) 134 return NULL; 135 136 if (STRINGLIB_LEN(self) >= width && STRINGLIB_CHECK_EXACT(self)) { 137#if STRINGLIB_MUTABLE 138 /* We're defined as returning a copy; If the object is mutable 139 * that means we must make an identical copy. */ 140 return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self)); 141#else 142 Py_INCREF(self); 143 return (PyObject*) self; 144#endif 145 } 146 147 return pad(self, 0, width - STRINGLIB_LEN(self), fillchar); 148} 149 150 151PyDoc_STRVAR(rjust__doc__, 152"B.rjust(width[, fillchar]) -> copy of B\n" 153"\n" 154"Return B right justified in a string of length width. Padding is\n" 155"done using the specified fill character (default is a space)"); 156 157static PyObject * 158stringlib_rjust(PyObject *self, PyObject *args) 159{ 160 Py_ssize_t width; 161 char fillchar = ' '; 162 163 if (!PyArg_ParseTuple(args, "n|c:rjust", &width, &fillchar)) 164 return NULL; 165 166 if (STRINGLIB_LEN(self) >= width && STRINGLIB_CHECK_EXACT(self)) { 167#if STRINGLIB_MUTABLE 168 /* We're defined as returning a copy; If the object is mutable 169 * that means we must make an identical copy. */ 170 return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self)); 171#else 172 Py_INCREF(self); 173 return (PyObject*) self; 174#endif 175 } 176 177 return pad(self, width - STRINGLIB_LEN(self), 0, fillchar); 178} 179 180 181PyDoc_STRVAR(center__doc__, 182"B.center(width[, fillchar]) -> copy of B\n" 183"\n" 184"Return B centered in a string of length width. Padding is\n" 185"done using the specified fill character (default is a space)."); 186 187static PyObject * 188stringlib_center(PyObject *self, PyObject *args) 189{ 190 Py_ssize_t marg, left; 191 Py_ssize_t width; 192 char fillchar = ' '; 193 194 if (!PyArg_ParseTuple(args, "n|c:center", &width, &fillchar)) 195 return NULL; 196 197 if (STRINGLIB_LEN(self) >= width && STRINGLIB_CHECK_EXACT(self)) { 198#if STRINGLIB_MUTABLE 199 /* We're defined as returning a copy; If the object is mutable 200 * that means we must make an identical copy. */ 201 return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self)); 202#else 203 Py_INCREF(self); 204 return (PyObject*) self; 205#endif 206 } 207 208 marg = width - STRINGLIB_LEN(self); 209 left = marg / 2 + (marg & width & 1); 210 211 return pad(self, left, marg - left, fillchar); 212} 213 214PyDoc_STRVAR(zfill__doc__, 215"B.zfill(width) -> copy of B\n" 216"\n" 217"Pad a numeric string B with zeros on the left, to fill a field\n" 218"of the specified width. B is never truncated."); 219 220static PyObject * 221stringlib_zfill(PyObject *self, PyObject *args) 222{ 223 Py_ssize_t fill; 224 PyObject *s; 225 char *p; 226 Py_ssize_t width; 227 228 if (!PyArg_ParseTuple(args, "n:zfill", &width)) 229 return NULL; 230 231 if (STRINGLIB_LEN(self) >= width) { 232 if (STRINGLIB_CHECK_EXACT(self)) { 233#if STRINGLIB_MUTABLE 234 /* We're defined as returning a copy; If the object is mutable 235 * that means we must make an identical copy. */ 236 return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self)); 237#else 238 Py_INCREF(self); 239 return (PyObject*) self; 240#endif 241 } 242 else 243 return STRINGLIB_NEW( 244 STRINGLIB_STR(self), 245 STRINGLIB_LEN(self) 246 ); 247 } 248 249 fill = width - STRINGLIB_LEN(self); 250 251 s = pad(self, fill, 0, '0'); 252 253 if (s == NULL) 254 return NULL; 255 256 p = STRINGLIB_STR(s); 257 if (p[fill] == '+' || p[fill] == '-') { 258 /* move sign to beginning of string */ 259 p[0] = p[fill]; 260 p[fill] = '0'; 261 } 262 263 return (PyObject*) s; 264} 265