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 #define _GNU_SOURCE |
|
29 #include <string.h> |
|
30 #if defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >=2 |
|
31 #define FEATURE_MEMRCHR_AVAILABLE |
|
32 #endif |
|
33 |
28 #include "cx/string.h" |
34 #include "cx/string.h" |
29 |
35 |
30 #include <string.h> |
|
31 #include <stdarg.h> |
36 #include <stdarg.h> |
32 #include <assert.h> |
37 #include <assert.h> |
33 #include <errno.h> |
38 #include <errno.h> |
34 #include <limits.h> |
39 #include <limits.h> |
35 #include <float.h> |
40 #include <float.h> |
229 cxstring result = cx_strchr(cx_strcast(string), chr); |
234 cxstring result = cx_strchr(cx_strcast(string), chr); |
230 return (cxmutstr) {(char *) result.ptr, result.length}; |
235 return (cxmutstr) {(char *) result.ptr, result.length}; |
231 } |
236 } |
232 |
237 |
233 cxstring cx_strrchr( |
238 cxstring cx_strrchr( |
234 cxstring string, |
239 cxstring string, |
235 int chr |
240 int chr |
236 ) { |
241 ) { |
|
242 #ifdef FEATURE_MEMRCHR_AVAILABLE |
|
243 char *ret = memrchr(string.ptr, 0xFF & chr, string.length); |
|
244 if (ret == NULL) return (cxstring) {NULL, 0}; |
|
245 return (cxstring) {ret, string.length - (ret - string.ptr)}; |
|
246 #else |
237 chr = 0xFF & chr; |
247 chr = 0xFF & chr; |
238 size_t i = string.length; |
248 size_t i = string.length; |
239 while (i > 0) { |
249 while (i > 0) { |
240 i--; |
250 i--; |
241 // TODO: improve by comparing multiple bytes at once |
251 // TODO: improve by comparing multiple bytes at once |
242 if (string.ptr[i] == chr) { |
252 if (string.ptr[i] == chr) { |
243 return cx_strsubs(string, i); |
253 return cx_strsubs(string, i); |
244 } |
254 } |
245 } |
255 } |
246 return (cxstring) {NULL, 0}; |
256 return (cxstring) {NULL, 0}; |
|
257 #endif |
247 } |
258 } |
248 |
259 |
249 cxmutstr cx_strrchr_m( |
260 cxmutstr cx_strrchr_m( |
250 cxmutstr string, |
261 cxmutstr string, |
251 int chr |
262 int chr |