| 38 | */ |
| 39 | template <bool rstrip, typename character> |
| 40 | static inline int |
| 41 | string_cmp(int len1, const character *str1, int len2, const character *str2) |
| 42 | { |
| 43 | if (rstrip) { |
| 44 | /* |
| 45 | * Ignore/"trim" trailing whitespace (and 0s). Note that this function |
| 46 | * does not support unicode whitespace (and never has). |
| 47 | */ |
| 48 | while (len1 > 0) { |
| 49 | character c = str1[len1-1]; |
| 50 | if (c != (character)0 && !NumPyOS_ascii_isspace(c)) { |
| 51 | break; |
| 52 | } |
| 53 | len1--; |
| 54 | } |
| 55 | while (len2 > 0) { |
| 56 | character c = str2[len2-1]; |
| 57 | if (c != (character)0 && !NumPyOS_ascii_isspace(c)) { |
| 58 | break; |
| 59 | } |
| 60 | len2--; |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | int n = PyArray_MIN(len1, len2); |
| 65 | |
| 66 | if (sizeof(character) == 1) { |
| 67 | /* |
| 68 | * TODO: `memcmp` makes things 2x faster for longer words that match |
| 69 | * exactly, but at least 2x slower for short or mismatching ones. |
| 70 | */ |
| 71 | int cmp = memcmp(str1, str2, n); |
| 72 | if (cmp != 0) { |
| 73 | return cmp; |
| 74 | } |
| 75 | str1 += n; |
| 76 | str2 += n; |
| 77 | } |
| 78 | else { |
| 79 | for (int i = 0; i < n; i++) { |
| 80 | int cmp = character_cmp(*str1, *str2); |
| 81 | if (cmp != 0) { |
| 82 | return cmp; |
| 83 | } |
| 84 | str1++; |
| 85 | str2++; |
| 86 | } |
| 87 | } |
| 88 | if (len1 > len2) { |
| 89 | for (int i = n; i < len1; i++) { |
| 90 | int cmp = character_cmp(*str1, (character)0); |
| 91 | if (cmp != 0) { |
| 92 | return cmp; |
| 93 | } |
| 94 | str1++; |
| 95 | } |
| 96 | } |
| 97 | else if (len2 > len1) { |
nothing calls this directly
no test coverage detected