Revision e6821d09e4655af94f9c8af07333ae710094996a authored by Jeff King on 25 March 2015, 05:29:52 UTC, committed by Junio C Hamano on 25 March 2015, 17:25:27 UTC
These are all cases where we do a setup step of the form: for i in $foo; do set_up $i || break done && more_setup would not notice a failure in set_up (because break always returns a 0 exit code). These are just setup steps that we do not expect to fail, but it does not hurt to be defensive. Most can be fixed by converting the "break" to a "return 1" (since we eval our tests inside a function for just this purpose). A few of the loops are inside subshells, so we can use just "exit 1" to break out of the subshell. And a few can actually be made shorter by just unrolling the loop. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 76e057d
versioncmp.c
#include "cache.h"
/*
* versioncmp(): copied from string/strverscmp.c in glibc commit
* ee9247c38a8def24a59eb5cfb7196a98bef8cfdc, reformatted to Git coding
* style. The implementation is under LGPL-2.1 and Git relicenses it
* to GPLv2.
*/
/*
* states: S_N: normal, S_I: comparing integral part, S_F: comparing
* fractionnal parts, S_Z: idem but with leading Zeroes only
*/
#define S_N 0x0
#define S_I 0x3
#define S_F 0x6
#define S_Z 0x9
/* result_type: CMP: return diff; LEN: compare using len_diff/diff */
#define CMP 2
#define LEN 3
/*
* Compare S1 and S2 as strings holding indices/version numbers,
* returning less than, equal to or greater than zero if S1 is less
* than, equal to or greater than S2 (for more info, see the texinfo
* doc).
*/
int versioncmp(const char *s1, const char *s2)
{
const unsigned char *p1 = (const unsigned char *) s1;
const unsigned char *p2 = (const unsigned char *) s2;
unsigned char c1, c2;
int state, diff;
/*
* Symbol(s) 0 [1-9] others
* Transition (10) 0 (01) d (00) x
*/
static const uint8_t next_state[] = {
/* state x d 0 */
/* S_N */ S_N, S_I, S_Z,
/* S_I */ S_N, S_I, S_I,
/* S_F */ S_N, S_F, S_F,
/* S_Z */ S_N, S_F, S_Z
};
static const int8_t result_type[] = {
/* state x/x x/d x/0 d/x d/d d/0 0/x 0/d 0/0 */
/* S_N */ CMP, CMP, CMP, CMP, LEN, CMP, CMP, CMP, CMP,
/* S_I */ CMP, -1, -1, +1, LEN, LEN, +1, LEN, LEN,
/* S_F */ CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
/* S_Z */ CMP, +1, +1, -1, CMP, CMP, -1, CMP, CMP
};
if (p1 == p2)
return 0;
c1 = *p1++;
c2 = *p2++;
/* Hint: '0' is a digit too. */
state = S_N + ((c1 == '0') + (isdigit (c1) != 0));
while ((diff = c1 - c2) == 0) {
if (c1 == '\0')
return diff;
state = next_state[state];
c1 = *p1++;
c2 = *p2++;
state += (c1 == '0') + (isdigit (c1) != 0);
}
state = result_type[state * 3 + (((c2 == '0') + (isdigit (c2) != 0)))];
switch (state) {
case CMP:
return diff;
case LEN:
while (isdigit (*p1++))
if (!isdigit (*p2++))
return 1;
return isdigit (*p2) ? -1 : diff;
default:
return state;
}
}
Computing file changes ...