Perform a critical factorization of NEEDLE, of length NEEDLE_LEN. Return the index of the first byte in the right half, and set *PERIOD to the global period of the right half. The global period of a string is the smallest index (possibly its length) at which all remaining bytes in the string are repetitions of the prefix (the last repetition may be a subset of the prefix). When
| 116 | suffixes are determined by lexicographic comparison of |
| 117 | periodicity. */ |
| 118 | static size_t |
| 119 | critical_factorization (const unsigned char *needle, size_t needle_len, |
| 120 | size_t *period) |
| 121 | { |
| 122 | /* Index of last byte of left half, or SIZE_MAX. */ |
| 123 | size_t max_suffix, max_suffix_rev; |
| 124 | size_t j; /* Index into NEEDLE for current candidate suffix. */ |
| 125 | size_t k; /* Offset into current period. */ |
| 126 | size_t p; /* Intermediate period. */ |
| 127 | unsigned char a, b; /* Current comparison bytes. */ |
| 128 | |
| 129 | /* Invariants: |
| 130 | 0 <= j < NEEDLE_LEN - 1 |
| 131 | -1 <= max_suffix{,_rev} < j (treating SIZE_MAX as if it were signed) |
| 132 | min(max_suffix, max_suffix_rev) < global period of NEEDLE |
| 133 | 1 <= p <= global period of NEEDLE |
| 134 | p == global period of the substring NEEDLE[max_suffix{,_rev}+1...j] |
| 135 | 1 <= k <= p |
| 136 | */ |
| 137 | |
| 138 | /* Perform lexicographic search. */ |
| 139 | max_suffix = SIZE_MAX; |
| 140 | j = 0; |
| 141 | k = p = 1; |
| 142 | while (j + k < needle_len) |
| 143 | { |
| 144 | a = CANON_ELEMENT (needle[j + k]); |
| 145 | b = CANON_ELEMENT (needle[(size_t)(max_suffix + k)]); |
| 146 | if (a < b) |
| 147 | { |
| 148 | /* Suffix is smaller, period is entire prefix so far. */ |
| 149 | j += k; |
| 150 | k = 1; |
| 151 | p = j - max_suffix; |
| 152 | } |
| 153 | else if (a == b) |
| 154 | { |
| 155 | /* Advance through repetition of the current period. */ |
| 156 | if (k != p) |
| 157 | ++k; |
| 158 | else |
| 159 | { |
| 160 | j += p; |
| 161 | k = 1; |
| 162 | } |
| 163 | } |
| 164 | else /* b < a */ |
| 165 | { |
| 166 | /* Suffix is larger, start over from current location. */ |
| 167 | max_suffix = j++; |
| 168 | k = p = 1; |
| 169 | } |
| 170 | } |
| 171 | *period = p; |
| 172 | |
| 173 | /* Perform reverse lexicographic search. */ |
| 174 | max_suffix_rev = SIZE_MAX; |
| 175 | j = 0; |
no outgoing calls
no test coverage detected
searching dependent graphs…