blob: cbd7144b0ef92af05084fd1db2ea5a3587764d8a [file] [log] [blame]
Gregory P. Smith60d241f2007-10-16 06:31:30 +00001/* NOTE: this API is -ONLY- for use with single byte character strings. */
2/* Do not use it with Unicode. */
3
Gregory P. Smith60d241f2007-10-16 06:31:30 +00004/* 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__,
Guido van Rossum98297ee2007-11-06 21:34:58 +00008"B.expandtabs([tabsize]) -> copy of B\n\
Gregory P. Smith60d241f2007-10-16 06:31:30 +00009\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;
Benjamin Peterson23cf4032014-03-30 19:47:57 -040018 Py_ssize_t i, j;
Gregory P. Smith60d241f2007-10-16 06:31:30 +000019 PyObject *u;
20 int tabsize = 8;
Ezio Melotti6b027722013-04-21 04:07:51 +030021
Gregory P. Smith60d241f2007-10-16 06:31:30 +000022 if (!PyArg_ParseTuple(args, "|i:expandtabs", &tabsize))
Antoine Pitrou8d4e5052009-01-13 22:59:11 +000023 return NULL;
Ezio Melotti6b027722013-04-21 04:07:51 +030024
Gregory P. Smith60d241f2007-10-16 06:31:30 +000025 /* First pass: determine size of output string */
Antoine Pitrou8d4e5052009-01-13 22:59:11 +000026 i = j = 0;
Gregory P. Smith60d241f2007-10-16 06:31:30 +000027 e = STRINGLIB_STR(self) + STRINGLIB_LEN(self);
Benjamin Peterson23cf4032014-03-30 19:47:57 -040028 for (p = STRINGLIB_STR(self); p < e; p++) {
Gregory P. Smith60d241f2007-10-16 06:31:30 +000029 if (*p == '\t') {
Antoine Pitrou8d4e5052009-01-13 22:59:11 +000030 if (tabsize > 0) {
Benjamin Peterson23cf4032014-03-30 19:47:57 -040031 Py_ssize_t incr = tabsize - (j % tabsize);
32 if (j > PY_SSIZE_T_MAX - incr)
33 goto overflow;
34 j += incr;
Gregory P. Smith60d241f2007-10-16 06:31:30 +000035 }
36 }
Antoine Pitrou8d4e5052009-01-13 22:59:11 +000037 else {
Benjamin Peterson23cf4032014-03-30 19:47:57 -040038 if (j > PY_SSIZE_T_MAX - 1)
39 goto overflow;
Antoine Pitrou8d4e5052009-01-13 22:59:11 +000040 j++;
41 if (*p == '\n' || *p == '\r') {
Benjamin Peterson23cf4032014-03-30 19:47:57 -040042 if (i > PY_SSIZE_T_MAX - j)
43 goto overflow;
Antoine Pitrou8d4e5052009-01-13 22:59:11 +000044 i += j;
45 j = 0;
Antoine Pitrou8d4e5052009-01-13 22:59:11 +000046 }
47 }
Gregory P. Smith60d241f2007-10-16 06:31:30 +000048 }
Ezio Melotti6b027722013-04-21 04:07:51 +030049
Benjamin Peterson23cf4032014-03-30 19:47:57 -040050 if (i > PY_SSIZE_T_MAX - j)
51 goto overflow;
Benjamin Peterson0ad60982014-03-30 19:52:22 -040052
Gregory P. Smith60d241f2007-10-16 06:31:30 +000053 /* Second pass: create output string and fill it */
54 u = STRINGLIB_NEW(NULL, i + j);
55 if (!u)
56 return NULL;
Ezio Melotti6b027722013-04-21 04:07:51 +030057
Gregory P. Smith60d241f2007-10-16 06:31:30 +000058 j = 0;
59 q = STRINGLIB_STR(u);
Antoine Pitrou8d4e5052009-01-13 22:59:11 +000060
Benjamin Peterson23cf4032014-03-30 19:47:57 -040061 for (p = STRINGLIB_STR(self); p < e; p++) {
Gregory P. Smith60d241f2007-10-16 06:31:30 +000062 if (*p == '\t') {
Antoine Pitrou8d4e5052009-01-13 22:59:11 +000063 if (tabsize > 0) {
64 i = tabsize - (j % tabsize);
65 j += i;
66 while (i--)
67 *q++ = ' ';
68 }
69 }
70 else {
Gregory P. Smith60d241f2007-10-16 06:31:30 +000071 j++;
Antoine Pitrou8d4e5052009-01-13 22:59:11 +000072 *q++ = *p;
Gregory P. Smith60d241f2007-10-16 06:31:30 +000073 if (*p == '\n' || *p == '\r')
74 j = 0;
75 }
Benjamin Peterson23cf4032014-03-30 19:47:57 -040076 }
Ezio Melotti6b027722013-04-21 04:07:51 +030077
Gregory P. Smith60d241f2007-10-16 06:31:30 +000078 return u;
Benjamin Peterson23cf4032014-03-30 19:47:57 -040079 overflow:
80 PyErr_SetString(PyExc_OverflowError, "result too long");
81 return NULL;
Gregory P. Smith60d241f2007-10-16 06:31:30 +000082}
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__,
Guido van Rossum98297ee2007-11-06 21:34:58 +0000122"B.ljust(width[, fillchar]) -> copy of B\n"
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000123"\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__,
Guido van Rossum98297ee2007-11-06 21:34:58 +0000152"B.rjust(width[, fillchar]) -> copy of B\n"
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000153"\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__,
Guido van Rossum98297ee2007-11-06 21:34:58 +0000182"B.center(width[, fillchar]) -> copy of B\n"
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000183"\n"
Guido van Rossum98297ee2007-11-06 21:34:58 +0000184"Return B centered in a string of length width. Padding is\n"
185"done using the specified fill character (default is a space).");
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000186
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__,
Guido van Rossum98297ee2007-11-06 21:34:58 +0000215"B.zfill(width) -> copy of B\n"
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000216"\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}