partition.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /* stringlib: partition implementation */
  2. #ifndef STRINGLIB_FASTSEARCH_H
  3. # error must include "stringlib/fastsearch.h" before including this module
  4. #endif
  5. #if !STRINGLIB_MUTABLE && !defined(STRINGLIB_GET_EMPTY)
  6. # error "STRINGLIB_GET_EMPTY must be defined if STRINGLIB_MUTABLE is zero"
  7. #endif
  8. Py_LOCAL_INLINE(PyObject*)
  9. STRINGLIB(partition)(PyObject* str_obj,
  10. const STRINGLIB_CHAR* str, Py_ssize_t str_len,
  11. PyObject* sep_obj,
  12. const STRINGLIB_CHAR* sep, Py_ssize_t sep_len)
  13. {
  14. PyObject* out;
  15. Py_ssize_t pos;
  16. if (sep_len == 0) {
  17. PyErr_SetString(PyExc_ValueError, "empty separator");
  18. return NULL;
  19. }
  20. out = PyTuple_New(3);
  21. if (!out)
  22. return NULL;
  23. pos = FASTSEARCH(str, str_len, sep, sep_len, -1, FAST_SEARCH);
  24. if (pos < 0) {
  25. #if STRINGLIB_MUTABLE
  26. PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, str_len));
  27. PyTuple_SET_ITEM(out, 1, STRINGLIB_NEW(NULL, 0));
  28. PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(NULL, 0));
  29. if (PyErr_Occurred()) {
  30. Py_DECREF(out);
  31. return NULL;
  32. }
  33. #else
  34. Py_INCREF(str_obj);
  35. PyTuple_SET_ITEM(out, 0, (PyObject*) str_obj);
  36. PyObject *empty = (PyObject*)STRINGLIB_GET_EMPTY();
  37. assert(empty != NULL);
  38. Py_INCREF(empty);
  39. PyTuple_SET_ITEM(out, 1, empty);
  40. Py_INCREF(empty);
  41. PyTuple_SET_ITEM(out, 2, empty);
  42. #endif
  43. return out;
  44. }
  45. PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, pos));
  46. Py_INCREF(sep_obj);
  47. PyTuple_SET_ITEM(out, 1, sep_obj);
  48. pos += sep_len;
  49. PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str + pos, str_len - pos));
  50. if (PyErr_Occurred()) {
  51. Py_DECREF(out);
  52. return NULL;
  53. }
  54. return out;
  55. }
  56. Py_LOCAL_INLINE(PyObject*)
  57. STRINGLIB(rpartition)(PyObject* str_obj,
  58. const STRINGLIB_CHAR* str, Py_ssize_t str_len,
  59. PyObject* sep_obj,
  60. const STRINGLIB_CHAR* sep, Py_ssize_t sep_len)
  61. {
  62. PyObject* out;
  63. Py_ssize_t pos;
  64. if (sep_len == 0) {
  65. PyErr_SetString(PyExc_ValueError, "empty separator");
  66. return NULL;
  67. }
  68. out = PyTuple_New(3);
  69. if (!out)
  70. return NULL;
  71. pos = FASTSEARCH(str, str_len, sep, sep_len, -1, FAST_RSEARCH);
  72. if (pos < 0) {
  73. #if STRINGLIB_MUTABLE
  74. PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(NULL, 0));
  75. PyTuple_SET_ITEM(out, 1, STRINGLIB_NEW(NULL, 0));
  76. PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str, str_len));
  77. if (PyErr_Occurred()) {
  78. Py_DECREF(out);
  79. return NULL;
  80. }
  81. #else
  82. PyObject *empty = (PyObject*)STRINGLIB_GET_EMPTY();
  83. assert(empty != NULL);
  84. Py_INCREF(empty);
  85. PyTuple_SET_ITEM(out, 0, empty);
  86. Py_INCREF(empty);
  87. PyTuple_SET_ITEM(out, 1, empty);
  88. Py_INCREF(str_obj);
  89. PyTuple_SET_ITEM(out, 2, (PyObject*) str_obj);
  90. #endif
  91. return out;
  92. }
  93. PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, pos));
  94. Py_INCREF(sep_obj);
  95. PyTuple_SET_ITEM(out, 1, sep_obj);
  96. pos += sep_len;
  97. PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str + pos, str_len - pos));
  98. if (PyErr_Occurred()) {
  99. Py_DECREF(out);
  100. return NULL;
  101. }
  102. return out;
  103. }