blob: dd00976eacaa49c08d198cf73bc083b8898ad90c [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__,
Ezio Melotti745d54d2013-11-16 19:10:57 +02008"B.expandtabs(tabsize=8) -> 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*
Ezio Melotti745d54d2013-11-16 19:10:57 +020014stringlib_expandtabs(PyObject *self, PyObject *args, PyObject *kwds)
Gregory P. Smith60d241f2007-10-16 06:31:30 +000015{
16 const char *e, *p;
17 char *q;
Antoine Pitrou8d4e5052009-01-13 22:59:11 +000018 size_t i, j;
Gregory P. Smith60d241f2007-10-16 06:31:30 +000019 PyObject *u;
Ezio Melotti745d54d2013-11-16 19:10:57 +020020 static char *kwlist[] = {"tabsize", 0};
Gregory P. Smith60d241f2007-10-16 06:31:30 +000021 int tabsize = 8;
Ezio Melotti6b027722013-04-21 04:07:51 +030022
Ezio Melotti745d54d2013-11-16 19:10:57 +020023 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:expandtabs",
24 kwlist, &tabsize))
Antoine Pitrou8d4e5052009-01-13 22:59:11 +000025 return NULL;
Ezio Melotti6b027722013-04-21 04:07:51 +030026
Gregory P. Smith60d241f2007-10-16 06:31:30 +000027 /* First pass: determine size of output string */
Antoine Pitrou8d4e5052009-01-13 22:59:11 +000028 i = j = 0;
Gregory P. Smith60d241f2007-10-16 06:31:30 +000029 e = STRINGLIB_STR(self) + STRINGLIB_LEN(self);
30 for (p = STRINGLIB_STR(self); p < e; p++)
31 if (*p == '\t') {
Antoine Pitrou8d4e5052009-01-13 22:59:11 +000032 if (tabsize > 0) {
33 j += tabsize - (j % tabsize);
34 if (j > PY_SSIZE_T_MAX) {
Gregory P. Smith60d241f2007-10-16 06:31:30 +000035 PyErr_SetString(PyExc_OverflowError,
36 "result is too long");
37 return NULL;
38 }
39 }
40 }
Antoine Pitrou8d4e5052009-01-13 22:59:11 +000041 else {
42 j++;
43 if (*p == '\n' || *p == '\r') {
44 i += j;
45 j = 0;
46 if (i > PY_SSIZE_T_MAX) {
47 PyErr_SetString(PyExc_OverflowError,
48 "result is too long");
49 return NULL;
50 }
51 }
52 }
Ezio Melotti6b027722013-04-21 04:07:51 +030053
Antoine Pitrou8d4e5052009-01-13 22:59:11 +000054 if ((i + j) > PY_SSIZE_T_MAX) {
Gregory P. Smith60d241f2007-10-16 06:31:30 +000055 PyErr_SetString(PyExc_OverflowError, "result is too long");
56 return NULL;
57 }
Ezio Melotti6b027722013-04-21 04:07:51 +030058
Gregory P. Smith60d241f2007-10-16 06:31:30 +000059 /* Second pass: create output string and fill it */
60 u = STRINGLIB_NEW(NULL, i + j);
61 if (!u)
62 return NULL;
Ezio Melotti6b027722013-04-21 04:07:51 +030063
Gregory P. Smith60d241f2007-10-16 06:31:30 +000064 j = 0;
65 q = STRINGLIB_STR(u);
Ezio Melotti6b027722013-04-21 04:07:51 +030066
Gregory P. Smith60d241f2007-10-16 06:31:30 +000067 for (p = STRINGLIB_STR(self); p < e; p++)
68 if (*p == '\t') {
Antoine Pitrou8d4e5052009-01-13 22:59:11 +000069 if (tabsize > 0) {
70 i = tabsize - (j % tabsize);
71 j += i;
72 while (i--)
73 *q++ = ' ';
74 }
75 }
76 else {
Gregory P. Smith60d241f2007-10-16 06:31:30 +000077 j++;
Antoine Pitrou8d4e5052009-01-13 22:59:11 +000078 *q++ = *p;
Gregory P. Smith60d241f2007-10-16 06:31:30 +000079 if (*p == '\n' || *p == '\r')
80 j = 0;
81 }
Ezio Melotti6b027722013-04-21 04:07:51 +030082
Gregory P. Smith60d241f2007-10-16 06:31:30 +000083 return u;
84}
85
86Py_LOCAL_INLINE(PyObject *)
87pad(PyObject *self, Py_ssize_t left, Py_ssize_t right, char fill)
88{
89 PyObject *u;
90
91 if (left < 0)
92 left = 0;
93 if (right < 0)
94 right = 0;
95
96 if (left == 0 && right == 0 && STRINGLIB_CHECK_EXACT(self)) {
97#if STRINGLIB_MUTABLE
98 /* We're defined as returning a copy; If the object is mutable
99 * that means we must make an identical copy. */
100 return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self));
101#else
102 Py_INCREF(self);
103 return (PyObject *)self;
104#endif /* STRINGLIB_MUTABLE */
105 }
106
107 u = STRINGLIB_NEW(NULL,
108 left + STRINGLIB_LEN(self) + right);
109 if (u) {
110 if (left)
111 memset(STRINGLIB_STR(u), fill, left);
112 Py_MEMCPY(STRINGLIB_STR(u) + left,
113 STRINGLIB_STR(self),
114 STRINGLIB_LEN(self));
115 if (right)
116 memset(STRINGLIB_STR(u) + left + STRINGLIB_LEN(self),
117 fill, right);
118 }
119
120 return u;
121}
122
123PyDoc_STRVAR(ljust__doc__,
Guido van Rossum98297ee2007-11-06 21:34:58 +0000124"B.ljust(width[, fillchar]) -> copy of B\n"
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000125"\n"
126"Return B left justified in a string of length width. Padding is\n"
127"done using the specified fill character (default is a space).");
128
129static PyObject *
130stringlib_ljust(PyObject *self, PyObject *args)
131{
132 Py_ssize_t width;
133 char fillchar = ' ';
134
135 if (!PyArg_ParseTuple(args, "n|c:ljust", &width, &fillchar))
136 return NULL;
137
138 if (STRINGLIB_LEN(self) >= width && STRINGLIB_CHECK_EXACT(self)) {
139#if STRINGLIB_MUTABLE
140 /* We're defined as returning a copy; If the object is mutable
141 * that means we must make an identical copy. */
142 return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self));
143#else
144 Py_INCREF(self);
145 return (PyObject*) self;
146#endif
147 }
148
149 return pad(self, 0, width - STRINGLIB_LEN(self), fillchar);
150}
151
152
153PyDoc_STRVAR(rjust__doc__,
Guido van Rossum98297ee2007-11-06 21:34:58 +0000154"B.rjust(width[, fillchar]) -> copy of B\n"
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000155"\n"
156"Return B right justified in a string of length width. Padding is\n"
157"done using the specified fill character (default is a space)");
158
159static PyObject *
160stringlib_rjust(PyObject *self, PyObject *args)
161{
162 Py_ssize_t width;
163 char fillchar = ' ';
164
165 if (!PyArg_ParseTuple(args, "n|c:rjust", &width, &fillchar))
166 return NULL;
167
168 if (STRINGLIB_LEN(self) >= width && STRINGLIB_CHECK_EXACT(self)) {
169#if STRINGLIB_MUTABLE
170 /* We're defined as returning a copy; If the object is mutable
171 * that means we must make an identical copy. */
172 return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self));
173#else
174 Py_INCREF(self);
175 return (PyObject*) self;
176#endif
177 }
178
179 return pad(self, width - STRINGLIB_LEN(self), 0, fillchar);
180}
181
182
183PyDoc_STRVAR(center__doc__,
Guido van Rossum98297ee2007-11-06 21:34:58 +0000184"B.center(width[, fillchar]) -> copy of B\n"
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000185"\n"
Guido van Rossum98297ee2007-11-06 21:34:58 +0000186"Return B centered in a string of length width. Padding is\n"
187"done using the specified fill character (default is a space).");
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000188
189static PyObject *
190stringlib_center(PyObject *self, PyObject *args)
191{
192 Py_ssize_t marg, left;
193 Py_ssize_t width;
194 char fillchar = ' ';
195
196 if (!PyArg_ParseTuple(args, "n|c:center", &width, &fillchar))
197 return NULL;
198
199 if (STRINGLIB_LEN(self) >= width && STRINGLIB_CHECK_EXACT(self)) {
200#if STRINGLIB_MUTABLE
201 /* We're defined as returning a copy; If the object is mutable
202 * that means we must make an identical copy. */
203 return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self));
204#else
205 Py_INCREF(self);
206 return (PyObject*) self;
207#endif
208 }
209
210 marg = width - STRINGLIB_LEN(self);
211 left = marg / 2 + (marg & width & 1);
212
213 return pad(self, left, marg - left, fillchar);
214}
215
216PyDoc_STRVAR(zfill__doc__,
Guido van Rossum98297ee2007-11-06 21:34:58 +0000217"B.zfill(width) -> copy of B\n"
Gregory P. Smith60d241f2007-10-16 06:31:30 +0000218"\n"
219"Pad a numeric string B with zeros on the left, to fill a field\n"
220"of the specified width. B is never truncated.");
221
222static PyObject *
223stringlib_zfill(PyObject *self, PyObject *args)
224{
225 Py_ssize_t fill;
226 PyObject *s;
227 char *p;
228 Py_ssize_t width;
229
230 if (!PyArg_ParseTuple(args, "n:zfill", &width))
231 return NULL;
232
233 if (STRINGLIB_LEN(self) >= width) {
234 if (STRINGLIB_CHECK_EXACT(self)) {
235#if STRINGLIB_MUTABLE
236 /* We're defined as returning a copy; If the object is mutable
237 * that means we must make an identical copy. */
238 return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self));
239#else
240 Py_INCREF(self);
241 return (PyObject*) self;
242#endif
243 }
244 else
245 return STRINGLIB_NEW(
246 STRINGLIB_STR(self),
247 STRINGLIB_LEN(self)
248 );
249 }
250
251 fill = width - STRINGLIB_LEN(self);
252
253 s = pad(self, fill, 0, '0');
254
255 if (s == NULL)
256 return NULL;
257
258 p = STRINGLIB_STR(s);
259 if (p[fill] == '+' || p[fill] == '-') {
260 /* move sign to beginning of string */
261 p[0] = p[fill];
262 p[fill] = '0';
263 }
264
265 return (PyObject*) s;
266}