23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
26 * POSSIBILITY OF SUCH DAMAGE. |
26 * POSSIBILITY OF SUCH DAMAGE. |
27 */ |
27 */ |
|
28 #ifdef MEMRCHR_NEED_GNU |
28 #define _GNU_SOURCE |
29 #define _GNU_SOURCE |
|
30 #endif |
|
31 |
|
32 #include "cx/string.h" |
|
33 |
29 #include <string.h> |
34 #include <string.h> |
30 #if defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >=2 |
|
31 #define FEATURE_MEMRCHR_AVAILABLE |
|
32 #endif |
|
33 |
|
34 #include "cx/string.h" |
|
35 |
|
36 #include <stdarg.h> |
35 #include <stdarg.h> |
37 #include <assert.h> |
36 #include <assert.h> |
38 #include <errno.h> |
37 #include <errno.h> |
39 #include <limits.h> |
38 #include <limits.h> |
40 #include <float.h> |
39 #include <float.h> |
237 |
236 |
238 cxstring cx_strrchr( |
237 cxstring cx_strrchr( |
239 cxstring string, |
238 cxstring string, |
240 int chr |
239 int chr |
241 ) { |
240 ) { |
242 #ifdef FEATURE_MEMRCHR_AVAILABLE |
241 #ifdef WITH_MEMRCHR |
243 char *ret = memrchr(string.ptr, 0xFF & chr, string.length); |
242 char *ret = memrchr(string.ptr, 0xFF & chr, string.length); |
244 if (ret == NULL) return (cxstring) {NULL, 0}; |
243 if (ret == NULL) return (cxstring) {NULL, 0}; |
245 return (cxstring) {ret, string.length - (ret - string.ptr)}; |
244 return (cxstring) {ret, string.length - (ret - string.ptr)}; |
246 #else |
245 #else |
247 chr = 0xFF & chr; |
246 chr = 0xFF & chr; |
248 size_t i = string.length; |
247 size_t i = string.length; |
249 while (i > 0) { |
248 while (i > 0) { |
250 i--; |
249 i--; |
251 // TODO: improve by comparing multiple bytes at once |
|
252 if (string.ptr[i] == chr) { |
250 if (string.ptr[i] == chr) { |
253 return cx_strsubs(string, i); |
251 return cx_strsubs(string, i); |
254 } |
252 } |
255 } |
253 } |
256 return (cxstring) {NULL, 0}; |
254 return (cxstring) {NULL, 0}; |