Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
dd40fc3e
Commit
dd40fc3e
authored
May 04, 2016
by
Serhiy Storchaka
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #26765: Moved common code and docstrings for bytes and bytearray methods
to bytes_methods.c.
parent
045e6351
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
519 additions
and
777 deletions
+519
-777
Include/bytes_methods.h
Include/bytes_methods.h
+21
-0
Objects/bytearrayobject.c
Objects/bytearrayobject.c
+24
-328
Objects/bytes_methods.c
Objects/bytes_methods.c
+424
-0
Objects/bytesobject.c
Objects/bytesobject.c
+26
-336
Objects/stringlib/find.h
Objects/stringlib/find.h
+0
-73
Objects/stringlib/transmogrify.h
Objects/stringlib/transmogrify.h
+0
-30
Objects/unicodeobject.c
Objects/unicodeobject.c
+24
-10
No files found.
Include/bytes_methods.h
View file @
dd40fc3e
...
...
@@ -21,6 +21,15 @@ extern void _Py_bytes_title(char *result, const char *s, Py_ssize_t len);
extern
void
_Py_bytes_capitalize
(
char
*
result
,
const
char
*
s
,
Py_ssize_t
len
);
extern
void
_Py_bytes_swapcase
(
char
*
result
,
const
char
*
s
,
Py_ssize_t
len
);
extern
PyObject
*
_Py_bytes_find
(
const
char
*
str
,
Py_ssize_t
len
,
PyObject
*
args
);
extern
PyObject
*
_Py_bytes_index
(
const
char
*
str
,
Py_ssize_t
len
,
PyObject
*
args
);
extern
PyObject
*
_Py_bytes_rfind
(
const
char
*
str
,
Py_ssize_t
len
,
PyObject
*
args
);
extern
PyObject
*
_Py_bytes_rindex
(
const
char
*
str
,
Py_ssize_t
len
,
PyObject
*
args
);
extern
PyObject
*
_Py_bytes_count
(
const
char
*
str
,
Py_ssize_t
len
,
PyObject
*
args
);
extern
int
_Py_bytes_contains
(
const
char
*
str
,
Py_ssize_t
len
,
PyObject
*
arg
);
extern
PyObject
*
_Py_bytes_startswith
(
const
char
*
str
,
Py_ssize_t
len
,
PyObject
*
args
);
extern
PyObject
*
_Py_bytes_endswith
(
const
char
*
str
,
Py_ssize_t
len
,
PyObject
*
args
);
/* The maketrans() static method. */
extern
PyObject
*
_Py_bytes_maketrans
(
Py_buffer
*
frm
,
Py_buffer
*
to
);
...
...
@@ -37,7 +46,19 @@ extern const char _Py_upper__doc__[];
extern
const
char
_Py_title__doc__
[];
extern
const
char
_Py_capitalize__doc__
[];
extern
const
char
_Py_swapcase__doc__
[];
extern
const
char
_Py_count__doc__
[];
extern
const
char
_Py_find__doc__
[];
extern
const
char
_Py_index__doc__
[];
extern
const
char
_Py_rfind__doc__
[];
extern
const
char
_Py_rindex__doc__
[];
extern
const
char
_Py_startswith__doc__
[];
extern
const
char
_Py_endswith__doc__
[];
extern
const
char
_Py_maketrans__doc__
[];
extern
const
char
_Py_expandtabs__doc__
[];
extern
const
char
_Py_ljust__doc__
[];
extern
const
char
_Py_rjust__doc__
[];
extern
const
char
_Py_center__doc__
[];
extern
const
char
_Py_zfill__doc__
[];
/* this is needed because some docs are shared from the .o, not static */
#define PyDoc_STRVAR_shared(name,str) const char name[] = PyDoc_STR(str)
...
...
Objects/bytearrayobject.c
View file @
dd40fc3e
...
...
@@ -1097,147 +1097,16 @@ bytearray_dealloc(PyByteArrayObject *self)
#include "stringlib/transmogrify.h"
/* The following Py_LOCAL_INLINE and Py_LOCAL functions
were copied from the old char* style string object. */
/* helper macro to fixup start/end slice values */
#define ADJUST_INDICES(start, end, len) \
if (end > len) \
end = len; \
else if (end < 0) { \
end += len; \
if (end < 0) \
end = 0; \
} \
if (start < 0) { \
start += len; \
if (start < 0) \
start = 0; \
}
Py_LOCAL_INLINE
(
Py_ssize_t
)
bytearray_find_internal
(
PyByteArrayObject
*
self
,
PyObject
*
args
,
int
dir
)
{
PyObject
*
subobj
;
char
byte
;
Py_buffer
subbuf
;
const
char
*
sub
;
Py_ssize_t
len
,
sub_len
;
Py_ssize_t
start
=
0
,
end
=
PY_SSIZE_T_MAX
;
Py_ssize_t
res
;
if
(
!
stringlib_parse_args_finds_byte
(
"find/rfind/index/rindex"
,
args
,
&
subobj
,
&
byte
,
&
start
,
&
end
))
return
-
2
;
if
(
subobj
)
{
if
(
PyObject_GetBuffer
(
subobj
,
&
subbuf
,
PyBUF_SIMPLE
)
!=
0
)
return
-
2
;
sub
=
subbuf
.
buf
;
sub_len
=
subbuf
.
len
;
}
else
{
sub
=
&
byte
;
sub_len
=
1
;
}
len
=
PyByteArray_GET_SIZE
(
self
);
ADJUST_INDICES
(
start
,
end
,
len
);
if
(
end
-
start
<
sub_len
)
res
=
-
1
;
else
if
(
sub_len
==
1
)
{
if
(
dir
>
0
)
res
=
stringlib_find_char
(
PyByteArray_AS_STRING
(
self
)
+
start
,
end
-
start
,
*
sub
);
else
res
=
stringlib_rfind_char
(
PyByteArray_AS_STRING
(
self
)
+
start
,
end
-
start
,
*
sub
);
if
(
res
>=
0
)
res
+=
start
;
}
else
{
if
(
dir
>
0
)
res
=
stringlib_find_slice
(
PyByteArray_AS_STRING
(
self
),
len
,
sub
,
sub_len
,
start
,
end
);
else
res
=
stringlib_rfind_slice
(
PyByteArray_AS_STRING
(
self
),
len
,
sub
,
sub_len
,
start
,
end
);
}
if
(
subobj
)
PyBuffer_Release
(
&
subbuf
);
return
res
;
}
PyDoc_STRVAR
(
find__doc__
,
"B.find(sub[, start[, end]]) -> int
\n
\
\n
\
Return the lowest index in B where subsection sub is found,
\n
\
such that sub is contained within B[start,end]. Optional
\n
\
arguments start and end are interpreted as in slice notation.
\n
\
\n
\
Return -1 on failure."
);
static
PyObject
*
bytearray_find
(
PyByteArrayObject
*
self
,
PyObject
*
args
)
{
Py_ssize_t
result
=
bytearray_find_internal
(
self
,
args
,
+
1
);
if
(
result
==
-
2
)
return
NULL
;
return
PyLong_FromSsize_t
(
result
);
return
_Py_bytes_find
(
PyByteArray_AS_STRING
(
self
),
PyByteArray_GET_SIZE
(
self
),
args
);
}
PyDoc_STRVAR
(
count__doc__
,
"B.count(sub[, start[, end]]) -> int
\n
\
\n
\
Return the number of non-overlapping occurrences of subsection sub in
\n
\
bytes B[start:end]. Optional arguments start and end are interpreted
\n
\
as in slice notation."
);
static
PyObject
*
bytearray_count
(
PyByteArrayObject
*
self
,
PyObject
*
args
)
{
PyObject
*
sub_obj
;
const
char
*
str
=
PyByteArray_AS_STRING
(
self
),
*
sub
;
Py_ssize_t
sub_len
;
char
byte
;
Py_ssize_t
start
=
0
,
end
=
PY_SSIZE_T_MAX
;
Py_buffer
vsub
;
PyObject
*
count_obj
;
if
(
!
stringlib_parse_args_finds_byte
(
"count"
,
args
,
&
sub_obj
,
&
byte
,
&
start
,
&
end
))
return
NULL
;
if
(
sub_obj
)
{
if
(
PyObject_GetBuffer
(
sub_obj
,
&
vsub
,
PyBUF_SIMPLE
)
!=
0
)
return
NULL
;
sub
=
vsub
.
buf
;
sub_len
=
vsub
.
len
;
}
else
{
sub
=
&
byte
;
sub_len
=
1
;
}
ADJUST_INDICES
(
start
,
end
,
PyByteArray_GET_SIZE
(
self
));
count_obj
=
PyLong_FromSsize_t
(
stringlib_count
(
str
+
start
,
end
-
start
,
sub
,
sub_len
,
PY_SSIZE_T_MAX
)
);
if
(
sub_obj
)
PyBuffer_Release
(
&
vsub
);
return
count_obj
;
return
_Py_bytes_count
(
PyByteArray_AS_STRING
(
self
),
PyByteArray_GET_SIZE
(
self
),
args
);
}
/*[clinic input]
...
...
@@ -1269,216 +1138,40 @@ bytearray_copy_impl(PyByteArrayObject *self)
PyByteArray_GET_SIZE
(
self
));
}
PyDoc_STRVAR
(
index__doc__
,
"B.index(sub[, start[, end]]) -> int
\n
\
\n
\
Like B.find() but raise ValueError when the subsection is not found."
);
static
PyObject
*
bytearray_index
(
PyByteArrayObject
*
self
,
PyObject
*
args
)
{
Py_ssize_t
result
=
bytearray_find_internal
(
self
,
args
,
+
1
);
if
(
result
==
-
2
)
return
NULL
;
if
(
result
==
-
1
)
{
PyErr_SetString
(
PyExc_ValueError
,
"subsection not found"
);
return
NULL
;
}
return
PyLong_FromSsize_t
(
result
);
return
_Py_bytes_index
(
PyByteArray_AS_STRING
(
self
),
PyByteArray_GET_SIZE
(
self
),
args
);
}
PyDoc_STRVAR
(
rfind__doc__
,
"B.rfind(sub[, start[, end]]) -> int
\n
\
\n
\
Return the highest index in B where subsection sub is found,
\n
\
such that sub is contained within B[start,end]. Optional
\n
\
arguments start and end are interpreted as in slice notation.
\n
\
\n
\
Return -1 on failure."
);
static
PyObject
*
bytearray_rfind
(
PyByteArrayObject
*
self
,
PyObject
*
args
)
{
Py_ssize_t
result
=
bytearray_find_internal
(
self
,
args
,
-
1
);
if
(
result
==
-
2
)
return
NULL
;
return
PyLong_FromSsize_t
(
result
);
return
_Py_bytes_rfind
(
PyByteArray_AS_STRING
(
self
),
PyByteArray_GET_SIZE
(
self
),
args
);
}
PyDoc_STRVAR
(
rindex__doc__
,
"B.rindex(sub[, start[, end]]) -> int
\n
\
\n
\
Like B.rfind() but raise ValueError when the subsection is not found."
);
static
PyObject
*
bytearray_rindex
(
PyByteArrayObject
*
self
,
PyObject
*
args
)
{
Py_ssize_t
result
=
bytearray_find_internal
(
self
,
args
,
-
1
);
if
(
result
==
-
2
)
return
NULL
;
if
(
result
==
-
1
)
{
PyErr_SetString
(
PyExc_ValueError
,
"subsection not found"
);
return
NULL
;
}
return
PyLong_FromSsize_t
(
result
);
return
_Py_bytes_rindex
(
PyByteArray_AS_STRING
(
self
),
PyByteArray_GET_SIZE
(
self
),
args
);
}
static
int
bytearray_contains
(
PyObject
*
self
,
PyObject
*
arg
)
{
Py_ssize_t
ival
=
PyNumber_AsSsize_t
(
arg
,
PyExc_ValueError
);
if
(
ival
==
-
1
&&
PyErr_Occurred
())
{
Py_buffer
varg
;
Py_ssize_t
pos
;
PyErr_Clear
();
if
(
PyObject_GetBuffer
(
arg
,
&
varg
,
PyBUF_SIMPLE
)
!=
0
)
return
-
1
;
pos
=
stringlib_find
(
PyByteArray_AS_STRING
(
self
),
Py_SIZE
(
self
),
varg
.
buf
,
varg
.
len
,
0
);
PyBuffer_Release
(
&
varg
);
return
pos
>=
0
;
}
if
(
ival
<
0
||
ival
>=
256
)
{
PyErr_SetString
(
PyExc_ValueError
,
"byte must be in range(0, 256)"
);
return
-
1
;
}
return
memchr
(
PyByteArray_AS_STRING
(
self
),
(
int
)
ival
,
Py_SIZE
(
self
))
!=
NULL
;
return
_Py_bytes_contains
(
PyByteArray_AS_STRING
(
self
),
PyByteArray_GET_SIZE
(
self
),
arg
);
}
/* Matches the end (direction >= 0) or start (direction < 0) of self
* against substr, using the start and end arguments. Returns
* -1 on error, 0 if not found and 1 if found.
*/
Py_LOCAL
(
int
)
_bytearray_tailmatch
(
PyByteArrayObject
*
self
,
PyObject
*
substr
,
Py_ssize_t
start
,
Py_ssize_t
end
,
int
direction
)
{
Py_ssize_t
len
=
PyByteArray_GET_SIZE
(
self
);
const
char
*
str
;
Py_buffer
vsubstr
;
int
rv
=
0
;
str
=
PyByteArray_AS_STRING
(
self
);
if
(
PyObject_GetBuffer
(
substr
,
&
vsubstr
,
PyBUF_SIMPLE
)
!=
0
)
return
-
1
;
ADJUST_INDICES
(
start
,
end
,
len
);
if
(
direction
<
0
)
{
/* startswith */
if
(
start
+
vsubstr
.
len
>
len
)
{
goto
done
;
}
}
else
{
/* endswith */
if
(
end
-
start
<
vsubstr
.
len
||
start
>
len
)
{
goto
done
;
}
if
(
end
-
vsubstr
.
len
>
start
)
start
=
end
-
vsubstr
.
len
;
}
if
(
end
-
start
>=
vsubstr
.
len
)
rv
=
!
memcmp
(
str
+
start
,
vsubstr
.
buf
,
vsubstr
.
len
);
done:
PyBuffer_Release
(
&
vsubstr
);
return
rv
;
}
PyDoc_STRVAR
(
startswith__doc__
,
"B.startswith(prefix[, start[, end]]) -> bool
\n
\
\n
\
Return True if B starts with the specified prefix, False otherwise.
\n
\
With optional start, test B beginning at that position.
\n
\
With optional end, stop comparing B at that position.
\n
\
prefix can also be a tuple of bytes to try."
);
static
PyObject
*
bytearray_startswith
(
PyByteArrayObject
*
self
,
PyObject
*
args
)
{
Py_ssize_t
start
=
0
;
Py_ssize_t
end
=
PY_SSIZE_T_MAX
;
PyObject
*
subobj
;
int
result
;
if
(
!
stringlib_parse_args_finds
(
"startswith"
,
args
,
&
subobj
,
&
start
,
&
end
))
return
NULL
;
if
(
PyTuple_Check
(
subobj
))
{
Py_ssize_t
i
;
for
(
i
=
0
;
i
<
PyTuple_GET_SIZE
(
subobj
);
i
++
)
{
result
=
_bytearray_tailmatch
(
self
,
PyTuple_GET_ITEM
(
subobj
,
i
),
start
,
end
,
-
1
);
if
(
result
==
-
1
)
return
NULL
;
else
if
(
result
)
{
Py_RETURN_TRUE
;
}
}
Py_RETURN_FALSE
;
}
result
=
_bytearray_tailmatch
(
self
,
subobj
,
start
,
end
,
-
1
);
if
(
result
==
-
1
)
{
if
(
PyErr_ExceptionMatches
(
PyExc_TypeError
))
PyErr_Format
(
PyExc_TypeError
,
"startswith first arg must be bytes "
"or a tuple of bytes, not %s"
,
Py_TYPE
(
subobj
)
->
tp_name
);
return
NULL
;
}
else
return
PyBool_FromLong
(
result
);
return
_Py_bytes_startswith
(
PyByteArray_AS_STRING
(
self
),
PyByteArray_GET_SIZE
(
self
),
args
);
}
PyDoc_STRVAR
(
endswith__doc__
,
"B.endswith(suffix[, start[, end]]) -> bool
\n
\
\n
\
Return True if B ends with the specified suffix, False otherwise.
\n
\
With optional start, test B beginning at that position.
\n
\
With optional end, stop comparing B at that position.
\n
\
suffix can also be a tuple of bytes to try."
);
static
PyObject
*
bytearray_endswith
(
PyByteArrayObject
*
self
,
PyObject
*
args
)
{
Py_ssize_t
start
=
0
;
Py_ssize_t
end
=
PY_SSIZE_T_MAX
;
PyObject
*
subobj
;
int
result
;
if
(
!
stringlib_parse_args_finds
(
"endswith"
,
args
,
&
subobj
,
&
start
,
&
end
))
return
NULL
;
if
(
PyTuple_Check
(
subobj
))
{
Py_ssize_t
i
;
for
(
i
=
0
;
i
<
PyTuple_GET_SIZE
(
subobj
);
i
++
)
{
result
=
_bytearray_tailmatch
(
self
,
PyTuple_GET_ITEM
(
subobj
,
i
),
start
,
end
,
+
1
);
if
(
result
==
-
1
)
return
NULL
;
else
if
(
result
)
{
Py_RETURN_TRUE
;
}
}
Py_RETURN_FALSE
;
}
result
=
_bytearray_tailmatch
(
self
,
subobj
,
start
,
end
,
+
1
);
if
(
result
==
-
1
)
{
if
(
PyErr_ExceptionMatches
(
PyExc_TypeError
))
PyErr_Format
(
PyExc_TypeError
,
"endswith first arg must be bytes or "
"a tuple of bytes, not %s"
,
Py_TYPE
(
subobj
)
->
tp_name
);
return
NULL
;
}
else
return
PyBool_FromLong
(
result
);
return
_Py_bytes_endswith
(
PyByteArray_AS_STRING
(
self
),
PyByteArray_GET_SIZE
(
self
),
args
);
}
...
...
@@ -1544,7 +1237,7 @@ bytearray_translate_impl(PyByteArrayObject *self, PyObject *table,
result
=
PyByteArray_FromStringAndSize
((
char
*
)
NULL
,
inlen
);
if
(
result
==
NULL
)
goto
done
;
output_start
=
output
=
PyByteArray_A
sString
(
result
);
output_start
=
output
=
PyByteArray_A
S_STRING
(
result
);
input
=
PyByteArray_AS_STRING
(
input_obj
);
if
(
vdel
.
len
==
0
&&
table_chars
!=
NULL
)
{
...
...
@@ -2919,19 +2612,22 @@ bytearray_methods[] = {
BYTEARRAY_APPEND_METHODDEF
{
"capitalize"
,
(
PyCFunction
)
stringlib_capitalize
,
METH_NOARGS
,
_Py_capitalize__doc__
},
{
"center"
,
(
PyCFunction
)
stringlib_center
,
METH_VARARGS
,
center__doc__
},
{
"center"
,
(
PyCFunction
)
stringlib_center
,
METH_VARARGS
,
_Py_
center__doc__
},
BYTEARRAY_CLEAR_METHODDEF
BYTEARRAY_COPY_METHODDEF
{
"count"
,
(
PyCFunction
)
bytearray_count
,
METH_VARARGS
,
count__doc__
},
{
"count"
,
(
PyCFunction
)
bytearray_count
,
METH_VARARGS
,
_Py_count__doc__
},
BYTEARRAY_DECODE_METHODDEF
{
"endswith"
,
(
PyCFunction
)
bytearray_endswith
,
METH_VARARGS
,
endswith__doc__
},
{
"endswith"
,
(
PyCFunction
)
bytearray_endswith
,
METH_VARARGS
,
_Py_endswith__doc__
},
{
"expandtabs"
,
(
PyCFunction
)
stringlib_expandtabs
,
METH_VARARGS
|
METH_KEYWORDS
,
expandtabs__doc__
},
_Py_
expandtabs__doc__
},
BYTEARRAY_EXTEND_METHODDEF
{
"find"
,
(
PyCFunction
)
bytearray_find
,
METH_VARARGS
,
find__doc__
},
{
"find"
,
(
PyCFunction
)
bytearray_find
,
METH_VARARGS
,
_Py_find__doc__
},
BYTEARRAY_FROMHEX_METHODDEF
{
"hex"
,
(
PyCFunction
)
bytearray_hex
,
METH_NOARGS
,
hex__doc__
},
{
"index"
,
(
PyCFunction
)
bytearray_index
,
METH_VARARGS
,
index__doc__
},
{
"index"
,
(
PyCFunction
)
bytearray_index
,
METH_VARARGS
,
_Py_
index__doc__
},
BYTEARRAY_INSERT_METHODDEF
{
"isalnum"
,
(
PyCFunction
)
stringlib_isalnum
,
METH_NOARGS
,
_Py_isalnum__doc__
},
...
...
@@ -2948,7 +2644,7 @@ bytearray_methods[] = {
{
"isupper"
,
(
PyCFunction
)
stringlib_isupper
,
METH_NOARGS
,
_Py_isupper__doc__
},
BYTEARRAY_JOIN_METHODDEF
{
"ljust"
,
(
PyCFunction
)
stringlib_ljust
,
METH_VARARGS
,
ljust__doc__
},
{
"ljust"
,
(
PyCFunction
)
stringlib_ljust
,
METH_VARARGS
,
_Py_
ljust__doc__
},
{
"lower"
,
(
PyCFunction
)
stringlib_lower
,
METH_NOARGS
,
_Py_lower__doc__
},
BYTEARRAY_LSTRIP_METHODDEF
BYTEARRAY_MAKETRANS_METHODDEF
...
...
@@ -2957,23 +2653,23 @@ bytearray_methods[] = {
BYTEARRAY_REMOVE_METHODDEF
BYTEARRAY_REPLACE_METHODDEF
BYTEARRAY_REVERSE_METHODDEF
{
"rfind"
,
(
PyCFunction
)
bytearray_rfind
,
METH_VARARGS
,
rfind__doc__
},
{
"rindex"
,
(
PyCFunction
)
bytearray_rindex
,
METH_VARARGS
,
rindex__doc__
},
{
"rjust"
,
(
PyCFunction
)
stringlib_rjust
,
METH_VARARGS
,
rjust__doc__
},
{
"rfind"
,
(
PyCFunction
)
bytearray_rfind
,
METH_VARARGS
,
_Py_
rfind__doc__
},
{
"rindex"
,
(
PyCFunction
)
bytearray_rindex
,
METH_VARARGS
,
_Py_
rindex__doc__
},
{
"rjust"
,
(
PyCFunction
)
stringlib_rjust
,
METH_VARARGS
,
_Py_
rjust__doc__
},
BYTEARRAY_RPARTITION_METHODDEF
BYTEARRAY_RSPLIT_METHODDEF
BYTEARRAY_RSTRIP_METHODDEF
BYTEARRAY_SPLIT_METHODDEF
BYTEARRAY_SPLITLINES_METHODDEF
{
"startswith"
,
(
PyCFunction
)
bytearray_startswith
,
METH_VARARGS
,
startswith__doc__
},
_Py_
startswith__doc__
},
BYTEARRAY_STRIP_METHODDEF
{
"swapcase"
,
(
PyCFunction
)
stringlib_swapcase
,
METH_NOARGS
,
_Py_swapcase__doc__
},
{
"title"
,
(
PyCFunction
)
stringlib_title
,
METH_NOARGS
,
_Py_title__doc__
},
BYTEARRAY_TRANSLATE_METHODDEF
{
"upper"
,
(
PyCFunction
)
stringlib_upper
,
METH_NOARGS
,
_Py_upper__doc__
},
{
"zfill"
,
(
PyCFunction
)
stringlib_zfill
,
METH_VARARGS
,
zfill__doc__
},
{
"zfill"
,
(
PyCFunction
)
stringlib_zfill
,
METH_VARARGS
,
_Py_
zfill__doc__
},
{
NULL
}
};
...
...
Objects/bytes_methods.c
View file @
dd40fc3e
...
...
@@ -387,3 +387,427 @@ _Py_bytes_maketrans(Py_buffer *frm, Py_buffer *to)
return
res
;
}
#define FASTSEARCH fastsearch
#define STRINGLIB(F) stringlib_##F
#define STRINGLIB_CHAR char
#define STRINGLIB_SIZEOF_CHAR 1
#include "stringlib/fastsearch.h"
#include "stringlib/count.h"
#include "stringlib/find.h"
/*
Wraps stringlib_parse_args_finds() and additionally checks whether the
first argument is an integer in range(0, 256).
If this is the case, writes the integer value to the byte parameter
and sets subobj to NULL. Otherwise, sets the first argument to subobj
and doesn't touch byte. The other parameters are similar to those of
stringlib_parse_args_finds().
*/
Py_LOCAL_INLINE
(
int
)
parse_args_finds_byte
(
const
char
*
function_name
,
PyObject
*
args
,
PyObject
**
subobj
,
char
*
byte
,
Py_ssize_t
*
start
,
Py_ssize_t
*
end
)
{
PyObject
*
tmp_subobj
;
Py_ssize_t
ival
;
PyObject
*
err
;
if
(
!
stringlib_parse_args_finds
(
function_name
,
args
,
&
tmp_subobj
,
start
,
end
))
return
0
;
if
(
!
PyNumber_Check
(
tmp_subobj
))
{
*
subobj
=
tmp_subobj
;
return
1
;
}
ival
=
PyNumber_AsSsize_t
(
tmp_subobj
,
PyExc_OverflowError
);
if
(
ival
==
-
1
)
{
err
=
PyErr_Occurred
();
if
(
err
&&
!
PyErr_GivenExceptionMatches
(
err
,
PyExc_OverflowError
))
{
PyErr_Clear
();
*
subobj
=
tmp_subobj
;
return
1
;
}
}
if
(
ival
<
0
||
ival
>
255
)
{
PyErr_SetString
(
PyExc_ValueError
,
"byte must be in range(0, 256)"
);
return
0
;
}
*
subobj
=
NULL
;
*
byte
=
(
char
)
ival
;
return
1
;
}
/* helper macro to fixup start/end slice values */
#define ADJUST_INDICES(start, end, len) \
if (end > len) \
end = len; \
else if (end < 0) { \
end += len; \
if (end < 0) \
end = 0; \
} \
if (start < 0) { \
start += len; \
if (start < 0) \
start = 0; \
}
Py_LOCAL_INLINE
(
Py_ssize_t
)
find_internal
(
const
char
*
str
,
Py_ssize_t
len
,
const
char
*
function_name
,
PyObject
*
args
,
int
dir
)
{
PyObject
*
subobj
;
char
byte
;
Py_buffer
subbuf
;
const
char
*
sub
;
Py_ssize_t
sub_len
;
Py_ssize_t
start
=
0
,
end
=
PY_SSIZE_T_MAX
;
Py_ssize_t
res
;
if
(
!
parse_args_finds_byte
(
function_name
,
args
,
&
subobj
,
&
byte
,
&
start
,
&
end
))
return
-
2
;
if
(
subobj
)
{
if
(
PyObject_GetBuffer
(
subobj
,
&
subbuf
,
PyBUF_SIMPLE
)
!=
0
)
return
-
2
;
sub
=
subbuf
.
buf
;
sub_len
=
subbuf
.
len
;
}
else
{
sub
=
&
byte
;
sub_len
=
1
;
}
ADJUST_INDICES
(
start
,
end
,
len
);
if
(
end
-
start
<
sub_len
)
res
=
-
1
;
else
if
(
sub_len
==
1
)
{
if
(
dir
>
0
)
res
=
stringlib_find_char
(
str
+
start
,
end
-
start
,
*
sub
);
else
res
=
stringlib_rfind_char
(
str
+
start
,
end
-
start
,
*
sub
);
if
(
res
>=
0
)
res
+=
start
;
}
else
{
if
(
dir
>
0
)
res
=
stringlib_find_slice
(
str
,
len
,
sub
,
sub_len
,
start
,
end
);
else
res
=
stringlib_rfind_slice
(
str
,
len
,
sub
,
sub_len
,
start
,
end
);
}
if
(
subobj
)
PyBuffer_Release
(
&
subbuf
);
return
res
;
}
PyDoc_STRVAR_shared
(
_Py_find__doc__
,
"B.find(sub[, start[, end]]) -> int
\n
\
\n
\
Return the lowest index in B where subsection sub is found,
\n
\
such that sub is contained within B[start,end]. Optional
\n
\
arguments start and end are interpreted as in slice notation.
\n
\
\n
\
Return -1 on failure."
);
PyObject
*
_Py_bytes_find
(
const
char
*
str
,
Py_ssize_t
len
,
PyObject
*
args
)
{
Py_ssize_t
result
=
find_internal
(
str
,
len
,
"find"
,
args
,
+
1
);
if
(
result
==
-
2
)
return
NULL
;
return
PyLong_FromSsize_t
(
result
);
}
PyDoc_STRVAR_shared
(
_Py_index__doc__
,
"B.index(sub[, start[, end]]) -> int
\n
\
\n
\
Like B.find() but raise ValueError when the subsection is not found."
);
PyObject
*
_Py_bytes_index
(
const
char
*
str
,
Py_ssize_t
len
,
PyObject
*
args
)
{
Py_ssize_t
result
=
find_internal
(
str
,
len
,
"index"
,
args
,
+
1
);
if
(
result
==
-
2
)
return
NULL
;
if
(
result
==
-
1
)
{
PyErr_SetString
(
PyExc_ValueError
,
"subsection not found"
);
return
NULL
;
}
return
PyLong_FromSsize_t
(
result
);
}
PyDoc_STRVAR_shared
(
_Py_rfind__doc__
,
"B.rfind(sub[, start[, end]]) -> int
\n
\
\n
\
Return the highest index in B where subsection sub is found,
\n
\
such that sub is contained within B[start,end]. Optional
\n
\
arguments start and end are interpreted as in slice notation.
\n
\
\n
\
Return -1 on failure."
);
PyObject
*
_Py_bytes_rfind
(
const
char
*
str
,
Py_ssize_t
len
,
PyObject
*
args
)
{
Py_ssize_t
result
=
find_internal
(
str
,
len
,
"rfind"
,
args
,
-
1
);
if
(
result
==
-
2
)
return
NULL
;
return
PyLong_FromSsize_t
(
result
);
}
PyDoc_STRVAR_shared
(
_Py_rindex__doc__
,
"B.rindex(sub[, start[, end]]) -> int
\n
\
\n
\
Like B.rfind() but raise ValueError when the subsection is not found."
);
PyObject
*
_Py_bytes_rindex
(
const
char
*
str
,
Py_ssize_t
len
,
PyObject
*
args
)
{
Py_ssize_t
result
=
find_internal
(
str
,
len
,
"rindex"
,
args
,
-
1
);
if
(
result
==
-
2
)
return
NULL
;
if
(
result
==
-
1
)
{
PyErr_SetString
(
PyExc_ValueError
,
"subsection not found"
);
return
NULL
;
}
return
PyLong_FromSsize_t
(
result
);
}
PyDoc_STRVAR_shared
(
_Py_count__doc__
,
"B.count(sub[, start[, end]]) -> int
\n
\
\n
\
Return the number of non-overlapping occurrences of subsection sub in
\n
\
bytes B[start:end]. Optional arguments start and end are interpreted
\n
\
as in slice notation."
);
PyObject
*
_Py_bytes_count
(
const
char
*
str
,
Py_ssize_t
len
,
PyObject
*
args
)
{
PyObject
*
sub_obj
;
const
char
*
sub
;
Py_ssize_t
sub_len
;
char
byte
;
Py_ssize_t
start
=
0
,
end
=
PY_SSIZE_T_MAX
;
Py_buffer
vsub
;
PyObject
*
count_obj
;
if
(
!
parse_args_finds_byte
(
"count"
,
args
,
&
sub_obj
,
&
byte
,
&
start
,
&
end
))
return
NULL
;
if
(
sub_obj
)
{
if
(
PyObject_GetBuffer
(
sub_obj
,
&
vsub
,
PyBUF_SIMPLE
)
!=
0
)
return
NULL
;
sub
=
vsub
.
buf
;
sub_len
=
vsub
.
len
;
}
else
{
sub
=
&
byte
;
sub_len
=
1
;
}
ADJUST_INDICES
(
start
,
end
,
len
);
count_obj
=
PyLong_FromSsize_t
(
stringlib_count
(
str
+
start
,
end
-
start
,
sub
,
sub_len
,
PY_SSIZE_T_MAX
)
);
if
(
sub_obj
)
PyBuffer_Release
(
&
vsub
);
return
count_obj
;
}
int
_Py_bytes_contains
(
const
char
*
str
,
Py_ssize_t
len
,
PyObject
*
arg
)
{
Py_ssize_t
ival
=
PyNumber_AsSsize_t
(
arg
,
PyExc_ValueError
);
if
(
ival
==
-
1
&&
PyErr_Occurred
())
{
Py_buffer
varg
;
Py_ssize_t
pos
;
PyErr_Clear
();
if
(
PyObject_GetBuffer
(
arg
,
&
varg
,
PyBUF_SIMPLE
)
!=
0
)
return
-
1
;
pos
=
stringlib_find
(
str
,
len
,
varg
.
buf
,
varg
.
len
,
0
);
PyBuffer_Release
(
&
varg
);
return
pos
>=
0
;
}
if
(
ival
<
0
||
ival
>=
256
)
{
PyErr_SetString
(
PyExc_ValueError
,
"byte must be in range(0, 256)"
);
return
-
1
;
}
return
memchr
(
str
,
(
int
)
ival
,
len
)
!=
NULL
;
}
/* Matches the end (direction >= 0) or start (direction < 0) of the buffer
* against substr, using the start and end arguments. Returns
* -1 on error, 0 if not found and 1 if found.
*/
Py_LOCAL
(
int
)
tailmatch
(
const
char
*
str
,
Py_ssize_t
len
,
PyObject
*
substr
,
Py_ssize_t
start
,
Py_ssize_t
end
,
int
direction
)
{
Py_buffer
sub_view
=
{
NULL
,
NULL
};
const
char
*
sub
;
Py_ssize_t
slen
;
if
(
PyBytes_Check
(
substr
))
{
sub
=
PyBytes_AS_STRING
(
substr
);
slen
=
PyBytes_GET_SIZE
(
substr
);
}
else
{
if
(
PyObject_GetBuffer
(
substr
,
&
sub_view
,
PyBUF_SIMPLE
)
!=
0
)
return
-
1
;
sub
=
sub_view
.
buf
;
slen
=
sub_view
.
len
;
}
ADJUST_INDICES
(
start
,
end
,
len
);
if
(
direction
<
0
)
{
/* startswith */
if
(
start
+
slen
>
len
)
goto
notfound
;
}
else
{
/* endswith */
if
(
end
-
start
<
slen
||
start
>
len
)
goto
notfound
;
if
(
end
-
slen
>
start
)
start
=
end
-
slen
;
}
if
(
end
-
start
<
slen
)
goto
notfound
;
if
(
memcmp
(
str
+
start
,
sub
,
slen
)
!=
0
)
goto
notfound
;
PyBuffer_Release
(
&
sub_view
);
return
1
;
notfound:
PyBuffer_Release
(
&
sub_view
);
return
0
;
}
Py_LOCAL
(
PyObject
*
)
_Py_bytes_tailmatch
(
const
char
*
str
,
Py_ssize_t
len
,
const
char
*
function_name
,
PyObject
*
args
,
int
direction
)
{
Py_ssize_t
start
=
0
;
Py_ssize_t
end
=
PY_SSIZE_T_MAX
;
PyObject
*
subobj
;
int
result
;
if
(
!
stringlib_parse_args_finds
(
function_name
,
args
,
&
subobj
,
&
start
,
&
end
))
return
NULL
;
if
(
PyTuple_Check
(
subobj
))
{
Py_ssize_t
i
;
for
(
i
=
0
;
i
<
PyTuple_GET_SIZE
(
subobj
);
i
++
)
{
result
=
tailmatch
(
str
,
len
,
PyTuple_GET_ITEM
(
subobj
,
i
),
start
,
end
,
direction
);
if
(
result
==
-
1
)
return
NULL
;
else
if
(
result
)
{
Py_RETURN_TRUE
;
}
}
Py_RETURN_FALSE
;
}
result
=
tailmatch
(
str
,
len
,
subobj
,
start
,
end
,
direction
);
if
(
result
==
-
1
)
{
if
(
PyErr_ExceptionMatches
(
PyExc_TypeError
))
PyErr_Format
(
PyExc_TypeError
,
"%s first arg must be bytes or a tuple of bytes, "
"not %s"
,
function_name
,
Py_TYPE
(
subobj
)
->
tp_name
);
return
NULL
;
}
else
return
PyBool_FromLong
(
result
);
}
PyDoc_STRVAR_shared
(
_Py_startswith__doc__
,
"B.startswith(prefix[, start[, end]]) -> bool
\n
\
\n
\
Return True if B starts with the specified prefix, False otherwise.
\n
\
With optional start, test B beginning at that position.
\n
\
With optional end, stop comparing B at that position.
\n
\
prefix can also be a tuple of bytes to try."
);
PyObject
*
_Py_bytes_startswith
(
const
char
*
str
,
Py_ssize_t
len
,
PyObject
*
args
)
{
return
_Py_bytes_tailmatch
(
str
,
len
,
"startswith"
,
args
,
-
1
);
}
PyDoc_STRVAR_shared
(
_Py_endswith__doc__
,
"B.endswith(suffix[, start[, end]]) -> bool
\n
\
\n
\
Return True if B ends with the specified suffix, False otherwise.
\n
\
With optional start, test B beginning at that position.
\n
\
With optional end, stop comparing B at that position.
\n
\
suffix can also be a tuple of bytes to try."
);
PyObject
*
_Py_bytes_endswith
(
const
char
*
str
,
Py_ssize_t
len
,
PyObject
*
args
)
{
return
_Py_bytes_tailmatch
(
str
,
len
,
"endswith"
,
args
,
+
1
);
}
PyDoc_STRVAR_shared
(
_Py_expandtabs__doc__
,
"B.expandtabs(tabsize=8) -> copy of B
\n
\
\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."
);
PyDoc_STRVAR_shared
(
_Py_ljust__doc__
,
"B.ljust(width[, fillchar]) -> copy of B
\n
"
"
\n
"
"Return B left justified in a string of length width. Padding is
\n
"
"done using the specified fill character (default is a space)."
);
PyDoc_STRVAR_shared
(
_Py_rjust__doc__
,
"B.rjust(width[, fillchar]) -> copy of B
\n
"
"
\n
"
"Return B right justified in a string of length width. Padding is
\n
"
"done using the specified fill character (default is a space)"
);
PyDoc_STRVAR_shared
(
_Py_center__doc__
,
"B.center(width[, fillchar]) -> copy of B
\n
"
"
\n
"
"Return B centered in a string of length width. Padding is
\n
"
"done using the specified fill character (default is a space)."
);
PyDoc_STRVAR_shared
(
_Py_zfill__doc__
,
"B.zfill(width) -> copy of B
\n
"
"
\n
"
"Pad a numeric string B with zeros on the left, to fill a field
\n
"
"of the specified width. B is never truncated."
);
Objects/bytesobject.c
View file @
dd40fc3e
...
...
@@ -486,11 +486,11 @@ formatlong(PyObject *v, int flags, int prec, int type)
static
int
byte_converter
(
PyObject
*
arg
,
char
*
p
)
{
if
(
PyBytes_Check
(
arg
)
&&
PyBytes_
Size
(
arg
)
==
1
)
{
if
(
PyBytes_Check
(
arg
)
&&
PyBytes_
GET_SIZE
(
arg
)
==
1
)
{
*
p
=
PyBytes_AS_STRING
(
arg
)[
0
];
return
1
;
}
else
if
(
PyByteArray_Check
(
arg
)
&&
PyByteArray_
Size
(
arg
)
==
1
)
{
else
if
(
PyByteArray_Check
(
arg
)
&&
PyByteArray_
GET_SIZE
(
arg
)
==
1
)
{
*
p
=
PyByteArray_AS_STRING
(
arg
)[
0
];
return
1
;
}
...
...
@@ -1488,24 +1488,7 @@ bytes_repeat(PyBytesObject *a, Py_ssize_t n)
static
int
bytes_contains
(
PyObject
*
self
,
PyObject
*
arg
)
{
Py_ssize_t
ival
=
PyNumber_AsSsize_t
(
arg
,
PyExc_ValueError
);
if
(
ival
==
-
1
&&
PyErr_Occurred
())
{
Py_buffer
varg
;
Py_ssize_t
pos
;
PyErr_Clear
();
if
(
PyObject_GetBuffer
(
arg
,
&
varg
,
PyBUF_SIMPLE
)
!=
0
)
return
-
1
;
pos
=
stringlib_find
(
PyBytes_AS_STRING
(
self
),
Py_SIZE
(
self
),
varg
.
buf
,
varg
.
len
,
0
);
PyBuffer_Release
(
&
varg
);
return
pos
>=
0
;
}
if
(
ival
<
0
||
ival
>=
256
)
{
PyErr_SetString
(
PyExc_ValueError
,
"byte must be in range(0, 256)"
);
return
-
1
;
}
return
memchr
(
PyBytes_AS_STRING
(
self
),
(
int
)
ival
,
Py_SIZE
(
self
))
!=
NULL
;
return
_Py_bytes_contains
(
PyBytes_AS_STRING
(
self
),
PyBytes_GET_SIZE
(
self
),
arg
);
}
static
PyObject
*
...
...
@@ -1890,157 +1873,30 @@ _PyBytes_Join(PyObject *sep, PyObject *x)
return
bytes_join
((
PyBytesObject
*
)
sep
,
x
);
}
/* helper macro to fixup start/end slice values */
#define ADJUST_INDICES(start, end, len) \
if (end > len) \
end = len; \
else if (end < 0) { \
end += len; \
if (end < 0) \
end = 0; \
} \
if (start < 0) { \
start += len; \
if (start < 0) \
start = 0; \
}
Py_LOCAL_INLINE
(
Py_ssize_t
)
bytes_find_internal
(
PyBytesObject
*
self
,
PyObject
*
args
,
int
dir
)
{
PyObject
*
subobj
;
char
byte
;
Py_buffer
subbuf
;
const
char
*
sub
;
Py_ssize_t
len
,
sub_len
;
Py_ssize_t
start
=
0
,
end
=
PY_SSIZE_T_MAX
;
Py_ssize_t
res
;
if
(
!
stringlib_parse_args_finds_byte
(
"find/rfind/index/rindex"
,
args
,
&
subobj
,
&
byte
,
&
start
,
&
end
))
return
-
2
;
if
(
subobj
)
{
if
(
PyObject_GetBuffer
(
subobj
,
&
subbuf
,
PyBUF_SIMPLE
)
!=
0
)
return
-
2
;
sub
=
subbuf
.
buf
;
sub_len
=
subbuf
.
len
;
}
else
{
sub
=
&
byte
;
sub_len
=
1
;
}
len
=
PyBytes_GET_SIZE
(
self
);
ADJUST_INDICES
(
start
,
end
,
len
);
if
(
end
-
start
<
sub_len
)
res
=
-
1
;
else
if
(
sub_len
==
1
)
{
if
(
dir
>
0
)
res
=
stringlib_find_char
(
PyBytes_AS_STRING
(
self
)
+
start
,
end
-
start
,
*
sub
);
else
res
=
stringlib_rfind_char
(
PyBytes_AS_STRING
(
self
)
+
start
,
end
-
start
,
*
sub
);
if
(
res
>=
0
)
res
+=
start
;
}
else
{
if
(
dir
>
0
)
res
=
stringlib_find_slice
(
PyBytes_AS_STRING
(
self
),
len
,
sub
,
sub_len
,
start
,
end
);
else
res
=
stringlib_rfind_slice
(
PyBytes_AS_STRING
(
self
),
len
,
sub
,
sub_len
,
start
,
end
);
}
if
(
subobj
)
PyBuffer_Release
(
&
subbuf
);
return
res
;
}
PyDoc_STRVAR
(
find__doc__
,
"B.find(sub[, start[, end]]) -> int
\n
\
\n
\
Return the lowest index in B where substring sub is found,
\n
\
such that sub is contained within B[start:end]. Optional
\n
\
arguments start and end are interpreted as in slice notation.
\n
\
\n
\
Return -1 on failure."
);
static
PyObject
*
bytes_find
(
PyBytesObject
*
self
,
PyObject
*
args
)
{
Py_ssize_t
result
=
bytes_find_internal
(
self
,
args
,
+
1
);
if
(
result
==
-
2
)
return
NULL
;
return
PyLong_FromSsize_t
(
result
);
return
_Py_bytes_find
(
PyBytes_AS_STRING
(
self
),
PyBytes_GET_SIZE
(
self
),
args
);
}
PyDoc_STRVAR
(
index__doc__
,
"B.index(sub[, start[, end]]) -> int
\n
\
\n
\
Like B.find() but raise ValueError when the substring is not found."
);
static
PyObject
*
bytes_index
(
PyBytesObject
*
self
,
PyObject
*
args
)
{
Py_ssize_t
result
=
bytes_find_internal
(
self
,
args
,
+
1
);
if
(
result
==
-
2
)
return
NULL
;
if
(
result
==
-
1
)
{
PyErr_SetString
(
PyExc_ValueError
,
"substring not found"
);
return
NULL
;
}
return
PyLong_FromSsize_t
(
result
);
return
_Py_bytes_index
(
PyBytes_AS_STRING
(
self
),
PyBytes_GET_SIZE
(
self
),
args
);
}
PyDoc_STRVAR
(
rfind__doc__
,
"B.rfind(sub[, start[, end]]) -> int
\n
\
\n
\
Return the highest index in B where substring sub is found,
\n
\
such that sub is contained within B[start:end]. Optional
\n
\
arguments start and end are interpreted as in slice notation.
\n
\
\n
\
Return -1 on failure."
);
static
PyObject
*
bytes_rfind
(
PyBytesObject
*
self
,
PyObject
*
args
)
{
Py_ssize_t
result
=
bytes_find_internal
(
self
,
args
,
-
1
);
if
(
result
==
-
2
)
return
NULL
;
return
PyLong_FromSsize_t
(
result
);
return
_Py_bytes_rfind
(
PyBytes_AS_STRING
(
self
),
PyBytes_GET_SIZE
(
self
),
args
);
}
PyDoc_STRVAR
(
rindex__doc__
,
"B.rindex(sub[, start[, end]]) -> int
\n
\
\n
\
Like B.rfind() but raise ValueError when the substring is not found."
);
static
PyObject
*
bytes_rindex
(
PyBytesObject
*
self
,
PyObject
*
args
)
{
Py_ssize_t
result
=
bytes_find_internal
(
self
,
args
,
-
1
);
if
(
result
==
-
2
)
return
NULL
;
if
(
result
==
-
1
)
{
PyErr_SetString
(
PyExc_ValueError
,
"substring not found"
);
return
NULL
;
}
return
PyLong_FromSsize_t
(
result
);
return
_Py_bytes_rindex
(
PyBytes_AS_STRING
(
self
),
PyBytes_GET_SIZE
(
self
),
args
);
}
...
...
@@ -2179,51 +2035,10 @@ bytes_rstrip_impl(PyBytesObject *self, PyObject *bytes)
}
PyDoc_STRVAR
(
count__doc__
,
"B.count(sub[, start[, end]]) -> int
\n
\
\n
\
Return the number of non-overlapping occurrences of substring sub in
\n
\
string B[start:end]. Optional arguments start and end are interpreted
\n
\
as in slice notation."
);
static
PyObject
*
bytes_count
(
PyBytesObject
*
self
,
PyObject
*
args
)
{
PyObject
*
sub_obj
;
const
char
*
str
=
PyBytes_AS_STRING
(
self
),
*
sub
;
Py_ssize_t
sub_len
;
char
byte
;
Py_ssize_t
start
=
0
,
end
=
PY_SSIZE_T_MAX
;
Py_buffer
vsub
;
PyObject
*
count_obj
;
if
(
!
stringlib_parse_args_finds_byte
(
"count"
,
args
,
&
sub_obj
,
&
byte
,
&
start
,
&
end
))
return
NULL
;
if
(
sub_obj
)
{
if
(
PyObject_GetBuffer
(
sub_obj
,
&
vsub
,
PyBUF_SIMPLE
)
!=
0
)
return
NULL
;
sub
=
vsub
.
buf
;
sub_len
=
vsub
.
len
;
}
else
{
sub
=
&
byte
;
sub_len
=
1
;
}
ADJUST_INDICES
(
start
,
end
,
PyBytes_GET_SIZE
(
self
));
count_obj
=
PyLong_FromSsize_t
(
stringlib_count
(
str
+
start
,
end
-
start
,
sub
,
sub_len
,
PY_SSIZE_T_MAX
)
);
if
(
sub_obj
)
PyBuffer_Release
(
&
vsub
);
return
count_obj
;
return
_Py_bytes_count
(
PyBytes_AS_STRING
(
self
),
PyBytes_GET_SIZE
(
self
),
args
);
}
...
...
@@ -2307,7 +2122,7 @@ bytes_translate_impl(PyBytesObject *self, PyObject *table, int group_right_1,
PyBuffer_Release
(
&
table_view
);
return
NULL
;
}
output_start
=
output
=
PyBytes_A
sString
(
result
);
output_start
=
output
=
PyBytes_A
S_STRING
(
result
);
input
=
PyBytes_AS_STRING
(
input_obj
);
if
(
dellen
==
0
&&
table_chars
!=
NULL
)
{
...
...
@@ -2914,145 +2729,17 @@ bytes_replace_impl(PyBytesObject *self, Py_buffer *old, Py_buffer *new,
/** End DALKE **/
/* Matches the end (direction >= 0) or start (direction < 0) of self
* against substr, using the start and end arguments. Returns
* -1 on error, 0 if not found and 1 if found.
*/
Py_LOCAL
(
int
)
_bytes_tailmatch
(
PyBytesObject
*
self
,
PyObject
*
substr
,
Py_ssize_t
start
,
Py_ssize_t
end
,
int
direction
)
{
Py_ssize_t
len
=
PyBytes_GET_SIZE
(
self
);
Py_ssize_t
slen
;
Py_buffer
sub_view
=
{
NULL
,
NULL
};
const
char
*
sub
;
const
char
*
str
;
if
(
PyBytes_Check
(
substr
))
{
sub
=
PyBytes_AS_STRING
(
substr
);
slen
=
PyBytes_GET_SIZE
(
substr
);
}
else
{
if
(
PyObject_GetBuffer
(
substr
,
&
sub_view
,
PyBUF_SIMPLE
)
!=
0
)
return
-
1
;
sub
=
sub_view
.
buf
;
slen
=
sub_view
.
len
;
}
str
=
PyBytes_AS_STRING
(
self
);
ADJUST_INDICES
(
start
,
end
,
len
);
if
(
direction
<
0
)
{
/* startswith */
if
(
start
+
slen
>
len
)
goto
notfound
;
}
else
{
/* endswith */
if
(
end
-
start
<
slen
||
start
>
len
)
goto
notfound
;
if
(
end
-
slen
>
start
)
start
=
end
-
slen
;
}
if
(
end
-
start
<
slen
)
goto
notfound
;
if
(
memcmp
(
str
+
start
,
sub
,
slen
)
!=
0
)
goto
notfound
;
PyBuffer_Release
(
&
sub_view
);
return
1
;
notfound:
PyBuffer_Release
(
&
sub_view
);
return
0
;
}
PyDoc_STRVAR
(
startswith__doc__
,
"B.startswith(prefix[, start[, end]]) -> bool
\n
\
\n
\
Return True if B starts with the specified prefix, False otherwise.
\n
\
With optional start, test B beginning at that position.
\n
\
With optional end, stop comparing B at that position.
\n
\
prefix can also be a tuple of bytes to try."
);
static
PyObject
*
bytes_startswith
(
PyBytesObject
*
self
,
PyObject
*
args
)
{
Py_ssize_t
start
=
0
;
Py_ssize_t
end
=
PY_SSIZE_T_MAX
;
PyObject
*
subobj
;
int
result
;
if
(
!
stringlib_parse_args_finds
(
"startswith"
,
args
,
&
subobj
,
&
start
,
&
end
))
return
NULL
;
if
(
PyTuple_Check
(
subobj
))
{
Py_ssize_t
i
;
for
(
i
=
0
;
i
<
PyTuple_GET_SIZE
(
subobj
);
i
++
)
{
result
=
_bytes_tailmatch
(
self
,
PyTuple_GET_ITEM
(
subobj
,
i
),
start
,
end
,
-
1
);
if
(
result
==
-
1
)
return
NULL
;
else
if
(
result
)
{
Py_RETURN_TRUE
;
}
}
Py_RETURN_FALSE
;
}
result
=
_bytes_tailmatch
(
self
,
subobj
,
start
,
end
,
-
1
);
if
(
result
==
-
1
)
{
if
(
PyErr_ExceptionMatches
(
PyExc_TypeError
))
PyErr_Format
(
PyExc_TypeError
,
"startswith first arg must be bytes "
"or a tuple of bytes, not %s"
,
Py_TYPE
(
subobj
)
->
tp_name
);
return
NULL
;
}
else
return
PyBool_FromLong
(
result
);
return
_Py_bytes_startswith
(
PyBytes_AS_STRING
(
self
),
PyBytes_GET_SIZE
(
self
),
args
);
}
PyDoc_STRVAR
(
endswith__doc__
,
"B.endswith(suffix[, start[, end]]) -> bool
\n
\
\n
\
Return True if B ends with the specified suffix, False otherwise.
\n
\
With optional start, test B beginning at that position.
\n
\
With optional end, stop comparing B at that position.
\n
\
suffix can also be a tuple of bytes to try."
);
static
PyObject
*
bytes_endswith
(
PyBytesObject
*
self
,
PyObject
*
args
)
{
Py_ssize_t
start
=
0
;
Py_ssize_t
end
=
PY_SSIZE_T_MAX
;
PyObject
*
subobj
;
int
result
;
if
(
!
stringlib_parse_args_finds
(
"endswith"
,
args
,
&
subobj
,
&
start
,
&
end
))
return
NULL
;
if
(
PyTuple_Check
(
subobj
))
{
Py_ssize_t
i
;
for
(
i
=
0
;
i
<
PyTuple_GET_SIZE
(
subobj
);
i
++
)
{
result
=
_bytes_tailmatch
(
self
,
PyTuple_GET_ITEM
(
subobj
,
i
),
start
,
end
,
+
1
);
if
(
result
==
-
1
)
return
NULL
;
else
if
(
result
)
{
Py_RETURN_TRUE
;
}
}
Py_RETURN_FALSE
;
}
result
=
_bytes_tailmatch
(
self
,
subobj
,
start
,
end
,
+
1
);
if
(
result
==
-
1
)
{
if
(
PyErr_ExceptionMatches
(
PyExc_TypeError
))
PyErr_Format
(
PyExc_TypeError
,
"endswith first arg must be bytes or "
"a tuple of bytes, not %s"
,
Py_TYPE
(
subobj
)
->
tp_name
);
return
NULL
;
}
else
return
PyBool_FromLong
(
result
);
return
_Py_bytes_endswith
(
PyBytes_AS_STRING
(
self
),
PyBytes_GET_SIZE
(
self
),
args
);
}
...
...
@@ -3224,17 +2911,20 @@ bytes_methods[] = {
{
"__getnewargs__"
,
(
PyCFunction
)
bytes_getnewargs
,
METH_NOARGS
},
{
"capitalize"
,
(
PyCFunction
)
stringlib_capitalize
,
METH_NOARGS
,
_Py_capitalize__doc__
},
{
"center"
,
(
PyCFunction
)
stringlib_center
,
METH_VARARGS
,
center__doc__
},
{
"count"
,
(
PyCFunction
)
bytes_count
,
METH_VARARGS
,
count__doc__
},
{
"center"
,
(
PyCFunction
)
stringlib_center
,
METH_VARARGS
,
_Py_center__doc__
},
{
"count"
,
(
PyCFunction
)
bytes_count
,
METH_VARARGS
,
_Py_count__doc__
},
BYTES_DECODE_METHODDEF
{
"endswith"
,
(
PyCFunction
)
bytes_endswith
,
METH_VARARGS
,
endswith__doc__
},
_Py_
endswith__doc__
},
{
"expandtabs"
,
(
PyCFunction
)
stringlib_expandtabs
,
METH_VARARGS
|
METH_KEYWORDS
,
expandtabs__doc__
},
{
"find"
,
(
PyCFunction
)
bytes_find
,
METH_VARARGS
,
find__doc__
},
_Py_expandtabs__doc__
},
{
"find"
,
(
PyCFunction
)
bytes_find
,
METH_VARARGS
,
_Py_find__doc__
},
BYTES_FROMHEX_METHODDEF
{
"hex"
,
(
PyCFunction
)
bytes_hex
,
METH_NOARGS
,
hex__doc__
},
{
"index"
,
(
PyCFunction
)
bytes_index
,
METH_VARARGS
,
index__doc__
},
{
"index"
,
(
PyCFunction
)
bytes_index
,
METH_VARARGS
,
_Py_
index__doc__
},
{
"isalnum"
,
(
PyCFunction
)
stringlib_isalnum
,
METH_NOARGS
,
_Py_isalnum__doc__
},
{
"isalpha"
,
(
PyCFunction
)
stringlib_isalpha
,
METH_NOARGS
,
...
...
@@ -3250,29 +2940,29 @@ bytes_methods[] = {
{
"isupper"
,
(
PyCFunction
)
stringlib_isupper
,
METH_NOARGS
,
_Py_isupper__doc__
},
BYTES_JOIN_METHODDEF
{
"ljust"
,
(
PyCFunction
)
stringlib_ljust
,
METH_VARARGS
,
ljust__doc__
},
{
"ljust"
,
(
PyCFunction
)
stringlib_ljust
,
METH_VARARGS
,
_Py_
ljust__doc__
},
{
"lower"
,
(
PyCFunction
)
stringlib_lower
,
METH_NOARGS
,
_Py_lower__doc__
},
BYTES_LSTRIP_METHODDEF
BYTES_MAKETRANS_METHODDEF
BYTES_PARTITION_METHODDEF
BYTES_REPLACE_METHODDEF
{
"rfind"
,
(
PyCFunction
)
bytes_rfind
,
METH_VARARGS
,
rfind__doc__
},
{
"rindex"
,
(
PyCFunction
)
bytes_rindex
,
METH_VARARGS
,
rindex__doc__
},
{
"rjust"
,
(
PyCFunction
)
stringlib_rjust
,
METH_VARARGS
,
rjust__doc__
},
{
"rfind"
,
(
PyCFunction
)
bytes_rfind
,
METH_VARARGS
,
_Py_
rfind__doc__
},
{
"rindex"
,
(
PyCFunction
)
bytes_rindex
,
METH_VARARGS
,
_Py_
rindex__doc__
},
{
"rjust"
,
(
PyCFunction
)
stringlib_rjust
,
METH_VARARGS
,
_Py_
rjust__doc__
},
BYTES_RPARTITION_METHODDEF
BYTES_RSPLIT_METHODDEF
BYTES_RSTRIP_METHODDEF
BYTES_SPLIT_METHODDEF
BYTES_SPLITLINES_METHODDEF
{
"startswith"
,
(
PyCFunction
)
bytes_startswith
,
METH_VARARGS
,
startswith__doc__
},
_Py_
startswith__doc__
},
BYTES_STRIP_METHODDEF
{
"swapcase"
,
(
PyCFunction
)
stringlib_swapcase
,
METH_NOARGS
,
_Py_swapcase__doc__
},
{
"title"
,
(
PyCFunction
)
stringlib_title
,
METH_NOARGS
,
_Py_title__doc__
},
BYTES_TRANSLATE_METHODDEF
{
"upper"
,
(
PyCFunction
)
stringlib_upper
,
METH_NOARGS
,
_Py_upper__doc__
},
{
"zfill"
,
(
PyCFunction
)
stringlib_zfill
,
METH_VARARGS
,
zfill__doc__
},
{
"zfill"
,
(
PyCFunction
)
stringlib_zfill
,
METH_VARARGS
,
_Py_
zfill__doc__
},
{
NULL
,
NULL
}
/* sentinel */
};
...
...
Objects/stringlib/find.h
View file @
dd40fc3e
...
...
@@ -117,76 +117,3 @@ STRINGLIB(parse_args_finds)(const char * function_name, PyObject *args,
}
#undef FORMAT_BUFFER_SIZE
#if STRINGLIB_IS_UNICODE
/*
Wraps stringlib_parse_args_finds() and additionally ensures that the
first argument is a unicode object.
*/
Py_LOCAL_INLINE
(
int
)
STRINGLIB
(
parse_args_finds_unicode
)(
const
char
*
function_name
,
PyObject
*
args
,
PyObject
**
substring
,
Py_ssize_t
*
start
,
Py_ssize_t
*
end
)
{
if
(
STRINGLIB
(
parse_args_finds
)(
function_name
,
args
,
substring
,
start
,
end
))
{
if
(
ensure_unicode
(
*
substring
)
<
0
)
return
0
;
return
1
;
}
return
0
;
}
#else
/* !STRINGLIB_IS_UNICODE */
/*
Wraps stringlib_parse_args_finds() and additionally checks whether the
first argument is an integer in range(0, 256).
If this is the case, writes the integer value to the byte parameter
and sets subobj to NULL. Otherwise, sets the first argument to subobj
and doesn't touch byte. The other parameters are similar to those of
stringlib_parse_args_finds().
*/
Py_LOCAL_INLINE
(
int
)
STRINGLIB
(
parse_args_finds_byte
)(
const
char
*
function_name
,
PyObject
*
args
,
PyObject
**
subobj
,
char
*
byte
,
Py_ssize_t
*
start
,
Py_ssize_t
*
end
)
{
PyObject
*
tmp_subobj
;
Py_ssize_t
ival
;
PyObject
*
err
;
if
(
!
STRINGLIB
(
parse_args_finds
)(
function_name
,
args
,
&
tmp_subobj
,
start
,
end
))
return
0
;
if
(
!
PyNumber_Check
(
tmp_subobj
))
{
*
subobj
=
tmp_subobj
;
return
1
;
}
ival
=
PyNumber_AsSsize_t
(
tmp_subobj
,
PyExc_OverflowError
);
if
(
ival
==
-
1
)
{
err
=
PyErr_Occurred
();
if
(
err
&&
!
PyErr_GivenExceptionMatches
(
err
,
PyExc_OverflowError
))
{
PyErr_Clear
();
*
subobj
=
tmp_subobj
;
return
1
;
}
}
if
(
ival
<
0
||
ival
>
255
)
{
PyErr_SetString
(
PyExc_ValueError
,
"byte must be in range(0, 256)"
);
return
0
;
}
*
subobj
=
NULL
;
*
byte
=
(
char
)
ival
;
return
1
;
}
#endif
/* STRINGLIB_IS_UNICODE */
Objects/stringlib/transmogrify.h
View file @
dd40fc3e
...
...
@@ -4,12 +4,6 @@
/* 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__
,
"B.expandtabs(tabsize=8) -> copy of B
\n
\
\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
,
PyObject
*
kwds
)
{
...
...
@@ -120,12 +114,6 @@ pad(PyObject *self, Py_ssize_t left, Py_ssize_t right, char fill)
return
u
;
}
PyDoc_STRVAR
(
ljust__doc__
,
"B.ljust(width[, fillchar]) -> copy of B
\n
"
"
\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
)
{
...
...
@@ -150,12 +138,6 @@ stringlib_ljust(PyObject *self, PyObject *args)
}
PyDoc_STRVAR
(
rjust__doc__
,
"B.rjust(width[, fillchar]) -> copy of B
\n
"
"
\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
)
{
...
...
@@ -180,12 +162,6 @@ stringlib_rjust(PyObject *self, PyObject *args)
}
PyDoc_STRVAR
(
center__doc__
,
"B.center(width[, fillchar]) -> copy of B
\n
"
"
\n
"
"Return B centered in a string of length width. Padding is
\n
"
"done using the specified fill character (default is a space)."
);
static
PyObject
*
stringlib_center
(
PyObject
*
self
,
PyObject
*
args
)
{
...
...
@@ -213,12 +189,6 @@ stringlib_center(PyObject *self, PyObject *args)
return
pad
(
self
,
left
,
marg
-
left
,
fillchar
);
}
PyDoc_STRVAR
(
zfill__doc__
,
"B.zfill(width) -> copy of B
\n
"
"
\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
)
{
...
...
Objects/unicodeobject.c
View file @
dd40fc3e
...
...
@@ -11244,6 +11244,25 @@ PyUnicode_AppendAndDel(PyObject **pleft, PyObject *right)
Py_XDECREF
(
right
);
}
/*
Wraps stringlib_parse_args_finds() and additionally ensures that the
first argument is a unicode object.
*/
Py_LOCAL_INLINE
(
int
)
parse_args_finds_unicode
(
const
char
*
function_name
,
PyObject
*
args
,
PyObject
**
substring
,
Py_ssize_t
*
start
,
Py_ssize_t
*
end
)
{
if
(
stringlib_parse_args_finds
(
function_name
,
args
,
substring
,
start
,
end
))
{
if
(
ensure_unicode
(
*
substring
)
<
0
)
return
0
;
return
1
;
}
return
0
;
}
PyDoc_STRVAR
(
count__doc__
,
"S.count(sub[, start[, end]]) -> int
\n
\
\n
\
...
...
@@ -11262,8 +11281,7 @@ unicode_count(PyObject *self, PyObject *args)
void
*
buf1
,
*
buf2
;
Py_ssize_t
len1
,
len2
,
iresult
;
if
(
!
stringlib_parse_args_finds_unicode
(
"count"
,
args
,
&
substring
,
&
start
,
&
end
))
if
(
!
parse_args_finds_unicode
(
"count"
,
args
,
&
substring
,
&
start
,
&
end
))
return
NULL
;
kind1
=
PyUnicode_KIND
(
self
);
...
...
@@ -11445,8 +11463,7 @@ unicode_find(PyObject *self, PyObject *args)
Py_ssize_t
end
=
0
;
Py_ssize_t
result
;
if
(
!
stringlib_parse_args_finds_unicode
(
"find"
,
args
,
&
substring
,
&
start
,
&
end
))
if
(
!
parse_args_finds_unicode
(
"find"
,
args
,
&
substring
,
&
start
,
&
end
))
return
NULL
;
if
(
PyUnicode_READY
(
self
)
==
-
1
)
...
...
@@ -11525,8 +11542,7 @@ unicode_index(PyObject *self, PyObject *args)
Py_ssize_t
start
=
0
;
Py_ssize_t
end
=
0
;
if
(
!
stringlib_parse_args_finds_unicode
(
"index"
,
args
,
&
substring
,
&
start
,
&
end
))
if
(
!
parse_args_finds_unicode
(
"index"
,
args
,
&
substring
,
&
start
,
&
end
))
return
NULL
;
if
(
PyUnicode_READY
(
self
)
==
-
1
)
...
...
@@ -12555,8 +12571,7 @@ unicode_rfind(PyObject *self, PyObject *args)
Py_ssize_t
end
=
0
;
Py_ssize_t
result
;
if
(
!
stringlib_parse_args_finds_unicode
(
"rfind"
,
args
,
&
substring
,
&
start
,
&
end
))
if
(
!
parse_args_finds_unicode
(
"rfind"
,
args
,
&
substring
,
&
start
,
&
end
))
return
NULL
;
if
(
PyUnicode_READY
(
self
)
==
-
1
)
...
...
@@ -12584,8 +12599,7 @@ unicode_rindex(PyObject *self, PyObject *args)
Py_ssize_t
end
=
0
;
Py_ssize_t
result
;
if
(
!
stringlib_parse_args_finds_unicode
(
"rindex"
,
args
,
&
substring
,
&
start
,
&
end
))
if
(
!
parse_args_finds_unicode
(
"rindex"
,
args
,
&
substring
,
&
start
,
&
end
))
return
NULL
;
if
(
PyUnicode_READY
(
self
)
==
-
1
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment