| 117 | */ |
| 118 | |
| 119 | int versioncmp(const char *s1, const char *s2) |
| 120 | { |
| 121 | const unsigned char *p1 = (const unsigned char *) s1; |
| 122 | const unsigned char *p2 = (const unsigned char *) s2; |
| 123 | unsigned char c1, c2; |
| 124 | int state, diff; |
| 125 | |
| 126 | /* |
| 127 | * Symbol(s) 0 [1-9] others |
| 128 | * Transition (10) 0 (01) d (00) x |
| 129 | */ |
| 130 | static const uint8_t next_state[] = { |
| 131 | /* state x d 0 */ |
| 132 | /* S_N */ S_N, S_I, S_Z, |
| 133 | /* S_I */ S_N, S_I, S_I, |
| 134 | /* S_F */ S_N, S_F, S_F, |
| 135 | /* S_Z */ S_N, S_F, S_Z |
| 136 | }; |
| 137 | |
| 138 | static const int8_t result_type[] = { |
| 139 | /* state x/x x/d x/0 d/x d/d d/0 0/x 0/d 0/0 */ |
| 140 | |
| 141 | /* S_N */ CMP, CMP, CMP, CMP, LEN, CMP, CMP, CMP, CMP, |
| 142 | /* S_I */ CMP, -1, -1, +1, LEN, LEN, +1, LEN, LEN, |
| 143 | /* S_F */ CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, |
| 144 | /* S_Z */ CMP, +1, +1, -1, CMP, CMP, -1, CMP, CMP |
| 145 | }; |
| 146 | |
| 147 | if (p1 == p2) |
| 148 | return 0; |
| 149 | |
| 150 | c1 = *p1++; |
| 151 | c2 = *p2++; |
| 152 | /* Hint: '0' is a digit too. */ |
| 153 | state = S_N + ((c1 == '0') + (isdigit (c1) != 0)); |
| 154 | |
| 155 | while ((diff = c1 - c2) == 0) { |
| 156 | if (c1 == '\0') |
| 157 | return diff; |
| 158 | |
| 159 | state = next_state[state]; |
| 160 | c1 = *p1++; |
| 161 | c2 = *p2++; |
| 162 | state += (c1 == '0') + (isdigit (c1) != 0); |
| 163 | } |
| 164 | |
| 165 | if (!initialized) { |
| 166 | const char *const newk = "versionsort.suffix"; |
| 167 | const char *const oldk = "versionsort.prereleasesuffix"; |
| 168 | const struct string_list *newl; |
| 169 | const struct string_list *oldl; |
| 170 | int new = repo_config_get_string_multi(the_repository, newk, &newl); |
| 171 | int old = repo_config_get_string_multi(the_repository, oldk, &oldl); |
| 172 | |
| 173 | if (!new && !old) |
| 174 | warning("ignoring %s because %s is set", oldk, newk); |
| 175 | if (!new) |
| 176 | prereleases = newl; |
no test coverage detected