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 7 PyDoc_STRVAR(expandtabs__doc__, 8 "B.expandtabs([tabsize]) -> copy of B\n\ 9 \n\ 10 Return a copy of B where all tab characters are expanded using spaces.\n\ 11 If tabsize is not given, a tab size of 8 characters is assumed."); 12 13 static PyObject* 14 stringlib_expandtabs(PyObject *self, PyObject *args) 15 { 16 const char *e, *p; 17 char *q; 18 size_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 j += tabsize - (j % tabsize); 32 if (j > PY_SSIZE_T_MAX) { 33 PyErr_SetString(PyExc_OverflowError, 34 "result is too long"); 35 return NULL; 36 } 37 } 38 } 39 else { 40 j++; 41 if (*p == '\n' || *p == '\r') { 42 i += j; 43 j = 0; 44 if (i > PY_SSIZE_T_MAX) { 45 PyErr_SetString(PyExc_OverflowError, 46 "result is too long"); 47 return NULL; 48 } 49 } 50 } 51 52 if ((i + j) > PY_SSIZE_T_MAX) { 53 PyErr_SetString(PyExc_OverflowError, "result is too long"); 54 return NULL; 55 } 56 57 /* Second pass: create output string and fill it */ 58 u = STRINGLIB_NEW(NULL, i + j); 59 if (!u) 60 return NULL; 61 62 j = 0; 63 q = STRINGLIB_STR(u); 64 65 for (p = STRINGLIB_STR(self); p < e; p++) 66 if (*p == '\t') { 67 if (tabsize > 0) { 68 i = tabsize - (j % tabsize); 69 j += i; 70 while (i--) 71 *q++ = ' '; 72 } 73 } 74 else { 75 j++; 76 *q++ = *p; 77 if (*p == '\n' || *p == '\r') 78 j = 0; 79 } 80 81 return u; 82 } 83 84 Py_LOCAL_INLINE(PyObject *) 85 pad(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 121 PyDoc_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 127 static PyObject * 128 stringlib_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 151 PyDoc_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 157 static PyObject * 158 stringlib_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 181 PyDoc_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 187 static PyObject * 188 stringlib_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 214 PyDoc_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 220 static PyObject * 221 stringlib_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